一年前在和一位大神的聊天中了解了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还有许多其它的特性还有待我去挖掘。