基于CodeceptJS,從0到1搭建E2E自動化測試框架

CodeceptJS

CodeceptJS是基于現(xiàn)代web技術(shù)的E2E自動化測試框<wbr>架,具有特殊的BDD風(fēng)格語法土铺;基于 Feature 和 Scenario 兩個粒度來組織測試讓它看起來更有 E2E 測試的樣子萤悴,它支持最新的ES6語法瘾腰,<wbr>同時也屏蔽各種復(fù)雜的回調(diào)細(xì)節(jié),<wbr>所有的測試用例都是以第一人稱來做覆履,<wbr>讓測試代碼閱讀起來更像是自然語言蹋盆。

Quick Start

第一步,先讓測試跑起來

按照quick start搭建了環(huán)境硝全,寫出了第一個測試-登陸栖雾,感覺so easy.

Feature('My First Test');

Scenario('test something', ({ I }) => {
  I.amOnPage('https://github.com');
  I.click('Sign in');
  I.fillField('username', 'myName');
  I.fillField('password', 'myPassword');
  I.click('Sign in');
  I.see('Welcome, myName');
});

CI

第一個測試成功了,趕緊放到CI上跑一跑柳沙,每天定時運(yùn)行岩灭,<wbr>自動做回歸測試,想想都覺得很美好赂鲤。 那么問題來了噪径,CI server上沒有安裝測試工具所需的環(huán)境依賴怎么辦?<wbr>在哪個環(huán)境運(yùn)行数初,DEV找爱,QA,UAT泡孩?<wbr>運(yùn)行完以后有report嗎车摄?

別急,都有現(xiàn)成的解決方案仑鸥。
在CI server上啟動一個包含測試環(huán)境依賴的docker吮播,<wbr>先讓測試運(yùn)行在最可控的QA環(huán)境,<wbr>搜索一款最適合當(dāng)前工具的report眼俊,比如allure意狠,<wbr>跟devops小哥哥pair一下,<wbr>jenkinsfile就生成了疮胖,<wbr>E2E自動化測試每天定時跑起來了环戈,<wbr>測試運(yùn)行失敗就會發(fā)送消息到日常工作群闷板,及時發(fā)現(xiàn)問題~

pipeline {
  agent {
    kubernetes {
      label 'swgen2-e2e'
      defaultContainer 'jnlp'
      yaml """
        apiVersion: v1
        kind: Pod
        metadata:
        labels:
          app: swgen2-e2e-app
        spec:
          containers:
          - name: codecepjs
            image: codeception/codeceptjs
            command:
            - cat
            tty: true
      """
    }
  }

    stages {
        stage('Run e2e in qa') {
            steps {
                catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
                    container('codecepjs') {
                    sh 'codeceptjs run --grep @qa -o \'{ "helpers": {"TestCafe": {"url": "https://swgen2-qa.successwareg2.com"}}}\' --plugins allure'
                    }
                  }
                }
        }
    }

    post {
        always {
            script {
                allure([
                        includeProperties: false,
                        jdk: '',
                        properties: [],
                        reportBuildPolicy: 'ALWAYS',
                        results: [[path: 'output']]
                ])
            }
        }
        failure {
            slackSend(color: '#FF0000',
                    channel: '#swplatform-jenkins',
                    message: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL}) \nCommitter: (${getCommitter()})")
        }
        fixed {
            slackSend(color: '#00FF00',
                    channel: '#swplatform-jenkins',
                    message: "BACK TO NORMAL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
        }
    }
}

新的問題

CodeceptJS支持語義化的元素定位符,<wbr>可以自動判斷定位符類型并且尋找元素院塞,<wbr>對于編寫測試代碼來說確實(shí)很方便遮晚,不用辛辛苦苦找元素定位了,<wbr>可是有些元素通過文本作為定位符找不到啊拦止,<wbr>而且通過文本找元素好像很慢县遣?還有哪些元素定位的方式?
CodeceptJS的操作就支持amOnPage汹族,<wbr>click艺玲,fillField嗎?我還有一些其他的操作鞠抑,<wbr>應(yīng)該怎么寫啊忌警?
CodeceptJS的斷言只支持see嗎搁拙?<wbr>我還有地方要用not see,它也能支持嗎法绵?

這幾個問題拋出了學(xué)習(xí)一個自動化測試工具的基本路徑箕速,<wbr>那就是學(xué)習(xí)元素定位符,操作朋譬,斷言盐茎,<wbr>其中元素定位符對于一般的UI自動化測試工具都是通用的,<wbr>而操作和斷言徙赢,每個工具提供的語法不一樣字柠。然而,<wbr>一旦掌握一種工具狡赐,其他任何工具學(xué)習(xí)起來都很快窑业。學(xué)好數(shù)理化,<wbr>走遍天下都不怕~

