敏捷自动化测试(1)—— 我们的测试为什么不够敏捷?
測試是為了保證軟件的質(zhì)量,敏捷測試關(guān)鍵是保證可以持續(xù)、及時的對軟件質(zhì)量情況進行全面的反饋。由于在敏捷開發(fā)過程中每個迭代都會增加功能、修復(fù)缺陷或重構(gòu)代碼,所以在完成當前迭代新增特性測試工作的同時,還要通過回歸測試來保證歷史功能不受影響。為此我們期望:
測試范圍足夠廣:- 測試用例要覆蓋所有功能;
- 要在各種可能的環(huán)境下作兼容性測試;
- 系統(tǒng)的穩(wěn)定性、性能都要測試;
測試頻率足夠高:
- 每日構(gòu)建產(chǎn)生的版本要保證可用;
- 每個迭代都需要對歷史功能做回歸測試;
- 釋放前或上線后如果打了補丁,就需要回歸;
但實際情況往往不遂人愿:
實際測試周期變短:
- 上線時間提前確定,研發(fā)進度延期,測試計劃被迫延后;
- 最后階段經(jīng)常會臨時增加測試任務(wù);
- 所有人都知道還需要再經(jīng)過一輪測試,但時間沒有了;
有效測試資源稀缺:
- 臨時從其他項目抽調(diào)的測試人員不能立刻有效的開展測試工作;
- “搞不清楚”本項目的研發(fā)人員到底是不會做測試還是不愿做測試;
因此由于客觀上的資源和時間限制,完整的、及時回歸測試在人工測試情況下,往往是不可能完成的任務(wù)。團隊內(nèi)部也會產(chǎn)生各種爭執(zhí):
- 提交給測試的版本為什么研發(fā)人員不先做通過性測試?
- 這次代碼改動量不大,有必要再花那么多時間回歸么?
- 當初不是承諾這次修改肯定不會影響以前的功能么?
- 怎么不早說要支持Chrome瀏覽器,現(xiàn)在哪還有時間測試啊?
- 怎么能讓現(xiàn)場出現(xiàn)這種低級的Bug,打補丁后為什么不仔細回歸一遍?
爭執(zhí)越演越烈,最終有團隊成員爆發(fā)了:“這簡直不是人干的活!”。
您怎么看待這句話呢?
其實話糙理不糙,用更理性的語言翻譯一下就是“有些工作不應(yīng)該以人工的方式來完成”,比如:
- 大量機械的、重復(fù)性的回歸測試;
- 結(jié)果的正確性不依賴主觀判斷的測試;
- 需要模擬大量數(shù)據(jù)、大量并發(fā)量的測試;
- 需要不間斷執(zhí)行的測試(比如7*24小時持續(xù)執(zhí)行);
- 需要短時間內(nèi)完成的大量測試用例執(zhí)行(比如完整的功能回歸測試);
通過自動化測試可以極大的提升回歸測試、穩(wěn)定性測試以及兼容性測試的工作效率,在保障產(chǎn)品質(zhì)量和持續(xù)構(gòu)建等方面起到舉足輕重的作用。特別是在敏捷開發(fā)模式下,自動化測試是必不可少的。
目前業(yè)界的商業(yè)/開源自動化測試工具有很多,比如,功能測試工具有QTP、Selenium等,性能測試有LoadRunner、JMeter等。其工作原理無非都是通過“測試腳本”和“測試數(shù)據(jù)”來完成“測試過程”,并比較“測試結(jié)果”,進而形成“測試報告”。
本文不對這些測試工具的差異或優(yōu)劣進行對比,只以作者目前采用的Selenium為例進行分析:敏捷開發(fā)模式需要自動化測試,但自動化測試本身的敏捷性又如何呢?
Selenium是針對Web應(yīng)用的開源自動化測試工具,通過編寫模擬用戶操作的腳本,它會打開瀏覽器對Web應(yīng)用進行黑盒測試。可以方便的用于功能測試、兼容性測試、 穩(wěn)定性測試及并發(fā)測試。目前已被主流瀏覽器廠商廣泛支持,同時也是很多其它自動化測試工具(比如,RobotFramework)的底層核心技術(shù)。Selenium由IDE、Remote Control(簡稱RC)、WebDriver、Grid四個工程組成:
- Selenium IDE
是一個用于錄制/回放測試腳本的Firefox附加組件,錄制的腳本可以生成基于Selenium RC的測試代碼(Java、Ruby、C#等)。適用于快速入門,不太適用于實際較大的測試項目;
- Selenium RC
RC由Server和Client組成兩部分組成,Server負責加載/關(guān)閉瀏覽器以及作為HTTP代理來訪問Web應(yīng)用,Clinet支持多種編程語言和測試框架(TestNG、JUnit、NUnit等)。
- Selenium WebDriver
WebDriver作為Selenium2的核心特性提供比RC更簡潔易用的API,是官方推薦的RC替代方案。可以更好的支持動態(tài)網(wǎng)頁,不需要再額外啟動一個獨立的Server。
- Selenium Grid
是Selenium的一個擴展工具,可以很方便地同時在多臺機器上和異構(gòu)環(huán)境中并行運行多個RC或WebDriver用例。
Selenium RC是通過在瀏覽器加載時“注入”JS函數(shù)來操縱后續(xù)的瀏覽器行為,Selenium WebDriver則通過直接調(diào)用各個瀏覽器內(nèi)置的本地事件來達到這一目的。WebDriver目前已經(jīng)作為W3C規(guī)范草案,提交由Google、Mozilla等瀏覽器廠商討論。
WebDriver規(guī)范定義一組與平臺、語言無關(guān)的接口,包括發(fā)現(xiàn)和操作頁面上的元素以及控制瀏覽器行為,主要用于支持Web應(yīng)用的自動化測試。WebDriver的核心是通過findElement方法返回DOM對象(WebElement),通過WebElement可以對DOM對象進行操作(獲取屬性、觸發(fā)事件等)。其中findElement方法需要的元素定位器(Locator)支持ID、XPath、CSS、超鏈接文本等多種方式。
“WebDriver”顧名思義就是“Web瀏覽器驅(qū)動”,它專注于解決如何通過外部命令(通常為測試用例)操作瀏覽器的問題。至于測試用例按照什么順序執(zhí)行、執(zhí)行過程中如何傳遞數(shù)據(jù)、測試結(jié)果如何斷言、如何報告,則可以通過集成其它優(yōu)秀的專業(yè)測試框架(比如,TestNG)來實現(xiàn)(WebDriver沒有必要重復(fù)造輪子)。
下面用以“用戶管理”為例,來看看用WebDriver實現(xiàn)的“增加”和“刪除”測試腳本(只示意部分關(guān)鍵代碼)。
1、在用戶列表頁面點擊“新增”按鈕,跳轉(zhuǎn)到新增用戶頁面:
webDriver.findElement(By.xpath("//a[contains(@id,'addUserBtn')]//button")).click();.腳本解讀:
- By.xpath()表示通過XPath來定位頁面元素;
- click()表示在找到的當前控件上執(zhí)行點擊操作;
2、在新增用戶頁面,輸入“帳號”、“密碼”、“姓名”,選擇“性別”、“生日”和“國籍”,然后點擊“保存”按鈕,回到用戶列表頁面,并判斷是否增加成功:
1) String account="autotest2"; 2) webDriver.findElement(By.xpath("//div[contains(@id,'account_userForm')]//input")).sendKeys(account); 3) webDriver.findElement(By.xpath("//div[contains(@id,'password_userForm')]//input")).sendKeys("1"); 4) webDriver.findElement(By.xpath("//div[contains(@id,'name_userForm')]//input")).sendKeys(account); 5) webDriver.findElement(By.xpath("//div[contains(@id,'sex_userForm')]//input")).click(); 6) webDriver.findElement(By.xpath("//span[text()='女']")).click(); 7) webDriver.findElement(By.xpath("//div[contains(@id,'birthdate_userForm')]//input")).click(); 8) webDriver.findElement(By.xpath("//div[contains(@id,'nationality_userForm')]//input")).click(); 9) webDriver.findElement(By.xpath("//span[text()='中國']")).click(); 10) webDriver.findElement(By.xpath("//a[contains(@id,'userSaveBtn')]//button")).click(); 11) WebElement ele = webDriver.findElement(By.xpath("//div[text()='"+account+"']")); 12) Assert.assertNotNull(ele);腳本解讀:
- sendKeys ()表示在找到的當前控件上輸入字符;
- 2~9行表示通過輸入或點擊選擇的方式為用戶相關(guān)屬性賦值;
- 第10行表示點擊“保存”按鈕(點擊后會自動轉(zhuǎn)向用戶列表頁面);
- 11~12行表示查找頁面上文本內(nèi)容為新增帳號的div,并斷言該div是存在的(不為空);
3、刪除剛剛增加的人員,然后判斷是否刪除成功:
1) webDriver.findElement(By.xpath("//a[contains(@id,'deleteUserBtn')]//button")).click(); 2) WebElement ele = webDriver.findElement(By.xpath("//div[text()='"+account+"']")); 3) Assert.assertNull(ele);腳本解讀:
- 第1行表示點擊“刪除”按鈕;
- 2~3行表示查找頁面上文本內(nèi)容為新增帳號的div,并斷言該div已經(jīng)不存在了(為空);
通過上面的腳本就可以實現(xiàn)“用戶增加、刪除”的自動化測試,并且可以跨瀏覽器。看到這里您會不會覺得整體還不錯,如果測試腳本再能通過錄制的方式自動生成就更好了!
“看”起來確實還不錯,但在實際項目中用起來就沒那么爽了。這其實是在技術(shù)/工具選型時普遍存在的現(xiàn)象:在驗證/試用階段的評價很高,但在投入生產(chǎn)使用時會遇到各種各樣的問題,因此大家在選型階段除了考慮功能,還要考慮技術(shù)/工具本身的開放性和可擴展性。
上面的方案單純從技術(shù)的角度來講是很不錯的:開源、社區(qū)活躍、標準化程度高、支持跨瀏覽器、腳本回放穩(wěn)定、可集成性高,等等。
但是如果就這樣應(yīng)用在實際項目中,會從過程的角度暴露一些棘手的問題:
- 測試腳本是“代碼級”的,那么應(yīng)該由誰來編寫呢?
測試人員和開發(fā)人員好像都有編寫這些測試腳本義務(wù),但似乎又都有不寫的理由。
- 測試腳本必須不斷的修改才能在最新版本上跑通,誰該為此買單?
在敏捷開發(fā)過程中需要快速響應(yīng)需求的變化(新增、變更),這一點整個團隊都好理解。因此如果需求發(fā)生變化,開發(fā)人員修改代碼、測試人員修改測試腳本,一切順理成章,大家相安無事。但是在用戶需求沒有變化時,開發(fā)人員頻繁修改代碼的情況也很常見:比如,修改Bug、針對“壞味道”做重構(gòu)、調(diào)整頁面布局或樣式。于是在“毫無征兆”的情況下,測試腳本又無法執(zhí)行了!
這時候測試人員可能會質(zhì)問開發(fā)人員:“做之前怎么不想清楚?都已經(jīng)測試完成的功能,為什么還總是反復(fù)修改?什么時候代碼才能穩(wěn)定?”。
而開發(fā)人員此時也會非常理直氣壯:“有Bug能不改么?頁面布局不合理導(dǎo)致用戶體驗差,能不改么?而且敏捷中的一個重要的實踐就是重構(gòu)啊”。
大家又是似乎都有道理、也都有苦衷。我雖然作為測試人員,但是在這個問題上還是“偏向于”開發(fā)人員的: 在軟件生命周期的各個階段(需求、設(shè)計、開發(fā)、測試)中,后面的階段對前置階段是有一定依賴的,所以越往后期響應(yīng)變化的難度越大。比如,在“開發(fā)”環(huán)節(jié)不僅需要響應(yīng)“需求”的變化(新增、變更),而且需要響應(yīng)“設(shè)計”的變化。從這個角度來看,“測試”本就應(yīng)該響應(yīng)“開發(fā)”的變化。
對于在實際項目自動化測試過程中遇到的上述問題,歸根到底是因為“自動化測試方案本身的敏捷程度不夠”,主要體現(xiàn)在如下三個方面:
1、 學(xué)習(xí)成本高
測試人員除了要掌握WebDriver接口之外,還要掌握XPath、TestNG的用法,甚至還需要對功能的前臺實現(xiàn)有一定了解。
2、 腳本維護困難
敏銳的開發(fā)/測試人員從上面的示例腳本中,可以馬上嗅出一些“壞味道(Bad Smell)”: 代碼相似度非常高、可能變化的數(shù)據(jù)被硬編碼在測試代碼里、代碼可讀性差、測試代碼與頁面源碼耦合度大,等等。這些壞味道的出現(xiàn),通常意味著需要進行重構(gòu),否則會愈演愈烈,最終變得尾大不掉。
【注】業(yè)界常見的測試工具本質(zhì)上還是針對頁面源碼來編寫(或生成)測試腳本的,即使提供了錄制工具,此類腳本的可讀性和后期可維護性還是非常差的。
3、 斷言條件繁瑣
業(yè)界常見的測試工具即使提供錄制腳本的功能,但是對于“斷言”還是需要人工插入的(工具做不到智能的判斷我們想要在哪里設(shè)置斷言),于是斷言就成了自動化測試人員的“噩夢”。
斷言對象可能很“多”,頁面的信息量往往很大,需要在測試腳本中為每個斷言對象(比如,頁面某個文本框的值)補充斷言語句。
預(yù)期結(jié)果是可能“變”化的,甚至是動態(tài)的,因此預(yù)期結(jié)果的值如果與腳本邏輯耦合在一起,將來極難維護。 斷言機制比較“呆”板,對于 未設(shè)為斷言對象的字段,如果發(fā)生錯誤也是無法感知的,并且難以對于UI樣式或UI邏輯(比如,翻頁圖標應(yīng)該灰顯)進行斷言。
換個角度可以理解為,如果這樣的斷言條件“多”的話,整個測試用例集會“變”的非常“呆”板!
想要有效的改善這些問題,就必須讓自動化測試變得“敏捷”起來!
轉(zhuǎn)載于:https://www.cnblogs.com/xinleishare/p/4256670.html
總結(jié)
以上是生活随笔為你收集整理的敏捷自动化测试(1)—— 我们的测试为什么不够敏捷?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电视盒子为啥不能内置到电视机机里?
- 下一篇: 解决SimpleButton被移除后保持