<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          你不知道的Cypress系列(2) -- ”該死"的PO模型?!

          共 7920字,需瀏覽 16分鐘

           ·

          2020-12-23 23:37

          iTesting,愛(ài)測(cè)試,愛(ài)分享


          我的新書(shū)前端自動(dòng)化測(cè)試框架Cypress從入門(mén)到精通出版啦!


          自從我的新書(shū)<前端自動(dòng)化測(cè)試框架 -- Cypress從入門(mén)到精通>上市以來(lái),這本書(shū)受到了大量同學(xué)熱情的追捧和討論。在跟同學(xué)們的交流中,我也了解到, 原來(lái)除了國(guó)外優(yōu)秀的公司(例如Adobe, 迪士尼,AutoDesk等等), 國(guó)內(nèi)也有很多公司在嘗試使用Cypress提升測(cè)試效率。而在Cypress中國(guó)群內(nèi)、在公眾號(hào)iTesting里,我每天都能看到大量關(guān)于Cypress的使用討論和私下問(wèn)詢。這讓我感到無(wú)比榮幸。(買(mǎi)了書(shū)的同學(xué)們,公眾號(hào)回復(fù)你的微信號(hào),拉你到Cypress中國(guó)群)。


          除了日常推薦大家通過(guò)閱讀我的書(shū)來(lái)解決日常Cypress使用問(wèn)題外,我也一直在更新著我這邊的Cypress知識(shí)圖譜, 不夸張的說(shuō),目前我總結(jié)和實(shí)踐下來(lái)知識(shí)點(diǎn)多達(dá)200多篇。本著“雕琢自我,普惠他人”的原則,我決定在公眾號(hào)iTesting上開(kāi)設(shè)<你不知道的Cypress系列>專(zhuān)欄。此專(zhuān)欄目的是分享一些我自己趟過(guò)的坑,走過(guò)的彎路、以及在選型時(shí)拋棄了的實(shí)踐。希望讓大家在選用Cypress作為前端自動(dòng)化測(cè)試框架方案時(shí), 可以借鑒一下,避免再走我走過(guò)的彎路。


          今天是<你不知道的Cypress系列>的第二篇 --  絕知此事要躬行,別被Cypress官方忽悠瘸了!


          為了讓大家看到標(biāo)題就知道我再說(shuō)什么,我把標(biāo)題更改為:


          你不知道的Cypress系列(2) -- ”該死"的PO模型


          01

          PO模型是什么


          無(wú)論你基于何種自動(dòng)化測(cè)試框架開(kāi)發(fā)你的測(cè)試腳本,PO模型絕對(duì)是你繞不過(guò)的坎兒。


          PO模型(Page Object Module)算得上自動(dòng)化測(cè)試的最佳實(shí)踐之一,其中心思想如下:

          • 把物理上的頁(yè)面或者邏輯上的功能組合當(dāng)成一個(gè)Page 類(lèi)處理。

          • 針對(duì)每一個(gè)Page類(lèi),將此Page上所屬的元素、此Page類(lèi)上元素動(dòng)作的組合分別封裝成Object, 以及Class Methods。

          • 所有針對(duì)此頁(yè)面的操作以Page 類(lèi)的實(shí)例引用。


          從代碼實(shí)現(xiàn)上來(lái)看,元素、元素操作、 Page類(lèi)、Page類(lèi)對(duì)應(yīng)的測(cè)試類(lèi)就是PO。


          實(shí)現(xiàn)PO模型后,測(cè)試用例的操作細(xì)節(jié)會(huì)被隱藏,轉(zhuǎn)而以面向?qū)ο?,或者說(shuō),以業(yè)務(wù)角度展示操作步驟,我們直接看一個(gè)PO封裝后的測(cè)試用例:

          import LoginPage from "../pages/login"import mainPage from "../pages/main"

          describe('PageObject模式之登錄測(cè)試', function () {// 關(guān)注公眾號(hào)iTesting,玩轉(zhuǎn)Cypressconst username = 'iTesting'const password = 'password123'
          it('登錄成功', function () {const loginInstance = new LoginPage() loginInstance.visitPage() .isTargetPage() .login(username, password)
          const mainInstance = new mainPage() mainInstance.isTargetPage() .welComeText.should('contain', 'iTesting') })})

          從業(yè)務(wù)角度看,PO模型非常直觀:

          初始化LoginPage實(shí)例訪問(wèn)LoginPage判斷LoginPage可訪問(wèn)登錄
          接著訪問(wèn)mainPage(登錄后會(huì)跳轉(zhuǎn)的頁(yè)面)判斷mainPage可訪問(wèn)在mainPage上斷言



          02


          PO模型的好處


          由上文可以看到, PO模型的目的,主要是為了重用元素,做到每個(gè)元素定位、每個(gè)元素、甚至每個(gè)類(lèi)方法,在整個(gè)項(xiàng)目中,有且僅有一處定義,其它都是調(diào)用。通過(guò)這樣的方式,PO模型做到了即使在復(fù)雜項(xiàng)目中,也不會(huì)增加維護(hù)成本。


          除此之外,在當(dāng)前微服務(wù)開(kāi)發(fā)模式下,動(dòng)輒十幾個(gè)、幾十個(gè)微服務(wù)會(huì)同步進(jìn)行開(kāi)發(fā)。那么,過(guò)去那種一個(gè)測(cè)試工程師搞定所有自動(dòng)化測(cè)試的機(jī)會(huì)不再有了。當(dāng)前大多數(shù)公司的實(shí)踐是將測(cè)試框架收歸專(zhuān)門(mén)團(tuán)隊(duì)負(fù)責(zé),而將自動(dòng)化腳本的編寫(xiě)下放到各微服務(wù)團(tuán)隊(duì)。對(duì)應(yīng)的, 各個(gè)團(tuán)隊(duì)下的業(yè)務(wù)測(cè)試工程師要具體負(fù)責(zé)其微服務(wù)的自動(dòng)化測(cè)試。


          PO模型天然帶來(lái)一個(gè)好處,即,Page類(lèi)天然隔離了模塊和團(tuán)隊(duì)。例如我是團(tuán)隊(duì)A的測(cè)試工程師,除去公用Page外,我只需要關(guān)注我這個(gè)微服務(wù)下的所有Page類(lèi)及類(lèi)方法即可。而不必關(guān)心其它團(tuán)隊(duì)所own的頁(yè)面。


          如果我對(duì)其它組的服務(wù)有依賴,這些通常會(huì)構(gòu)建專(zhuān)門(mén)的函數(shù)并成為Common Page的一部分。


          如果有新人進(jìn)來(lái),他的學(xué)習(xí)成本只是我們團(tuán)隊(duì)負(fù)責(zé)的頁(yè)面 + 公用Page,相對(duì)來(lái)說(shuō)比較友好。


          03


          Cypress怎么看PO模型


          正如Cypress官方所宣揚(yáng)的一樣:

          // The page object pattern isn’t actually anything “special”.

          換句話說(shuō), Page Object只是方便重用而已,沒(méi)什么大不了。


          Cypress官方覺(jué)得Page Object模型里的大量Page類(lèi)及其對(duì)應(yīng)的測(cè)試類(lèi)的使用,會(huì)加重調(diào)用鏈條,隱藏各個(gè)操作之間的動(dòng)作細(xì)節(jié),加重使用者的負(fù)擔(dān), 具體來(lái)說(shuō):


          1. 使用PO模型人為的在測(cè)試中引入了其他狀態(tài),這些狀態(tài)是你(測(cè)試腳本創(chuàng)建者)自己定義的,而不是應(yīng)用程序內(nèi)部擁有的, 它增加了debug成本。

          // 這個(gè)假設(shè)是成立的,因?yàn)槌绦騼?nèi)部并沒(méi)有Page,更遑論P(yáng)age里的方法。// 那么當(dāng)你運(yùn)行失敗時(shí)發(fā)現(xiàn),Page.addWallet失敗了,你無(wú)法直接知道哪里出錯(cuò)// 你必須找到addWallet的定義,再去查看其實(shí)現(xiàn),才能知道哪里錯(cuò)。

                 2. 使用PO模型使得測(cè)試速度變慢。

          // 這也是事實(shí)。// 畢竟你每次操作都要先initial Page實(shí)例,然后再尋找類(lèi)方法,最后才是執(zhí)行。

                 3.   使用PO模型使代碼陷入“Conditional Testing”的怪圈。

          // 比如你的方法里存在如下判斷:// 如果頁(yè)面發(fā)生AAA, 你會(huì)進(jìn)行BBB操作, 如果發(fā)生CCC,你會(huì)進(jìn)行DDD操作。// 這在Cypress看來(lái)是反模式。因?yàn)镃ypress跟你的應(yīng)用程序運(yùn)行在同一個(gè)生命周期。// Cypress可以捕獲應(yīng)用程序里發(fā)生的一切。// 所以,你理應(yīng)知道你的操作引發(fā)的結(jié)果到底是AAA還是CCC。


          這3條, 條條劍指PO模型的七寸。


          Cypress官方又說(shuō),好既然PO不好用, 而且它存在只是為了方便重用,那么我給你更好的辦法:


          于是Custom Commands出爐了。Custom Commands你可以看成是PO模型里的Common Page。所有在Custom Commands里定義的方法,天生可以被任何測(cè)試之間調(diào)用。相當(dāng)于你生成了自己的全局命令。


          來(lái)看一個(gè)Custom Commands的具體例子:

          Cypress.Commands.add('login', (username, password) => {    Cypress.log({        name: 'login',        message: `${username} | ${password}`,    })    // 關(guān)注公眾號(hào)iTesting,精通Cypress使用return cy.request({        method: 'POST',        url: '/login',        form: true,        body: {            username,            password,        },    })})


          這樣,在使用上,你也不需要管什么Login Page類(lèi),Login測(cè)試類(lèi)了。你在任何代碼里直接寫(xiě):

          cy.login("關(guān)注iTesting,玩轉(zhuǎn)Cypress")

          它自然幫你登錄成功, Page是什么?頓時(shí)不香了好嗎!


          Custom Commands的具體用法我的新書(shū)<前端自動(dòng)化測(cè)試框架 -- Cypress從入門(mén)到精通>里講的還算通透,這里就不多說(shuō)。


          另外,在JavaScript世界里, 很講究一個(gè)鏈?zhǔn)秸{(diào)用(Chainable), Custom COmmands + 鏈?zhǔn)秸{(diào)用,Cypress認(rèn)為它完全可以取代PO模型。


          通過(guò)chainable把你的所有操作“可視化”。于是,一個(gè)Cypress推崇的測(cè)試用例就變成這樣:

          /// 
                
          describe('Custom Commands模式之登錄測(cè)試', function () {// 關(guān)注公眾號(hào)iTesting,玩轉(zhuǎn)Cypress
          it('登錄成功', function () { cy.login(username, password) .verifyLoginSuccess() .verifyWelcomeTxt() })})

          從cypress角度,你看到的是login成功后直接去驗(yàn)證welcome的文本在不在。


          這樣感覺(jué)代碼量是不是更少,代碼更直觀了?


          03


          我怎么看PO和Custom Commands


          這里我也談下我對(duì)PO和Custom Commands的看法。


          首先要謹(jǐn)記:Cypress的出現(xiàn)是為Developer服務(wù)的,它對(duì)Developer的友好程度要高于Tester。


          基于此,我們?cè)賮?lái)看登錄成功這個(gè)用例, 你看到的是

          cy.xxx()   .yyy()   .zzz()

          這樣的模式調(diào)用鏈清晰,從層次上來(lái)是,也比PO模型少了一層。出錯(cuò)后的調(diào)試,也更方便。


          但是!


          你的測(cè)試用例都是cy這樣,cy那樣,當(dāng)然對(duì)于Cypress官方來(lái)說(shuō),很成功,Visibility非常高,簡(jiǎn)直是Cypress的活廣告,美滋滋?。?/span>


          可是,你的“業(yè)務(wù)”呢?


          不錯(cuò)!你的業(yè)務(wù)以及業(yè)務(wù)細(xì)節(jié)被隱藏了!


          雖然從Cypress的Custom Commands方式讓測(cè)試寫(xiě)起代碼來(lái)更爽,但是別忘記,在國(guó)內(nèi),我們還存在大量的測(cè)試人員,測(cè)試開(kāi)發(fā)水平不足?。ù藭r(shí)應(yīng)該有廣告,我的拉勾專(zhuān)欄<測(cè)試開(kāi)發(fā)入門(mén)與實(shí)戰(zhàn)>開(kāi)欄24小時(shí)內(nèi)售賣(mài)超10000+, 破了測(cè)試專(zhuān)欄的記錄,值得你去拉勾上搜一下 :))


          而且,從習(xí)慣上來(lái)說(shuō),國(guó)內(nèi)的同學(xué)們更習(xí)慣從業(yè)務(wù)角度去理解測(cè)試。并且Custom Commands把所有的公用功能都寫(xiě)在一個(gè)文件里,對(duì)測(cè)試人員來(lái)說(shuō)不友好,當(dāng)我的測(cè)試用例超過(guò)10000條時(shí),Custom Commands里的公用方法,恐怕也有幾百個(gè)了??偛荒芪襾?lái)一個(gè)新人,讓他花上幾周時(shí)間去熟悉所有的方法吧!況且,都微服務(wù)了,他以后基本也只負(fù)責(zé)其中一些測(cè)試,那么我讓他學(xué)那么多跟他沒(méi)關(guān)系的方法干嘛呢?


          雖然Custom Commands也可以做到按照微服務(wù)組織,然后在每個(gè)微服務(wù)Folder下實(shí)現(xiàn)一個(gè)Custom Commands的子域。但是,這樣做,你使用時(shí)候由要跟PO模型一樣先引入再使用, 那么它跟PO模型又有什么區(qū)別呢??。?/span>

          ?


          04


          PO和Custom Commands我都要


          紙上得來(lái)終覺(jué)淺!

          紙上得來(lái)終覺(jué)淺!

          紙上得來(lái)終覺(jué)淺!


          不能迷信權(quán)威!我剛開(kāi)始搭建公司的前端框架時(shí), 我就完全按照Cypress官方建議做,結(jié)果,當(dāng)我的測(cè)試用例到達(dá)幾千條時(shí),我傻了,Custom Commands里的方法幾百個(gè),即使是我自己寫(xiě)的,但我自己也鬧不清楚哪個(gè)做哪個(gè)用處,因?yàn)闆](méi)有了Page做參考,時(shí)間一長(zhǎng),我很難從函數(shù)命名上看出這個(gè)方法應(yīng)該在那個(gè)頁(yè)面下使用, 更別說(shuō)對(duì)框架不熟悉的新人了。


          結(jié)果沒(méi)辦法,我重新返工了一遍,把特別核心的公用功能放到Custom Commands里,把跟業(yè)務(wù)有關(guān)的,還是以Page Object方式組織。放到微服務(wù)下,放到Page下,這樣, 再來(lái)新人,我告訴他,你只要看這個(gè)commands這個(gè)文件還有你的微服務(wù)folder就好了。


          所以, PO + Custom Commands + chainable是我的最佳實(shí)踐, 以后我的測(cè)試用例就變成這樣了。

          ///

          import mainPage from "../pages/main"describe('PageObject模式之登錄測(cè)試', function () {// 關(guān)注公眾號(hào)iTesting,玩轉(zhuǎn)Cypressconst username = 'iTesting'const password = 'password123'
          it('登錄成功', function () { cy.login(username, password)const mainInstance = new mainPage() mainInstance.isTargetPage() .welComeText.should('contain', 'iTesting') })})


          這下終于清靜了!是么?


          Cypress又提出了一個(gè)模型,App Actions, 同學(xué),你想去嘗嘗鮮嗎?


          往期回看:

                      你不知道的Cypress系列(1) --雞肋的BDD

          下期預(yù)告:

                    你不知道的Cypress系列(3) -- 是時(shí)候重構(gòu)自己的思維了!


          為了更好的支持我創(chuàng)作,麻煩同學(xué)們動(dòng)動(dòng)小手,點(diǎn)贊 + 在看 + 轉(zhuǎn)發(fā)一鍵三聯(lián):)



          技術(shù)討論

          公眾號(hào)里直接回復(fù) 666, 帶你入圈。


           -   -  時(shí)人莫小池中水, 淺處不妨有臥龍  -  -

          作者:

          Kevin Cai, 江湖人稱蔡老師。

          兩性情感專(zhuān)家,非著名測(cè)試開(kāi)發(fā)。

          技術(shù)路線的堅(jiān)定支持者,始終相信Nobody can be somebody。      


          · 猜你喜歡的文章 ·

          功能測(cè)試進(jìn)階系列直播(免費(fèi))

          前端測(cè)試框架Cypress從入門(mén)到精通

          自研測(cè)試框架ktest介紹(適用于UI和API)

          測(cè)試開(kāi)發(fā)入門(mén)與實(shí)踐

          瀏覽 50
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  97影院在线午夜 | 人妻在线中文字幕 | 国产一级a毛一级a看… | www.天天操.com | 欧美性爱69网 |