前回までで、通常操作に関しての実装は完了して、思い通りにアプリを操作できるところまで行きました。
で、今回はテスト自動化で困りがちな点の対応を考えていきます。これもアプリケーションドライバ層で吸収すれば良いと思います。
ここから先はAppDriverクラスを拡張していきます。
そんなに難しいことではなくチップス的なテクニックです。
モーダルで固まった場合の対応
タイムアウトさせるしかないですね。
時間が来たら対象を強制終了します。
こんな感じです。
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; namespace EmployeeManagementDriver { public class Killer { Task _killer; bool _executing = true; bool _kill; public int Timeup { get; set; } public Killer(int timeup, int processId) { Timeup = timeup; _killer = Task.Factory.StartNew(() => { Stopwatch watch = new Stopwatch(); watch.Start(); while (_executing) { if (Timeup < watch.ElapsedMilliseconds) { Process.GetProcessById(processId).Kill(); _kill = true; break; } Thread.Sleep(10); } }); } public bool Finish() { _executing = false; _killer.Wait(); return !_kill; } } }
AppDriverで使ってみましょう。
using Codeer.Friendly; using Codeer.Friendly.Dynamic; using Codeer.Friendly.Windows; using Codeer.Friendly.Windows.Grasp; using Ong.Friendly.FormsStandardControls; using System.Diagnostics; namespace EmployeeManagementDriver { public class AppDriver { WindowsAppFriend _app; public MainFormDriver MainForm { get; private set; } public Killer Killer{ get; private set; } public AppDriver() { var process = Process.Start("EmployeeManagement.exe"); _app = new WindowsAppFriend(process); MainForm = new MainFormDriver(new WindowControl(_app, process.MainWindowHandle)); //5分でタイムアウトにする Killer = new Killer(1000 * 60 * 5, process.Id); } public void Release() { if (Killer.Finish()) { //タイムアップ終了していない場合は自ら終了させる Process.GetProcessById(_app.ProcessId).CloseMainWindow(); } } } }
時間は共通で定義しておいて、特別なテストだけ延長するとかにすると良いと思います。
あんまり、細かく設定するのは面倒ですので、テストが複雑化してしまいます。
正常パスでは発生しないケースなので。
ちょっとテストしておきましょう。
[TestMethod] public void TestTimeup() { _app.Killer.Timeup = 1000; try { var addForm = _app.MainForm.ButtonAdd_EmulateClick(); addForm.ButtonEntry_EmulateClickAndClose(); Assert.Fail(); } catch (FriendlyOperationException) { } }
これで、モーダルダイアログで止まっても、5分後には次のテストに移れます。
実はもう一つやることがあります。
それは、対象アプリのライフサイクルの管理です。
次回はそれをやります。
サンプルコード修正
2015/1/30
モーダルダイアログの書き方が適切でなかったので修正しました。それにより、一部ここに書くのは不適当な記事を削除しました。また別の機会に解説します。