qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請(qǐng)?jiān)L問(wèn) http://qaseven.github.io/

          我們的測(cè)試為什么不夠敏捷?

          測(cè)試是為了保證軟件的質(zhì)量,敏捷測(cè)試關(guān)鍵是保證可以持續(xù)、及時(shí)的對(duì)軟件質(zhì)量情況進(jìn)行全面的反饋。由于在敏捷開(kāi)發(fā)過(guò)程中每個(gè)迭代都會(huì)增加功能、修復(fù)缺陷或重構(gòu)代碼,所以在完成當(dāng)前迭代新增特性測(cè)試工作的同時(shí),還要通過(guò)回歸測(cè)試來(lái)保證歷史功能不受影響。為此我們期望:

            測(cè)試范圍足夠廣:

            ● 測(cè)試用例要覆蓋所有功能;

            ● 要在各種可能的環(huán)境下作兼容性測(cè)試;

            ● 系統(tǒng)的穩(wěn)定性、性能都要測(cè)試;

            測(cè)試頻率足夠高:

            ● 每日構(gòu)建產(chǎn)生的版本要保證可用;

            ● 每個(gè)迭代都需要對(duì)歷史功能做回歸測(cè)試;

            ● 釋放前或上線后如果打了補(bǔ)丁,就需要回歸;

            但實(shí)際情況往往不遂人愿:

            實(shí)際測(cè)試周期變短:

            ● 上線時(shí)間提前確定,研發(fā)進(jìn)度延期,測(cè)試計(jì)劃被迫延后;

            ● 最后階段經(jīng)常會(huì)臨時(shí)增加測(cè)試任務(wù);

            ● 所有人都知道還需要再經(jīng)過(guò)一輪測(cè)試,但時(shí)間沒(méi)有了;

            有效測(cè)試資源稀缺:

            ● 臨時(shí)從其他項(xiàng)目抽調(diào)的測(cè)試人員不能立刻有效的開(kāi)展測(cè)試工作;

            ● “搞不清楚”本項(xiàng)目的研發(fā)人員到底是不會(huì)做測(cè)試還是不愿做測(cè)試;

            因此由于客觀上的資源和時(shí)間限制,完整的、及時(shí)回歸測(cè)試在人工測(cè)試情況下,往往是不可能完成的任務(wù)。團(tuán)隊(duì)內(nèi)部也會(huì)產(chǎn)生各種爭(zhēng)執(zhí):

            ● 提交給測(cè)試的版本為什么研發(fā)人員不先做通過(guò)性測(cè)試?

            ● 這次代碼改動(dòng)量不大,有必要再花那么多時(shí)間回歸么?

            ● 當(dāng)初不是承諾這次修改肯定不會(huì)影響以前的功能么?

            ● 怎么不早說(shuō)要支持Chrome瀏覽器,現(xiàn)在哪還有時(shí)間測(cè)試啊?

            怎么能讓現(xiàn)場(chǎng)出現(xiàn)這種低級(jí)的Bug,打補(bǔ)丁后為什么不仔細(xì)回歸一遍?

            爭(zhēng)執(zhí)越演越烈,最終有團(tuán)隊(duì)成員爆發(fā)了:“這簡(jiǎn)直不是人干的活!”。

            您怎么看待這句話呢?

            其實(shí)話糙理不糙,用更理性的語(yǔ)言翻譯一下就是“有些工作不應(yīng)該以人工的方式來(lái)完成”,比如:

            ● 大量機(jī)械的、重復(fù)性的回歸測(cè)試;

            ● 結(jié)果的正確性不依賴主觀判斷的測(cè)試;

            ● 需要模擬大量數(shù)據(jù)、大量并發(fā)量的測(cè)試;

            ● 需要不間斷執(zhí)行的測(cè)試(比如7*24小時(shí)持續(xù)執(zhí)行);

            ● 需要短時(shí)間內(nèi)完成的大量測(cè)試用例執(zhí)行(比如完整的功能回歸測(cè)試);

           通過(guò)自動(dòng)化測(cè)試可以極大的提升回歸測(cè)試、穩(wěn)定性測(cè)試以及兼容性測(cè)試的工作效率,在保障產(chǎn)品質(zhì)量和持續(xù)構(gòu)建等方面起到舉足輕重的作用。特別是在敏捷開(kāi)發(fā)模式下,自動(dòng)化測(cè)試是必不可少的。

            目前業(yè)界的商業(yè)/開(kāi)源自動(dòng)化測(cè)試工具有很多,比如,功能測(cè)試工具有QTP、Selenium等,性能測(cè)試有LoadRunner、JMeter等。其工作原理無(wú)非都是通過(guò)“測(cè)試腳本”和“測(cè)試數(shù)據(jù)”來(lái)完成“測(cè)試過(guò)程”,并比較“測(cè)試結(jié)果”,進(jìn)而形成“測(cè)試報(bào)告”。

            本文不對(duì)這些測(cè)試工具的差異或優(yōu)劣進(jìn)行對(duì)比,只以作者目前采用的Selenium為例進(jìn)行分析:敏捷開(kāi)發(fā)模式需要自動(dòng)化測(cè)試,但自動(dòng)化測(cè)試本身的敏捷性又如何呢?

            Selenium是針對(duì)Web應(yīng)用的開(kāi)源自動(dòng)化測(cè)試工具,通過(guò)編寫(xiě)模擬用戶操作的腳本,它會(huì)打開(kāi)瀏覽器對(duì)Web應(yīng)用進(jìn)行黑盒測(cè)試??梢苑奖愕挠糜诠δ軠y(cè)試、兼容性測(cè)試、 穩(wěn)定性測(cè)試及并發(fā)測(cè)試。目前已被主流瀏覽器廠商廣泛支持,同時(shí)也是很多其它自動(dòng)化測(cè)試工具(比如,RobotFramework)的底層核心技術(shù)。Selenium由IDE、Remote Control(簡(jiǎn)稱RC)、WebDriver、Grid四個(gè)工程組成:

            ● Selenium IDE

            是一個(gè)用于錄制/回放測(cè)試腳本的Firefox附加組件,錄制的腳本可以生成基于Selenium RC的測(cè)試代碼(Java、Ruby、C#等)。適用于快速入門(mén),不太適用于實(shí)際較大的測(cè)試項(xiàng)目;

            ● Selenium RC

            RC由Server和Client組成兩部分組成,Server負(fù)責(zé)加載/關(guān)閉瀏覽器以及作為HTTP代理來(lái)訪問(wèn)Web應(yīng)用,Clinet支持多種編程語(yǔ)言和測(cè)試框架(TestNG、JUnit、NUnit等)。

            ● Selenium WebDriver

            WebDriver作為Selenium2的核心特性提供比RC更簡(jiǎn)潔易用的API,是官方推薦的RC替代方案??梢愿玫闹С謩?dòng)態(tài)網(wǎng)頁(yè),不需要再額外啟動(dòng)一個(gè)獨(dú)立的Server。

            ● Selenium Grid

            是Selenium的一個(gè)擴(kuò)展工具,可以很方便地同時(shí)在多臺(tái)機(jī)器上和異構(gòu)環(huán)境中并行運(yùn)行多個(gè)RC或WebDriver用例。

            Selenium RC是通過(guò)在瀏覽器加載時(shí)“注入”JS函數(shù)來(lái)操縱后續(xù)的瀏覽器行為,Selenium WebDriver則通過(guò)直接調(diào)用各個(gè)瀏覽器內(nèi)置的本地事件來(lái)達(dá)到這一目的。WebDriver目前已經(jīng)作為W3C規(guī)范草案,提交由Google、Mozilla等瀏覽器廠商討論。

            WebDriver規(guī)范定義一組與平臺(tái)、語(yǔ)言無(wú)關(guān)的接口,包括發(fā)現(xiàn)和操作頁(yè)面上的元素以及控制瀏覽器行為,主要用于支持Web應(yīng)用的自動(dòng)化測(cè)試。WebDriver的核心是通過(guò)findElement方法返回DOM對(duì)象(WebElement),通過(guò)WebElement可以對(duì)DOM對(duì)象進(jìn)行操作(獲取屬性、觸發(fā)事件等)。其中findElement方法需要的元素定位器(Locator)支持ID、XPath、CSS、超鏈接文本等多種方式。

            “WebDriver”顧名思義就是“Web瀏覽器驅(qū)動(dòng)”,它專注于解決如何通過(guò)外部命令(通常為測(cè)試用例)操作瀏覽器的問(wèn)題。至于測(cè)試用例按照什么順序執(zhí)行、執(zhí)行過(guò)程中如何傳遞數(shù)據(jù)、測(cè)試結(jié)果如何斷言、如何報(bào)告,則可以通過(guò)集成其它優(yōu)秀的專業(yè)測(cè)試框架(比如,TestNG)來(lái)實(shí)現(xiàn)(WebDriver沒(méi)有必要重復(fù)造輪子)。

            下面用以“用戶管理”為例,來(lái)看看用WebDriver實(shí)現(xiàn)的“增加”和“刪除”測(cè)試腳本(只示意部分關(guān)鍵代碼)。

            1、在用戶列表頁(yè)面點(diǎn)擊“新增”按鈕,跳轉(zhuǎn)到新增用戶頁(yè)面:

          webDriver.findElement(By.xpath("http://a[contains(@id,'addUserBtn')]//button")).click();

            腳本解讀:

            ● By.xpath()表示通過(guò)XPath來(lái)定位頁(yè)面元素;

            ● click()表示在找到的當(dāng)前控件上執(zhí)行點(diǎn)擊操作;

            2、在新增用戶頁(yè)面,輸入“帳號(hào)”、“密碼”、“姓名”,選擇“性別”、“生日”和“國(guó)籍”,然后點(diǎn)擊“保存”按鈕,回到用戶列表頁(yè)面,并判斷是否增加成功:

          1)  String account="autotest2";
          2)  webDriver.findElement(By.xpath("http://div[contains(@id,'account_userForm')]//input")).sendKeys(account);
          3)  webDriver.findElement(By.xpath("http://div[contains(@id,'password_userForm')]//input")).sendKeys("1");
          4)  webDriver.findElement(By.xpath("http://div[contains(@id,'name_userForm')]//input")).sendKeys(account);
          5)  webDriver.findElement(By.xpath("http://div[contains(@id,'sex_userForm')]//input")).click();
          6)  webDriver.findElement(By.xpath("http://span[text()='女']")).click();  
          7)  webDriver.findElement(By.xpath("http://div[contains(@id,'birthdate_userForm')]//input")).click();
          8)  webDriver.findElement(By.xpath("http://div[contains(@id,'nationality_userForm')]//input")).click();
          9)  webDriver.findElement(By.xpath("http://span[text()='中國(guó)']")).click();     
          10) webDriver.findElement(By.xpath("http://a[contains(@id,'userSaveBtn')]//button")).click();        
          11) WebElement ele = webDriver.findElement(By.xpath("http://div[text()='"+account+"']"));    
          12) Assert.assertNotNull(ele);

            腳本解讀:

            ● sendKeys ()表示在找到的當(dāng)前控件上輸入字符;

            ● 2~9行表示通過(guò)輸入或點(diǎn)擊選擇的方式為用戶相關(guān)屬性賦值;

            ● 第10行表示點(diǎn)擊“保存”按鈕(點(diǎn)擊后會(huì)自動(dòng)轉(zhuǎn)向用戶列表頁(yè)面);

            ● 11~12行表示查找頁(yè)面上文本內(nèi)容為新增帳號(hào)的div,并斷言該div是存在的(不為空);

            3、刪除剛剛增加的人員,然后判斷是否刪除成功:

          1)  webDriver.findElement(By.xpath("http://a[contains(@id,'deleteUserBtn')]//button")).click();
          2)  WebElement ele = webDriver.findElement(By.xpath("http://div[text()='"+account+"']"));
          3)  Assert.assertNull(ele);

            腳本解讀:

            ● 第1行表示點(diǎn)擊“刪除”按鈕;

            ● 2~3行表示查找頁(yè)面上文本內(nèi)容為新增帳號(hào)的div,并斷言該div已經(jīng)不存在了(為空);

            通過(guò)上面的腳本就可以實(shí)現(xiàn)“用戶增加、刪除”的自動(dòng)化測(cè)試,并且可以跨瀏覽器。看到這里您會(huì)不會(huì)覺(jué)得整體還不錯(cuò),如果測(cè)試腳本再能通過(guò)錄制的方式自動(dòng)生成就更好了!

            “看”起來(lái)確實(shí)還不錯(cuò),但在實(shí)際項(xiàng)目中用起來(lái)就沒(méi)那么爽了。這其實(shí)是在技術(shù)/工具選型時(shí)普遍存在的現(xiàn)象:在驗(yàn)證/試用階段的評(píng)價(jià)很高,但在投入生產(chǎn)使用時(shí)會(huì)遇到各種各樣的問(wèn)題,因此大家在選型階段除了考慮功能,還要考慮技術(shù)/工具本身的開(kāi)放性和可擴(kuò)展性。

            上面的方案單純從技術(shù)的角度來(lái)講是很不錯(cuò)的:開(kāi)源、社區(qū)活躍、標(biāo)準(zhǔn)化程度高、支持跨瀏覽器、腳本回放穩(wěn)定、可集成性高,等等。

            但是如果就這樣應(yīng)用在實(shí)際項(xiàng)目中,會(huì)從過(guò)程的角度暴露一些棘手的問(wèn)題:

            ● 測(cè)試腳本是“代碼級(jí)”的,那么應(yīng)該由誰(shuí)來(lái)編寫(xiě)呢?

            測(cè)試人員和開(kāi)發(fā)人員好像都有編寫(xiě)這些測(cè)試腳本義務(wù),但似乎又都有不寫(xiě)的理由。

            ● 測(cè)試腳本必須不斷的修改才能在最新版本上跑通,誰(shuí)該為此買(mǎi)單?

            在敏捷開(kāi)發(fā)過(guò)程中需要快速響應(yīng)需求的變化(新增、變更),這一點(diǎn)整個(gè)團(tuán)隊(duì)都好理解。因此如果需求發(fā)生變化,開(kāi)發(fā)人員修改代碼、測(cè)試人員修改測(cè)試腳本,一切順理成章,大家相安無(wú)事。但是在用戶需求沒(méi)有變化時(shí),開(kāi)發(fā)人員頻繁修改代碼的情況也很常見(jiàn):比如,修改Bug、針對(duì)“壞味道”做重構(gòu)、調(diào)整頁(yè)面布局或樣式。于是在“毫無(wú)征兆”的情況下,測(cè)試腳本又無(wú)法執(zhí)行了!

            這時(shí)候測(cè)試人員可能會(huì)質(zhì)問(wèn)開(kāi)發(fā)人員:“做之前怎么不想清楚?都已經(jīng)測(cè)試完成的功能,為什么還總是反復(fù)修改?什么時(shí)候代碼才能穩(wěn)定?”。

            而開(kāi)發(fā)人員此時(shí)也會(huì)非常理直氣壯:“有Bug能不改么?頁(yè)面布局不合理導(dǎo)致用戶體驗(yàn)差,能不改么?而且敏捷中的一個(gè)重要的實(shí)踐就是重構(gòu)啊”。

            大家又是似乎都有道理、也都有苦衷。我雖然作為測(cè)試人員,但是在這個(gè)問(wèn)題上還是“偏向于”開(kāi)發(fā)人員的: 在軟件生命周期的各個(gè)階段(需求、設(shè)計(jì)、開(kāi)發(fā)、測(cè)試)中,后面的階段對(duì)前置階段是有一定依賴的,所以越往后期響應(yīng)變化的難度越大。比如,在“開(kāi)發(fā)”環(huán)節(jié)不僅需要響應(yīng)“需求”的變化(新增、變更),而且需要響應(yīng)“設(shè)計(jì)”的變化。從這個(gè)角度來(lái)看,“測(cè)試”本就應(yīng)該響應(yīng)“開(kāi)發(fā)”的變化。

            對(duì)于在實(shí)際項(xiàng)目自動(dòng)化測(cè)試過(guò)程中遇到的上述問(wèn)題,歸根到底是因?yàn)?#8220;自動(dòng)化測(cè)試方案本身的敏捷程度不夠”,主要體現(xiàn)在如下三個(gè)方面:

            1、學(xué)習(xí)成本高

            測(cè)試人員除了要掌握WebDriver接口之外,還要掌握XPath、TestNG的用法,甚至還需要對(duì)功能的前臺(tái)實(shí)現(xiàn)有一定了解。

            2、腳本維護(hù)困難

            敏銳的開(kāi)發(fā)/測(cè)試人員從上面的示例腳本中,可以馬上嗅出一些“壞味道(Bad Smell)”: 代碼相似度非常高、可能變化的數(shù)據(jù)被硬編碼在測(cè)試代碼里、代碼可讀性差、測(cè)試代碼與頁(yè)面源碼耦合度大,等等。這些壞味道的出現(xiàn),通常意味著需要進(jìn)行重構(gòu),否則會(huì)愈演愈烈,最終變得尾大不掉。

            【注】業(yè)界常見(jiàn)的測(cè)試工具本質(zhì)上還是針對(duì)頁(yè)面源碼來(lái)編寫(xiě)(或生成)測(cè)試腳本的,即使提供了錄制工具,此類腳本的可讀性和后期可維護(hù)性還是非常差的。

            3、斷言條件繁瑣

            業(yè)界常見(jiàn)的測(cè)試工具即使提供錄制腳本的功能,但是對(duì)于“斷言”還是需要人工插入的(工具做不到智能的判斷我們想要在哪里設(shè)置斷言),于是斷言就成了自動(dòng)化測(cè)試人員的“噩夢(mèng)”。

            斷言對(duì)象可能很“多”,頁(yè)面的信息量往往很大,需要在測(cè)試腳本中為每個(gè)斷言對(duì)象(比如,頁(yè)面某個(gè)文本框的值)補(bǔ)充斷言語(yǔ)句。

            預(yù)期結(jié)果是可能“變”化的,甚至是動(dòng)態(tài)的,因此預(yù)期結(jié)果的值如果與腳本邏輯耦合在一起,將來(lái)極難維護(hù)。 斷言機(jī)制比較“呆”板,對(duì)于 未設(shè)為斷言對(duì)象的字段,如果發(fā)生錯(cuò)誤也是無(wú)法感知的,并且難以對(duì)于UI樣式或UI邏輯(比如,翻頁(yè)圖標(biāo)應(yīng)該灰顯)進(jìn)行斷言。

            換個(gè)角度可以理解為,如果這樣的斷言條件“多”的話,整個(gè)測(cè)試用例集會(huì)“變”的非常“呆”板!

            想要有效的改善這些問(wèn)題,就必須讓自動(dòng)化測(cè)試變得“敏捷”起來(lái)!

            在本系列后續(xù)的文章中會(huì)就“如何讓測(cè)試腳本易寫(xiě)、易讀、易維護(hù)”、“如何讓斷言不再成為測(cè)試的負(fù)擔(dān)”、“如何通過(guò)持續(xù)集成讓測(cè)試用例發(fā)揮更大的價(jià)值”進(jìn)行詳細(xì)的介紹,敬請(qǐng)關(guān)注!



          posted on 2013-01-15 10:43 順其自然EVO 閱讀(296) 評(píng)論(0)  編輯  收藏 所屬分類: 測(cè)試學(xué)習(xí)專欄管理方向

          <2013年1月>
          303112345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 分宜县| 丹阳市| 新安县| 昔阳县| 阿拉善右旗| 桦南县| 兴文县| 邯郸县| 从江县| 青铜峡市| 台安县| 吉安县| 额敏县| 浮山县| 阜康市| 福海县| 金秀| 綦江县| 临澧县| 宿州市| 郯城县| 无极县| 阜城县| 喀什市| 乳山市| 新河县| 惠州市| 房产| 麦盖提县| 池州市| 永德县| 邢台县| 东港市| 成都市| 定边县| 桓台县| 年辖:市辖区| 濮阳市| 襄樊市| 蒙山县| 中江县|