一年前在和一位大神的聊天中了解了Selenium自動化測試,興沖沖買了《零成本實現Web自動化測試——基於Selenium WebDriver和Cucumber》,看了前幾章一頭霧水,被各種理論打懵了。從此覺得自動化測試好厲害,但是好遙遠,沒有單元測試那么簡單易學啊。
這兩天,網站前期開發的一個大坑被挖出來了,幾乎把整個項目的所有頁面都改了。加上前期開發的新功能在SVN里一合並,看着一大堆沖突,我心里徹底沒底了,想着要測試一遍,但是那么多頁面和業務一測就是幾天。
要是所有的測試能夠自動化,以后能夠隨便擴展場景和業務邏輯就好了,回想起了Selenium,我就硬着頭皮試試看寫個web測試吧。
一、Selenium
根據網上資料,第一代Selenium主要分RC版本和IDE版本。后者只能在FireFox上使用,前者可以在任何瀏覽器上用,而且支持各種語言。RC版本好像就是我要的了,網上一搜,發現用起來很麻煩,而且大部分是Java,有Server端和Client端之分,Server端需要jdk編譯,使用方法基本是命令行,為了圖快只好拋棄了。。
后來在nuget里找到了WebDriver,其實也就是Selenium2.0,果斷裝上。結合網上對WebDriver的一些案例,馬上成功寫出了一個登錄web驗證
我的項目最終NuGet包如下:
主要安裝WebDriver應該就可以了,其它是依賴項,可以自動安裝的
這里主要參考了http://blog.sina.com.cn/s/blog_5c9288aa0101de2u.html

using System; using System.Collections.Generic; using System.Linq; using System.Text; using OpenQA.Selenium; using NUnit.Framework; using OpenQA.Selenium.Firefox; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Support.UI; namespace ConsoleApplication1 { [TestFixture] class Program { static void Main(string[] args) { Program p = new Program(); p.SetupTest(); p.TheUntitledTest(); p.TeardownTest(); } private IWebDriver driver; private StringBuilder verificationErrors; private string baseURL; private bool acceptNextAlert = true; [SetUp] public void SetupTest() { driver = new ChromeDriver(); baseURL = ""; verificationErrors = new StringBuilder(); } [TearDown] public void TeardownTest() { try { driver.Quit(); } catch (Exception) { // Ignore errors if unable to close the browser } Assert.AreEqual("", verificationErrors.ToString()); } [Test] public void TheUntitledTest() { driver.Navigate().GoToUrl(baseURL); driver.FindElement(By.Id("LoginName")).Clear(); driver.FindElement(By.Id("LoginName")).SendKeys(""); driver.FindElement(By.Id("password")).Clear(); driver.FindElement(By.Id("password")).SendKeys(""); driver.FindElement(By.Id("")).Click(); WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10)); wait.Until<bool>((d) => { try { IWebElement element = d.FindElement(By.Id("")); Assert.AreEqual(element.FindElement(By.ClassName("")).Text, ""); return false; } catch (NoSuchElementException) { return true; } }); } private bool IsElementPresent(By by) { try { driver.FindElement(by); return true; } catch (NoSuchElementException) { return false; } } private bool IsAlertPresent() { try { driver.SwitchTo().Alert(); return true; } catch (NoAlertPresentException) { return false; } } private string CloseAlertAndGetItsText() { try { IAlert alert = driver.SwitchTo().Alert(); string alertText = alert.Text; if (acceptNextAlert) { alert.Accept(); } else { alert.Dismiss(); } return alertText; } finally { acceptNextAlert = true; } } } }
運行時報錯,找不到文件chromedriver.exe,網上搜了下,在官網上下載好,放在程序運行目錄,就可以跑了
前面代碼中需要注意一點,WebDriverWait一節主要是為了等待網頁刷新完成,不然的話,沒等頁面跳轉,就開始抓元素或者判斷了,肯定會錯。這里主要用到了顯式的等待
參考http://blog.csdn.net/aerchi/article/details/8055913
測試通過,但是每個測試實例都要這樣寫一遍,工作量還是太大了!
如此巨大的測試代碼肯定需要一個框架進行組織吧。這里就輪到了SpecFlow。
二、SpecFlow
SpecFlow其實就是Cucumber .NET版本,Cucumber官網上找到的。Cucumber是驗收測試的一種實現,語法幾乎和自然語言一樣,相當於純黑盒的測試。
語法就是在什么場景下(Scenary),有什么樣的先決條件(Given),會執行什么行為得到什么結果(Then)
除了Nuget包(參考上面),還需要安裝vs插件才能使用
SpecFlow官網對具體使用方法其實有簡單案例、也有很詳細的文檔。當然大部分是英文,我看英文的速度太慢了,所以暫時用到哪個去查。
添加的Feature文件
右鍵Feature文件編輯窗口內部,生成對應的動作
以下是其中一段內容
[Then(@"Where '(.*)' display in '(.*)'")] public void ThenWhereDisplayIn(string p0, string p1) { WebDriverWait wait = new WebDriverWait(WebBrowser.Current, TimeSpan.FromSeconds(10)); wait.Until<bool>((d) => { try { Assert.AreEqual(WebBrowser.Current.FindElement(By.CssSelector(p1)).Text, p0); return false; } catch (NoSuchElementException) { return true; } }); }
WebBrowser.Current是一個單例的SeleniumDriver實例。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using TechTalk.SpecFlow; using OpenQA.Selenium; using OpenQA.Selenium.Firefox; using OpenQA.Selenium.Chrome; using OpenQA.Selenium.Support.UI; namespace SeleniumTest { public static class WebBrowser { public static ChromeDriver Current { get { if (!ScenarioContext.Current.ContainsKey("browser")) ScenarioContext.Current["browser"] = new ChromeDriver(); return ScenarioContext.Current["browser"] as ChromeDriver; } } } }
這樣,就可以通過擴充Scenery,重用所有的驗證了。
三、總結
NUnit:單元測試框架,提供各種斷言和測試引擎。
NSubstitute:許久不用,這次也沒用到,用來虛擬對象,單元測試中較常見。
Selenium:實現web自動化測試,靠他打開測試瀏覽器,自動輸入等。
Cucumber&SpecFlow:自動化測試框架,行為驅動開發、驗收測試。
關於Selenium和SpecFlow還有許多其它的特性還有待我去挖掘。