今回はUIAutomation PowerShell ExtentionとPesterを用いて、電卓アプリの自動化をしてみました。
その内容について、記載したいと思います。
なぜ、これをしようと思ったのか
デスクトップアプリの自動化といえば、UFTやegplant等の有償なものが多い。 プログラミングベースでデスクトップアプリを触れるものがないかなと思っていたところ、UIAutomationというものがあり、かつPowerShellだけで触れるものがあった。 また、PowerShellにテストフレームワークPesterがあるので組み合わせて使ってみたいと思った。#UIAutomation PowerShell Extentionとは
Microsoftが提供しているUI AutomationをPowerShellから呼び出せるようにしたものです。
UIAutomationとは
Microsoft UI Automationは、Microsoft Windows用の新しいアクセシビリティフレームワークで、Windows Presentation Foundation(WPF)をサポートするすべてのOSで利用できます。 UI Automationは、デスクトップ上のほとんどのユーザーインターフェース(UI)要素へのプログラムによるアクセスを提供し、スクリーンリーダーなどの支援技術製品がエンドユーザーにUIに関する情報を提供したり、標準入力以外の手段でUIを操作したりできるようにします。また、UI Automationでは、自動化されたテストスクリプトでUIを操作することもできます。 ([UI Automation Overview](https://docs.microsoft.com/en-us/dotnet/framework/ui-automation/ui-automation-overview)から一部をDeepl翻訳したもの)#Pesterとは
Pesterは、PowerShell用のテストおよびモッキングフレームワークです。
Pesterは、テストを書いて実行するためのフレームワークを提供します。Pesterは、ユニットテストや統合テストを書くために最もよく使われますが、それだけに限定されるものではありません。また、環境全体、コンピュータのデプロイメント、データベースの設定などを検証するツールのベースにもなります。
(Pesterの公式ページから一部をDeepl翻訳したもの)
#今回実施した環境
環境 | Version |
---|---|
Windows10 | 21H2 |
Powershell | 5.1.19041.1320 |
UI Automation PowerShell Extention | UIAutomation.0.8.7B3.NET40 |
Pester | 3.4.0(もともとWindowsに入っているものを使用) |
電卓アプリ(Windows標準) | 10.2103.8.0 |
インストール方法
UI Automation PowerShell Extention
以下のサイトからダウンロードし、任意のフォルダに展開します。
元々はhttps://uiautomation.codeplex.com/のCodeplexに格納されていました。
CodeplexはMicrosoftがオープンソース開発者向けに提供していたサービスなのですが、2017年12月15日をもってサービス終了になり、codeplexのページは閉鎖されました。ソースコード自体はhttps://github.com/apetrovskiy/STUPS/tree/master/UIAにありますが、インストール用のバイナリパッケージは上記のページにしか置かれていません。
私はC:\Program Files\WindowsPowerShell\ModulesにUIAutomationというフォルダを作成し、そこに展開しました。
Pester
PowerShellのバージョンが5.0以上の方はもともと入っているので、ここは飛ばして問題ありません。
PowerShellのバージョンが5.0未満の方、もしくは最新バージョンを使いたいという方は以下のサイトから、zipファイルをダウンロードし、任意のフォルダに展開してください。
私はC:\Program Files\WindowsPowerShell\ModulesにPesterというファイルが入っていました。
ダウンロードしたzipファイルを右クリック、プロパティでブロックの解除してから適当な場所に展開することをお勧めします。
これで、UI Automation PowerShell ExtentionとPesterのダウンロードは完了です。
とても楽です。
#自動化コードを書いてみる
では、ここから電卓の自動テストコードを書きます。
##Pesterのひな形を作成する
Pesterではコマンドを入力することで、テンプレートを作ることができるため、
今回はそれを使いたいと思います。
まずPowerShellで任意のフォルダまで移動し、以下のコマンドを入力します。
New-Fixture .\ファイル名(今回はcalcで実行しました。)
コマンド入力後、以下の画面が表示され、指定したフォルダに以下の2つのファイルが作成されたらOKです。
ディレクトリ:作成したファイルのディレクトリパス
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2021/12/04 17:22 25 calc.ps1
-a---- 2021/12/04 17:22 257 calc.Tests.ps1
calc.ps1はテスト対象のプログラムファイルです。
このファイルには電卓を自動操作するプログラムを書きます。
function calc {
}
calc.Tests.ps1はテスト用のプログラムファイルです。
このファイルに電卓の自動テストを書いていきます。
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
. "$here\$sut"
Describe "calc" {
It "does something useful" {
$true | Should Be $false
}
}
電卓のUI要素を取得する
電卓を自動で動かせるようにするには、UI要素を調べる必要があります。
デスクトップアプリの要素取得方法はいろいろありますが、
今回はUIAutomation PowerShell Extentionをダウンロードしたときに、組み込まれている「UIAutomationSpy」を使ってみます。
私の環境では、UIAutomation.0.8.7B3.NET40のUIAutomationSpyは動作しなかったため、UIAutomation.0.8.7B3.NET35のUIAutomationSpyを使いました。
-
STOPボタンを押下する。
この手順を繰り返して、操作したいUI要素を取得していきます。
コードを書く
今回は電卓の[1]ボタンを押すと、結果画面に「1」が表示することを確認するテストを書いていきます。
まず、calc.ps1に電卓の[1]ボタンを押す処理を書いていきます。
Import-Module "UIAutomation.dllが格納されているパス先を指定" #UI Automationモジュールをインポートする
[UIAutomation.Preferences]::Highlight=$false #自動操作中に表示される赤枠(ハイライト)を非表示にする
function click_numbutton_one {
$wndw = Get-UiaWindow -Name '電卓' # 対象のアプリを指定する
$wndw | Get-UiaButton -AutomationId 'num1Button' | Invoke-UiaButtonClick | Out-Null #電卓の[1]ボタンを指定し、クリックする
$wndw | Get-UiaText -AutomationID 'CalculatorResults' | Read-UIAControlName #電卓の計算結果表示エリアに表示されている数値を取得する
}
次に、calc.Tests.ps1にテストコードを書いていきます。
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
. "$here\$sut"
Describe "動作確認" {
Start-Process calc #電卓を起動
It "電卓ボタン1を押下すると、結果表示が1になること" { #テストケース名を記載
click_numbutton_one| Should Be "表示は 1 です" #実行する関数とアサーション処理を記載
}
Stop-Process -name Calculator #電卓を終了する
}
Pesterでテストを実行する
テストコードもかけたので、実際に実行してみましょう。
PowerShellを起動して、動かすプログラムファイルがあるディレクトリまで、移動します。
実行コマンドは以下です。
Invoke-Pester .\calc.Tests.ps1
実行後、期待結果通りであれば、以下がpowershellに表示されます。
また、xml形式でテスト結果を出力することができます。
テスト実行時に以下のオプションを追加すると良いです。
Invoke-Pester .\calc.Tests.ps1 -OutputFormat NUnitXml -OutputFile テスト結果.xml
サンプルコード
上のコードだけでは少し寂しかったので、いろいろと足しました。
まだまだ改善が必要なので、参考程度に見ていただければと思います。
サンプルコード
Import-Module "UIAutomation.dllが格納されているパス先を指定"
[UIAutomation.Preferences]::Highlight=$false
function click_numbutton_one {
$wndw = Get-UiaWindow -Name '電卓' # 対象のアプリを指定する
$wndw | Get-UiaButton -AutomationId 'num1Button' | Invoke-UiaButtonClick | Out-Null #電卓の[1]ボタンを指定し、クリックする
$wndw | Get-UiaText -AutomationId 'CalculatorResults' | Read-UIAControlName #電卓の計算結果表示エリアに表示されている数値を取得する
}
function click_numbutton([string]$num) {
$i = 0
$wndw = Get-UiaWindow -Name '電卓'
while([String]::IsNullOrEmpty($num[$i]) -eq $false)
{
$wndw | Get-UiaButton -AutomationId "num$($num[$i])Button" | Invoke-UiaButtonClick | Out-Null
$i++
}
}
function Four_law_calculation_button([string]$key) { # 演算子の+、-、*、/のボタンを押下する
$calculation = @{
"sum" = [string]"plusButton"
"subtract" = [string]"minusButton"
"multi" = [string]"multiplyButton"
"div" = [string]"divideButton"
}
$selectbutton = $calculation[$key]
$wndw = Get-UiaWindow -Name '電卓'
$wndw | Get-UiaButton -AutomationId $selectbutton | Invoke-UiaButtonClick | Out-Null
}
function click_equalbutton { #"="ボタンを押下する
$wndw = Get-UiaWindow -Name '電卓'
$wndw | Get-UiaButton -AutomationId "equalButton" | Invoke-UiaButtonClick | Out-Null
}
function reading_result_display_area { #結果表示エリアに表示されている数値を取得する
$wndw = Get-UiaWindow -Name '電卓'
$wndw | Get-UiaText -AutomationId 'CalculatorResults' | Read-UIAControlName #電卓の計算結果表示エリアに表示されている数値を取得する
}
サンプルテストコード
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
. "$here\$sut"
Describe "動作確認" {
Start-Process calc
It "電卓ボタン1を押下すると、結果表示が1になること" {
click_numbutton_one| Should Be "表示は 1 です"
}
Stop-Process -name Calculator
}
Describe "数字ボタンの動作確認" {
Start-Process calc
It "電卓ボタン2を押下すると、結果表示が2になること" {
click_numbutton "2"
reading_result_display_area | Should Be "表示は 2 です"
}
Stop-Process -name Calculator
}
Describe "足し算" {
Start-Process calc
It "10と10を足すと20になること" {
click_numbutton "10"
Four_law_calculation_button "sum"
click_numbutton "10"
click_equalbutton
reading_result_display_area | Should Be "表示は 20 です"
}
Stop-Process -name Calculator
}
Describe "引き算" {
Start-Process calc
It "100から99を引くと1になること" {
click_numbutton "100"
Four_law_calculation_button "subtract"
click_numbutton "99"
click_equalbutton
reading_result_display_area | Should Be "表示は 1 です"
}
Stop-Process -name Calculator
}
Describe "multi" {
Start-Process calc
It "25と100を書けると2500になること" {
click_numbutton "25"
Four_law_calculation_button "multi"
click_numbutton "100"
click_equalbutton
reading_result_display_area | Should Be "表示は 2,500 です"
}
Stop-Process -name Calculator
}
Describe "div" {
Start-Process calc
It "1000000から2を割ると500000になること" {
click_numbutton "1000000"
Four_law_calculation_button "div"
click_numbutton "2"
click_equalbutton
reading_result_display_area | Should Be "表示は 500,000 です"
}
Stop-Process -name Calculator
}
GitHubにも置いておきます。
#使ってみた所感
普段、seleniumやplaywrightを使っている人であれば、特に問題なく実装できるのかなと感じました。
ただ、パイプを使うコードはあまり見ないので、最初はやりにくいかもしれないです。
また文中にも述べましたが、UI Automation PowerShell Extentionは開発が終了しており、情報量がとても少ないため、高度なことをすると苦労する可能性があります。
業務で活用するのは厳しいかなというのが正直なところです。
だだ、powershellスクリプトの練習やテスト自動化の練習には活用できると思います。(環境構築も展開するだけでできるので、簡単に始めれると思います。)
webアプリの自動化に飽きたら、たまにはこちらも試してみてはいかがでしょうか。