【Windows】GUIアプリケーションの時間の掛かりそうな異常系検証を何とかする方法

この記事は[「1分で実現できる有用な技術 Advent Calendar 2014」](http://qiita.com/advent-calendar/2014/one-minute)の17日目の記事です。

#概要
* データの追加ボタンを10万回押して上限に達しても落ちない事を確認してください
* 1000回ドラッグアンドドロップして1001回目で上限エラーダイアログが出る事を確認してください

といったGUIアプリケーションの異常系検証の中で、特に単純作業の繰り返しの場合に利用可能なデバッグ方法を紹介します。
多分ギリギリ１分弱でできると思いますｗ


#UWSCを使おう！
上述のような検証では、

1. あらかじめ回数を制限したり逆に増やした状態のバイナリを開発者に用意してもらう
2. ショートカットキーを割り当てて連打する

といった方法でもできるのですが、
(1)は実際にリリースするバイナリではないので検証としては不完全ですし
(2)はマウス操作ではないのでやはり検証としては不完全です。

優秀なデバッガならメモリエディタで直接変更・・・とか方法については言い出すとキリが無さそうですが、
こんなときUWSCを使いましょう！というのがこの記事です。


#UWSCとは

(公式)http://www.uwsc.info/

キーボードとマウス操作をスクリプトで記述し再生できるアプリです。


#自分でスクリプトは組まず、基本的には「記録」した後スクリプトを弄ろう！

自分でマニュアル見ながらスクリプトを書くのは大変ですし１分でできません。

UWSCには「キーボードやマウス操作を記録してスクリプトとして保存する」という機能があります。
基本的には記録して保存したスクリプトを弄ればマニュアルなんて見る必要ありません。


#「電卓の１ボタンを10万回押す」スクリプトを実際に書いてみる

あなたは今から「Windowsの電卓アプリ」のデバッガーです！

検証依頼として次のような依頼メールが届きました。

「電卓の１ボタンを10万回押してもバグって落ちたりしない事を確認してくれ！」

あほか！！とか思いつつもこれは仕事。何とかしないといけません。

そんなあなたは懐かしきあの日のフラッシュゲーをマクロを使って不正クリアする為にUWSCを落としていました。
これを使ってこの検証を自動化して終わらしましょう！

先ずは起動して下記画像の赤丸で囲った「記録ボタン」を押します。

![kore.png](https://qiita-image-store.s3.amazonaws.com/0/59944/06ac7ab3-6be9-1f06-c7e6-425d0ab6d5ca.png)

この時点で記録が始まるので、電卓の１ボタンを１度だけ押しましょう。

![dentaku3.png](https://qiita-image-store.s3.amazonaws.com/0/59944/e7b7c133-f899-3cd5-b2dc-a86cd7d57aa9.png)

その後STOPボタンを押して記録を停止します。

![Stop.png](https://qiita-image-store.s3.amazonaws.com/0/59944/b7bc9e2b-e21e-fa02-ded2-0afd475870bf.png)

このままだと保存されてないのでこれをスクリプトとしてファイルに保存します。

![kore2.png](https://qiita-image-store.s3.amazonaws.com/0/59944/54be4053-f811-5c13-c6f7-b895312bc43f.png)

名前は「dentaku_click.UWS」とかで良いでしょう。
これをメモ帳で開いてください。

```dentaku_click.UWS
MMV(977,292,10)
MMV(977,291,203)
MMV(976,290,31)
MMV(975,289,10)
MMV(975,288,16)
MMV(974,286,10)
MMV(973,285,16)
MMV(972,284,10)
MMV(972,283,15)
MMV(972,282,10)
MMV(971,281,16)
MMV(971,280,10)
MMV(971,279,31)
MMV(970,279,10)
MMV(970,278,31)
MMV(970,277,16)
MMV(969,277,31)
ACW(GETID("電卓","CalcFrame"),932,5,228,337,0)
BTN(LEFT,DOWN,969,277,1045)
MMV(969,277,16)
BTN(LEFT,UP,969,277,62)
MMV(969,277,10)
MMV(971,275,265)
MMV(976,271,16)
MMV(982,267,10)
MMV(991,262,16)
MMV(1003,257,10)
MMV(1034,246,31)
MMV(1074,226,15)
MMV(1099,214,10)
MMV(1125,200,10)
MMV(1154,183,16)
MMV(1186,161,10)
MMV(1221,138,16)
MMV(1256,117,15)
MMV(1291,97,10)
MMV(1322,84,16)
MMV(1351,75,10)
MMV(1375,69,15)
MMV(1398,64,10)
...以降ずらずらと...
```

多分こんな感じで凄い事になってると思います。
大体予想付くと思いますが

* MMVはマウス移動
* BTNはボタンのクリックとか
* ACWはウィンドウクリックしてアクティブになるとかならないとか

です。よってMMVは何かの動作をする手前以外全部不要なので削除しましょう。
また最後まで続いているMMVはスクリプトを停止させる為にSTOPボタンを押そうとしているスクリプトなので全部消して構いません。
そうすると多分次のような感じになるはずです。

```dentaku_click.UWS
MMV(969,277,31)
ACW(GETID("電卓","CalcFrame"),932,5,228,337,0)
BTN(LEFT,DOWN,969,277,1045)
BTN(LEFT,UP,969,277,62)
```

これを保存して試しに再生してみましょう。再生ボタンは下記画像の赤丸です。

![saisei.png](https://qiita-image-store.s3.amazonaws.com/0/59944/3d60ecad-e63e-abb5-f40f-ab7922ff5c18.png)

ちゃんと１ボタンが押されるはずです。
後はこれをfor文で10万回回せばいいだけですね。

for文の書き方をマニュアルから探すのは面倒なので以下のfor文をコピペしましょう！

```dentaku_click.UWS
MMV(969,277,31)
ACW(GETID("電卓","CalcFrame"),932,5,228,337,0)
for i = 1 to 10
    BTN(LEFT,DOWN,969,277,1045)
    BTN(LEFT,UP,969,277,62)
next
```

それでは実行です！尚上記スクリプトはテストの為に10回だけしかクリックしてません。

ちゃんとボタンが10回クリックされたと思いますがかなり遅いと思います。
実は各種関数っぽい記述の最後の部分は全て実行する時間になってます。上記スクリプトの左クリックで言えば...

> BTN(LEFT,DOWN,969,277,1045)

この1045の部分です。ミリ秒なので約1秒毎にクリックしてますね。10万回押させると27時間掛かるので話になりません。
あまりに早すぎるとGUI側が認識しないのでここの値の設定は割と難しいところなんですが自分はいつも20ミリ秒くらいに設定してます。昔10ミリ秒だと認識しない場合があったので・・・まぁ環境次第です。色々試してください。

```dentaku_click.UWS
MMV(969,277,20)
ACW(GETID("電卓","CalcFrame"),932,5,228,337,0)
for i = 1 to 10
    BTN(LEFT,DOWN,969,277,20)
    BTN(LEFT,UP,969,277,20)
next
```

上記が修正版です。実行すればちゃんと20ミリ秒毎に10回押してくれます。
後はループ回数を100000にすれば良いだけですね。

#(おまけ)場合によってはスクリプトを書かなくて良い
本当に単純にクリック連打するだけならばもっと簡単な方法があります。
それがこのスクリプトです。

```dentaku_click.UWS
for i = 1 to 10000000
    BTN(LEFT,DOWN)
    BTN(LEFT,UP)
    SLEEP(0.02)
next
```

これは「現在のマウス位置で100万回クリックするスクリプト」です。
BTN関数の第三引数以降は実は不要で、設定しない場合その場でクリックします。間隔無しで実行させるとGUIが認識しないのでSLEEPで20ミリ秒停止させてます。

これをあらかじめUWSCで開いておいて、デバッグを開始したい位置にマウスポインタを移動させた後ショートカットキーを利用して再生、規定回超えたら停止すれば良いわけです。

再生と停止のショートカットはデフォルトだと

* 再生：ALT+F1
* 停止：ALT+F2

だと思います（これは設定ダイアログで変更できます）

まぁただそこまで手間でもないので回数に関してはデバッグする度に変えても良いかもしれません。自動で止まらないので。

皆さんの苦痛なデバッグ作業の助けになれば幸いです。