持續(xù)優(yōu)化

此刻枕屉,我的元素定位符常柄,操作,斷言已經(jīng)寫得很溜了搀擂。 當(dāng)我開始寫越來越多的測試后發(fā)現(xiàn)西潘,每個測試都要登陸一下,<wbr>怎么樣才能減少這種重復(fù)操作呢哨颂? 除了登錄喷市,我的代碼中很多重復(fù)操作,怎么樣封裝他們咆蒿,<wbr>方便調(diào)用呢东抹? dev小伙伴升級了依賴庫蚂子,導(dǎo)致元素定位變化了,<wbr>我需要大面積修改元素定位符缭黔,怎樣才能提高元素定位符的通用性食茎,<wbr>避免此類情況再次發(fā)生?

第一步馏谨,提取公共元素别渔,比如文本框,<wbr>當(dāng)我需要使用某個文本框時只需要輸入文本框的label就能定位<wbr>到它了惧互;

//封裝公共元素
editInput: function (inputName, text) {
      let locator = `//label[contains(., "${inputName}")]/preceding-sibling::input`;
      this.clearField(locator);
      this.appendField(locator, text);
    },

//

第二步哎媚,提取公共step,比如click tab作為common step放到一個文件里喊儡,當(dāng)我在任何頁面需要click tab時拨与,只需要寫上tab上的文字就可以了,<wbr>codeceptjs對button和link做了一層封裝艾猜,<wbr>所以看到quickstart里面买喧,click sign in的元素定位符只需要寫上文字就可以了;

第三步匆赃,提取公共function淤毛,比如登錄,<wbr>搜索等不同頁面常用操作放到common function文件里面算柳;

第四步低淡,提取每個頁面的公共function,<wbr>針對一個頁面的某個feature如果有多種測試場景瞬项,<wbr>此時公共function可以復(fù)用蔗蹋。

場景設(shè)計(jì)的巧思

測試場景設(shè)計(jì)需要許多巧思,<wbr>這樣才能讓E2E在日常運(yùn)行中更為流暢囱淋。

  • 盡可能精簡纸颜。因?yàn)镋2E保證的是主要功能和流程正確,<wbr>摻雜太多細(xì)節(jié)驗(yàn)證會讓代碼復(fù)雜度急劇增加绎橘,維護(hù)成本太高胁孙,<wbr>同時還會讓自己陷入我到底應(yīng)該把哪些測試點(diǎn)加入到E2E的焦慮中<wbr>。先用20%的精力做成80%的事情称鳞,再用剩下的80%<wbr>的精力想想怎么拔高20%涮较,比如提高團(tuán)隊(duì)的質(zhì)量意識。
  • 每個測試場景盡可能獨(dú)立冈止。這樣在其中一個場景報錯時狂票,<wbr>不會影響其他場景的測試結(jié)果,<wbr>并且任何時候想單獨(dú)運(yùn)行某個或某幾個測試都可以立即運(yùn)行熙暴,<wbr>不用修改代碼才能運(yùn)行闺属。場景獨(dú)立帶來的副作用就是慌盯,<wbr>會有許多重復(fù)操作,這時就需要封裝來解決這些冗余代碼掂器。
  • 在測試套件中進(jìn)行登錄操作亚皂。測試場景獨(dú)立的話,<wbr>每個測試開始前都需要進(jìn)行登錄操作国瓮,這會拉慢測試運(yùn)行速度灭必,<wbr>如果測試工具支持的話,<wbr>設(shè)置為在每個測試套件開始前進(jìn)行登錄操作乃摹,<wbr>這會大大減少重復(fù)的登錄操作禁漓。
  • 需要考慮數(shù)據(jù)的初始化。<wbr>數(shù)據(jù)初始化的方案要么是通過頁面操作去造數(shù)據(jù)孵睬,<wbr>它的缺點(diǎn)是添加了大量和測試場景無關(guān)的額外操作播歼,<wbr>使得代碼復(fù)雜加運(yùn)行時間變長;要么通過API造數(shù)據(jù)掰读,<wbr>但需要E2E測試工具支持荚恶;要么通過連接數(shù)據(jù)庫,<wbr>直接向數(shù)據(jù)庫插入數(shù)據(jù)磷支,缺點(diǎn)是數(shù)據(jù)庫表之間關(guān)聯(lián)關(guān)系復(fù)雜的話,<wbr>難以摸清這些關(guān)聯(lián)關(guān)系食寡,容易造出臟數(shù)據(jù)雾狈,<wbr>同時連接數(shù)據(jù)庫也需要E2E測試工具支持;<wbr>我最傾向的方式是在不受影響的環(huán)境中運(yùn)行E2E抵皱,<wbr>使用提前準(zhǔn)備好的固定數(shù)據(jù)善榛,當(dāng)然用完就失效的數(shù)據(jù),<wbr>比如跟狀態(tài)相關(guān)的數(shù)據(jù)呻畸,還是只能通過前三種方式創(chuàng)建移盆。
  • 需要考慮數(shù)據(jù)使用后的還原。這樣才能在下次運(yùn)行同一個測試時伤为,<wbr>不會因?yàn)閿?shù)據(jù)被改變而失敗咒循。
  • 加tag區(qū)分不同環(huán)境的測試。<wbr>針對不同環(huán)境運(yùn)行的測試場景不一樣的情況绞愚,<wbr>加tag區(qū)分不同環(huán)境叙甸,運(yùn)行時加上tag參數(shù)即可。

