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還有許多其它的特性還有待我去挖掘。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM