Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

FriendlyによるWindowsアプリテスト自動化手法 基礎技術編

5,824 views

Published on

Asian Automation Alliance ~自動化を語り合おう!(2014/06/28) でデモを交えながら話した元ネタです。(20分)

Published in: Software
  • Be the first to comment

FriendlyによるWindowsアプリテスト自動化手法 基礎技術編

  1. 1. Friendlyによる Windowsアプリテスト自動化手法 基礎技術解説編
  2. 2. 自己紹介 福本健治 職業:プログラマー C#でWPFのデスクトップアプリケーション 開発をしています
  3. 3. Windowsアプリテスト自動化 こんなことをやりたいんです。 →デモ
  4. 4. テスト設計技術 アプリ操作技術 テスト自動化に必要な技術は大きくは二つ
  5. 5. テスト設計技術 アプリ操作技術 今日はWindowsアプリ操作技術 に関して話します。
  6. 6. Windowsアプリ操作プログラム 作成時に最も困ったこと。 それはインターフェイス。 ・足りない。 ・不安定。 ・調整困難 だって、GUIって 人間用じゃん・・・。
  7. 7. GUI操作をエミュレートするライブラリは いくつか存在します。 まあ、それはそれで良いのですが、 テストを作りこんでいくと もう一手欲しかったりします。
  8. 8. で、Friendly http://www.codeer.co.jp/AutoTest
  9. 9. Codeer で検索 eが一個多い Nugetで無料で入手できます!
  10. 10. Friendly 他のとは根本的に違います。 対象プロセスと、友達になって、 プログラムを直で触らせてもらうのです。 最強
  11. 11. ①君のものは僕のもの public partial class MainForm : Form { ComboBox _comboBox; string MyFunc(int value) { return value.ToString(); } } public void YourThingIsMine() { var process= Process.GetProcessesByName("Target")[0]; //友達になると・・・ var app = new WindowsAppFriend(process); //別プロセスのオブジェクトを //自分のプロセスのもののように操作できる。 dynamic form = app.Type<Application>().OpenForms[0]; form._comboBox.SelectedIndex = 1; string ret = form.MyFunc(3); } そ、そんな・・・
  12. 12. ②僕のものは君のもの void MyThingIsYours() { var process= Process.GetProcessesByName("Target")[0]; var app = new WindowsAppFriend(process); //自分のコードを動的にインジェクション! WindowsAppExpander.LoadAssembly(app, GetType().Assembly); //挿入したコードを相手プロセスで実行 app.Type(GetType()). ForTest(); } static void ForTest() { /*テスト用*/ } え!? 勝手に?
  13. 13. 信じられない? では、デモやります。
  14. 14. 実用例
  15. 15. 安定したGUI操作 //プログラム時に使う操作を直接呼び出しているんだから //確実に動作して当然だよね♪ form._comboBox.SelectedIndex = 2; form._checkBox.CheckState = CheckState.Indeterminate; form._trackBar.Value = 100; *GUI操作は後で紹介する上位ライブラリを使うとさらに便利です。
  16. 16. 操作困難なGUI操作をスキップ void DragDrop(object sender, DragEventArgs e) { DropCore( e.Data.GetData(DataFormats.FileDrop) as string[]); } void DropCore(string[] files) { //ここから先のロジックの方が不安なんだよね。 } //クリップボード使う処理は //不安定になりがちだし、 //自動テストではコア部分だけにしよっと♪ //もちろん、抜かしたことは //チームで共有するよ。 form.DropCore(new string[] { path1, path2, path3 });
  17. 17. 内部データを抜き出して検証 //リストアイテムに格納されているデータ [Serializable] class MyItem { string Name { get; set; } int Age { get; set; } string Address { get; set; } } //データ取れるから、検証も簡単♪ MyItem item = form._listBox.Items[3]; Assert.AreEqual(“石川", item.Name); Assert.AreEqual(37, item.Age); Assert.AreEqual(“大阪”, item.Address);
  18. 18. 複雑な処理、アトミックに実行したい処理はInjection void Test() { WindowsAppExpander.LoadAssembly(app, GetType().Assembly); //挿入したstatic関数を呼び出し。 app.Type(GetType()). Change(form._grid, 1, 1, 2); } //割り込みなしで、確実に実行。 //実装も簡単。(^_^)v static void Change(DataGridView grid, int col, int row, int index) { grid.Focus(); grid.CurrentCell = grid[col, row]; grid.BeginEdit(false); ((ComboBox)grid.EditingControl).SelectedIndex = index; grid.EndEdit(); } 対象プロセス内で実行!
  19. 19. void Test() { //インジェクション! WindowsAppExpander.LoadAssembly( app, GetType().Assembly); //DLL公開関数も呼び出せる! app.Type(GetType()). MyNativeFunction(); } [DllImport("MFCApplication.exe")] static extern void MyNativeFunction(); extern "C" __declspec(dllexport) void __cdecl MyNativeFunction() { //みんな大好きMFC //処理内容 } レガシーなネイティブアプリを操作!
  20. 20. 使い方色々。 非常に応用が利くので、 工夫して使ってみてください。 この自由度の高さは テスト自動化のコストダウンの お役に立つと思います。
  21. 21. さらに、上位ライブラリもあるのです。
  22. 22. Friendlyは、インフラのみの提供です。 何でもできるのですが・・・。 何でも書く必要があります。 例えば・・・・。
  23. 23. static void EmulateChangeCellText(DataGrid grid, int itemIndex, int col, string text) { bool success = false; EventHandler<DataGridCellEditEndingEventArgs> hanlder = (s, e) => { TextBox textBox = e.EditingElement as TextBox; if (textBox != null) { textBox.Text = text; success = true; } }; grid.CellEditEnding += hanlder; EmulateChangeCurrentCell(grid, itemIndex, col); grid.BeginEdit(); grid.CommitEdit(DataGridEditingUnit.Row, true); grid.CellEditEnding -= hanlder; if (!success) { throw new NotSupportedException (ResourcesLocal4.Instance.DataGridErrorNotTextBoxCell); } } WPFのDataGridのテキスト変更処理 //これをインジェクションして実行させる。
  24. 24. static void EmulateChangeCellText(DataGrid grid, int itemIndex, int col, string text) { bool success = false; EventHandler<DataGridCellEditEndingEventArgs> hanlder = (s, e) => { TextBox textBox = e.EditingElement as TextBox; if (textBox != null) { textBox.Text = text; success = true; } }; grid.CellEditEnding += hanlder; EmulateChangeCurrentCell(grid, itemIndex, col); grid.BeginEdit(); grid.CommitEdit(DataGridEditingUnit.Row, true); grid.CellEditEnding -= hanlder; if (!success) { throw new NotSupportedException (ResourcesLocal4.Instance.DataGridErrorNotTextBoxCell); } } WPFのDataGridのテキスト変更処理 //これをインジェクションして実行させる。
  25. 25. //実装しておきました!これ使ってください。 WPFDataGrid grid(core); grid.EmulateChangeCellText(0, 1, “NewText”); WPFのDataGridのテキスト変更処理
  26. 26. 結局、GUI操作は、みんな使います。 多くの方、コミュニティーの協力により、 以下そろっておりますのでご利用ください。 ・ネイティブ用 ・WinForm用 ・WPF用 ・VSHTC.Friendly.PinInterface(特殊) http://www.codeer.co.jp/AutoTest/api-reference 全部無料!
  27. 27. ちなみに、 GUI操作は、似たようなライブラリがありますが、 Friendly系のライブラリの特徴は・・・ ・シンプル。 ・タイミング依存なし。 ・高速。 ・足りなければ、中身を使って簡単に拡張可能。
  28. 28. お知らせ
  29. 29. Windowsアプリテスト自動化を希望している企業様がありま したら、株式会社Codeerがお手伝いします。 【メリット】 テスト自動化は立ち上げにコストがかかりますが、 無料ライブラリのFriendlyを使うことと、 テスト自動化経験豊富な担当者のノウハウを使うことにより、 無駄を省いた導入が可能となります。
  30. 30. ご清聴ありがとうございました。

×