zoukankan      html  css  js  c++  java
  • Selenium+SpecFlow自动化测试一天实践(C#)

      一年前在和一位大神的聊天中了解了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;
                }
            }
        }
    }
    View Code

      运行时报错,找不到文件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还有许多其它的特性还有待我去挖掘。

  • 相关阅读:
    SQL Server学习之路:建立数据库、建立表
    tomcat访问的重定向问题
    PAT A1107——并查集
    ^-^
    JSON.parse()和JSON.stringify()的用法
    Android——ViewHolder的作用与用法
    题解-Atcoder_agc005D ~K Perm Counting
    题解-bzoj2560 串珠子
    题解-Codeforces710F String Set Queries
    游记-NOIP2018
  • 原文地址:https://www.cnblogs.com/enigmaxp/p/5374855.html
Copyright © 2011-2022 走看看