上一篇 [Appium][WinAppDriver] Appium + WinAppDriver 測試 Windows 桌面應用程式 UI,介紹如何使用 Appium + WinAppDriver 進行桌面應用程式的測試,但那個測試程式有點醜,我想要用 Page Object 重構一下,由於目前沒有工具可以協助,所以得一個一個敲
開發環境
- VS 2017
- .NET Framework 4.7.2
- Windows 10 Enterprise ver.1803 ,OS build 17134.648
重構前
先看看原本的面貌,我要做的動作就是把 FindElement 搬到 Page Object
[TestMethod] public void 輸入帳號密碼_按下登入_預期得到一個彈跳視窗並呈現Hiyao() { WindowsDriver.FindElementByAccessibilityId("Id_TextBox").SendKeys("yao"); WindowsDriver.FindElementByAccessibilityId("Password_TextBox").SendKeys("123456"); WindowsDriver.FindElementByAccessibilityId("Login_Button").Click(); var messageBox = WindowsDriver.FindElementByClassName("#32770"); var title = messageBox.Text; var messageText = messageBox.FindElementByXPath("//Text[@Name='Hi~yao']").Text; Assert.AreEqual("Title", title); Assert.AreEqual("Hi~yao", messageText); WindowsDriver.FindElementByXPath("//Button[@Name='OK']").Click(); }
Page Object 是為了隔離網頁結構的物件,讓測試程式碼不會出現 FindElment 這樣的代碼,提升測試程式碼的可讀性,請參考 https://martinfowler.com/bliki/PageObject.html
重構
首先建立 Page Object
internal class LoginPage { protected internal WindowsDriver<WindowsElement> _driver; public LoginPage(WindowsDriver<WindowsElement> driver) { this._driver = driver; } }
UI 上有三個控制項,分別為它們建立 IWinAppDriver 欄位,設定控制項狀態
// id public WindowsElement IdElement => this._driver.FindElementByAccessibilityId("Id_TextBox"); public LoginPage SetId(string id) { this.IdElement.SendKeys(id); return this; } // password public WindowsElement PasswordElement => this._driver.FindElementByAccessibilityId("Password_TextBox"); public LoginPage SetPassword(string password) { this.PasswordElement.SendKeys(password); return this; } // login public WindowsElement LoginElement => this._driver.FindElementByAccessibilityId("Login_Button"); public LoginPage ClickLogin() { this.LoginElement.Click(); return this; }
測試程式碼
[TestMethod] public void 輸入帳號密碼_按下登入_預期得到一個彈跳視窗並呈現Hiyao() { var loginPage = new LoginPage(WindowsDriver); loginPage.SetId("yao") .SetPassword("123456") .ClickLogin(); var messageBox = WindowsDriver.FindElementByClassName("#32770"); var title = messageBox.Text; var messageText = messageBox.FindElementByXPath("//Text[@Name='Hi~yao']").Text; Assert.AreEqual("Title", title); Assert.AreEqual("Hi~yao", messageText); WindowsDriver.FindElementByXPath("//Button[@Name='OK']").Click(); }
彈跳視窗的OK的 Element
// ok button public WindowsElement OkElement => this._driver.FindElementByXPath("//Button[@Name='OK']"); public LoginPage ClickOK() { this.OkElement.Click(); return this; }
彈跳視窗的 Element、驗證
// messagebox public WindowsElement MessageBoxElemnt => this._driver.FindElementByClassName("#32770"); public LoginPage VerifyMessageBoxByName(string expected) { var messageText = this.MessageBoxElemnt.FindElementByXPath($"//Text[@Name='{expected}']").Text; Assert.AreEqual(expected, messageText); return this; } public LoginPage VerifyMessageBoxByTitle(string expected) { var messageText = this.MessageBoxElemnt.Text; Assert.AreEqual(expected, messageText); return this; }
測試程式碼最後變成這樣,看起來乾淨多了呢
[TestMethod] public void 輸入帳號密碼_按下登入_預期得到一個彈跳視窗並呈現Hiyao() { var loginPage = new LoginPage(WindowsDriver); loginPage.SetId("yao") .SetPassword("123456") .ClickLogin(); loginPage.VerifyMessageBoxByTitle("Title") .VerifyMessageBoxByName("Hi~yao"); loginPage.ClickOK(); }
完整的 Page Object
https://github.com/yaochangyu/sample.dotblog/blob/master/Test/WinAppDriver/Lab.WinAppDriverTest/App.UnitTest/LoginPage.cs
範例專案
https://github.com/yaochangyu/sample.dotblog/tree/master/Test/WinAppDriver/Lab.WinAppDriverTest
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET