剛剛以SCRUM的方式結(jié)束了一個的ASP.NET網(wǎng)站的測試的第一個Spring,因為團(tuán)隊從無到有實現(xiàn)自動化測試系統(tǒng),有必要把這次的經(jīng)驗和教訓(xùn)總結(jié)一下,以便后續(xù)的Spring可以獲取一些有意義的借鑒。
創(chuàng)新互聯(lián)服務(wù)項目包括東勝網(wǎng)站建設(shè)、東勝網(wǎng)站制作、東勝網(wǎng)頁制作以及東勝網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,東勝網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到東勝省份的部分城市,未來相信會繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
因為是一個技術(shù)博客,所以使用SCRUM管理這個測試項目的經(jīng)驗放在別的地方分享,這系列的文章分享一下使用VSTT和Selenium結(jié)合實現(xiàn)自動化測試系統(tǒng)的經(jīng)驗。
Selenium簡介
Selenium主要是一個錄制并回放的自動化測試用例編制工具,由一個錄制工具Selenium IDE(一個Firefox插件,當(dāng)然這個工具也可以回放啦),一個回放工具Selenium Remote Control在其他機(jī)器和其他操作系統(tǒng)上進(jìn)行回放。Selenium的一個好處就是你可以使用它測試所有操作系統(tǒng)下的所有主流瀏覽器,至于Linux下面的konqueror和gnome下面自帶的瀏覽器,沒有試過Selenium是否支持,當(dāng)然那個控制臺界面下的瀏覽器就更沒有試過啦。Selenium還有一個Selenium Grid,據(jù)說很強(qiáng)大,因為項目比較緊,就沒有花時間去看它。
至于Selenium各個工具的用法,它的官網(wǎng)上有詳細(xì)的文檔,如果文檔也沒說清楚的話,那就直接讀源代碼吧。
Selenium和VSTT的整合
Selenium可以根據(jù)錄制的步驟生成直接在NUnit中使用的C#代碼,這些代碼基本上都可以在VSTT中直接使用,就是一些屬性需要更改。例如[TestFixture]改成[TestClass],[Test]改成[TestMethod]之類的,改好以后,啟動Selenium-RC,就可以直接在VSTT里面當(dāng)作普通的單元測試用例執(zhí)行了。
Selenium代碼優(yōu)化
既然要做自動化測試,那么有一點是必須要時刻考慮的,就是在產(chǎn)品開發(fā)過程中,程序界面甚至是內(nèi)部的類庫接口也是時刻改變的。而Selenium只能記錄當(dāng)時錄制測試用例的界面情況,因此需需要將它生成的代碼分解一下,以面向?qū)ο蟮姆绞絹碇貙憽@缦旅孢@段代碼的目的是測試用戶可以查看自己的博客:
[TestMethod]
public void TheTestTest()
{
selenium.Open("/");
selenium.Click("link=登錄");
selenium.WaitForPageToLoad("30000");
selenium.Type("tbUserName", "donjuan");
selenium.Type("tbPassword", "");
selenium.Click("btnLogin");
selenium.WaitForPageToLoad("30000");
selenium.Click("link=donjuan");
selenium.WaitForPageToLoad("30000");
selenium.Click("link=博客");
selenium.WaitForPageToLoad("30000");
}
但是網(wǎng)頁頁面布局,或者Html控件的Id、文本等內(nèi)容隨時都會被程序員修改,修改的原因有多種,例如修復(fù)新的錯誤(Bug),或者僅僅就是代碼重構(gòu)。因此作為測試團(tuán)隊,不能總是認(rèn)為網(wǎng)頁的內(nèi)容一成不變的。而象登錄這種操作,大部分測試用例都會用到,所以最好只要為登錄動作創(chuàng)建唯一的代碼 。有多個方案:
1. 為登錄創(chuàng)建一個獨立的測試用例,本來登錄這個功能就是要測試的嘛,在編輯自動化測試用例列表的時候,把登錄用例放在最前面。
2. 為登錄動作創(chuàng)建一個單獨的函數(shù),例如LogOn(),然后在其他測試用例當(dāng)中(包括登錄的測試用例)調(diào)用這個函數(shù),另外,因為可能會需要用到不同的 用戶,所以最好把用戶名和密碼等變量提取出來,變成LogOn(string username, string password)之類的函數(shù)。
兩個方案,顯然是第二個方案的彈性大,但是對于第一個方案,如果測試人員都是新手,且對代碼不熟悉的話,建議可以考慮。
于是我們的代碼就變成類似下面的代碼:
using System;
//
//這個異常是故意創(chuàng)建出來,用來封裝所有在測試代碼中發(fā)生的錯誤
//
public class CaseErrorException : Exception
{
public CaseErrorException(string message)
: base()
{
}
public CaseErrorException(Exception inner)
: this(null, inner)
{
}
public CaseErrorException(string message, Exception inner)
: base(message == null ? "測試代碼錯誤,請修復(fù)測試代碼,查看InnerException屬性!" :
string.Format("測試代碼錯誤,請修復(fù)測試代碼,詳細(xì)錯誤信息:{0};或者查看InnerException屬性!", message),
inner)
{
}
}
public class UserOperationsHelper
{
public void LogOn(string username, string password)
{
// string.Empty留出來為測試目的服務(wù)
if (username == null)
throw new CaseErrorException(new ArgumentNullException("username"));
if (password == null)
throw new CaseErrorException(new ArgumentNullException("password"));
selenium.Open("/");
selenium.Click("link=登錄");
selenium.WaitForPageToLoad(Consts.TimeToWaitForPageLoad);
selenium.Type("tbUserName", username);
selenium.Type("tbPassword", password);
selenium.Click("btnLogin");
selenium.WaitForPageToLoad(Consts.TimeToWaitForPageLoad);
}
}
public static class Consts
{
//將等待的時間提取成一個公開的函數(shù),因為在今后大規(guī)模的測試
//過程中,很多自動化測試用例不簡單地執(zhí)行,會導(dǎo)致網(wǎng)站響應(yīng)速度
//變慢,所以
public const string TimeToWaitForPageLoad = "30000";
}
public class TestLibrary
{
public UserOperationsHelper UserHelper { get; private set; }
}
public class TestClass
{
[TestMethod]
public void LogOnTest()
{
var username = "donjuan";
var password = "它是個秘密";
TestLibrary.UserHelper.LogOn(username, password);
//在測試過程中,我們發(fā)現(xiàn)這個鏈接是
//根據(jù)用戶名而變的,為了擴(kuò)展性,動態(tài)生成其標(biāo)識文本
selenium.Click(string.Format("link={0}", username));
selenium.WaitForPageToLoad(Consts.TimeToWaitForPageLoad);
selenium.Click("link=博客");
selenium.WaitForPageToLoad(Consts.TimeToWaitForPageLoad);
//執(zhí)行一些必要的測試驗證過程
Assert.IsTrue(selenium.IsTextPresented(...));
}
}
這里稍微解釋一下,創(chuàng)建自動化測試代碼,就是為了節(jié)省手工重復(fù)測試的工作量以及測試失誤的風(fēng)險。但只要是代碼,都會有可能出錯,因此自動化測試框架里面創(chuàng)建了一個CaseErrorException,這樣在每次分析測試用例失敗的時候,可以一眼區(qū)分開測試代碼的錯誤和產(chǎn)品代碼中的錯誤。例如在UserOperationHelper.LogOn函數(shù)中的參數(shù)檢查,當(dāng)然啦,在測試過程當(dāng)中,有可能需要測試不輸入用戶名或者密碼的情況下,驗證登錄界面是否正常工作的情況。因此在驗證參數(shù)的時候,特意為這種情況留下了String.Empty的入口,而對于null值,則基本上可以判斷是因為測試人員在編寫代碼上的失誤(具體原因會在數(shù)據(jù)驅(qū)動測試?yán)锩嬷v到)。
至于TestLibrary的初始化,完全可以放到每一個測試類型的TestInitializer里面,如下表所示:
[TestClass] public class AddBlogTest { private TestContext testContextInstance; public TestContext TestContext { get { return testContextInstance; } set { testContextInstance = value; } }
private TestLibrary TestLibrary; private ISelenium selenium;
[TestInitialize] public void SetupTest() { TestLibrary = TestLibrary.SetupTest(TestContext); selenium = TestLibrary.Selenium; }
[TestCleanup] public void TeardownTest() { TestLibrary.Shutdown(); } } |
咋看起來,把LogOn測試用例分解成那么多的類型,有點畫蛇添足,實際上這些函數(shù)庫正是為了更方便地創(chuàng)建后續(xù)的測試用例耗費的磨刀的功夫。例如下面的代碼是基于一些創(chuàng)建好了的函數(shù)編寫的測試用例:
[TestMethod] public void CreateBlog() { TestLibrary.UserHelper.LogOnAsAdmin(); var blog = TestLibrary.BlogHelper.CreateBlog("博客的標(biāo)題", "博客的鏈接");
selenium.Click("link=管理博客"); selenium.WaitForPageToLoad(Consts.TimeToWaitForPageLoad);
Assert.IsTrue(selenium.IsElementPresent(string.Format("link={0}", blog.Title))); } |
下一篇文章網(wǎng)站測試自動化系統(tǒng)—數(shù)據(jù)驅(qū)動測試講解這個框架和數(shù)據(jù)驅(qū)動測試的結(jié)合。
本文標(biāo)題:網(wǎng)站測試自動化系統(tǒng)—基于Selenium和VSTT
本文URL:http://muchs.cn/article6/pdjoog.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信公眾號、、網(wǎng)站內(nèi)鏈、搜索引擎優(yōu)化、小程序開發(fā)、響應(yīng)式網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)