更多思考

E2E總是被詬病位衩,運(yùn)行太慢裆蒸,維護(hù)頻繁,反饋太晚糖驴。<wbr>但在實(shí)際使用過程中僚祷,E2E發(fā)現(xiàn)了不少新功能破壞舊功能的情況佛致,<wbr>然而單元測試沒有發(fā)現(xiàn)這些問題(UT覆蓋率也很高)。<wbr>那么為了更好地使用E2E辙谜,就需要不斷優(yōu)化它俺榆。運(yùn)行太慢,<wbr>那么就在多個docker里面并發(fā)運(yùn)行筷弦;維護(hù)頻繁肋演,<wbr>那么就盡量用不容易變化的元素定位符,并且多封裝烂琴,<wbr>一旦發(fā)生變化改動也不會很多爹殊;反饋太晚,額奸绷。梗夸。。<wbr>它的屬性就是如此号醉,<wbr>用它來做日常的回歸測試保證舊功能完好是個不錯的選擇反症。

最后的成果

目前我們的項(xiàng)目上,一共有31個測試場景畔派,<wbr>單個docker容器里面運(yùn)行全部測試耗時大概13分鐘铅碍,<wbr>每次部署QA或者UAT后自動trigger E2E分別在不同環(huán)境運(yùn)行,<wbr>再也不用擔(dān)心Dev的重構(gòu)或者環(huán)境部署不當(dāng)造成的bug沒有及時<wbr>發(fā)現(xiàn)了线椰。另外胞谈,因?yàn)橛泻芏喙苍睾凸膊襟E的封裝,<wbr>添加新的測試代碼也很容易憨愉。唯一令人頭大的點(diǎn)就是烦绳,<wbr>它有時候有點(diǎn)不穩(wěn)定,報一些手動操作沒有的bug配紫,這類bug debug起來很難径密,也不知道算不算bug。躺孝。享扔。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市植袍,隨后出現(xiàn)的幾起案子伪很,更是在濱河造成了極大的恐慌,老刑警劉巖奋单,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锉试,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)呆盖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門拖云,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人应又,你說我怎么就攤上這事宙项。” “怎么了株扛?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵尤筐,是天一觀的道長。 經(jīng)常有香客問我洞就,道長盆繁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任旬蟋,我火速辦了婚禮油昂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘倾贰。我一直安慰自己冕碟,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布匆浙。 她就那樣靜靜地躺著安寺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪首尼。 梳的紋絲不亂的頭發(fā)上挑庶,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機(jī)與錄音饰恕,去河邊找鬼。 笑死井仰,一個胖子當(dāng)著我的面吹牛埋嵌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播俱恶,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼雹嗦,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了合是?” 一聲冷哼從身側(cè)響起了罪,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎聪全,沒想到半個月后泊藕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡难礼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年娃圆,在試婚紗的時候發(fā)現(xiàn)自己被綠了玫锋。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡讼呢,死狀恐怖撩鹿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情悦屏,我是刑警寧澤节沦,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站础爬,受9級特大地震影響甫贯,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜幕帆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一获搏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧失乾,春花似錦常熙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至纽竣,卻和暖如春墓贿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蜓氨。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工聋袋, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人穴吹。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓幽勒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親港令。 傳聞我的和親對象是個殘疾皇子啥容,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容