摘要:前同事留下的測試,是基于瀏覽器的,主要還是功能測試。這里不詳細說怎么在瀏覽器端使用測試了。而且作者也是建議和支持這樣做的,簡單明了的測試腳本,重要性有時候可能和測試本身一樣重要。經測試,在瀏覽器也有這種問題。
2016-09-03 更新
隨著在工作學習中更多地接觸、使用測試工具,發現自己在本文中的一些記錄是不準確、不正確的。
今天(九月三日)在家看了 NingJs 的直播,其中有一個分享是關于測試框架的,非常棒,之后有可能的話還是找來視頻再學習下。
是的,兩個月前的理解,是很初級很淺陋的。
繼續學習,繼續鉆研吧。
交代前因前些天接手了一個舊項目。幸好不是在原來的基礎上做些修修改改的工作,可以算是開發新版的。
把前面同事留下來的代碼 down 下來,看了一下。總體還是挺好的。還有 macha + chai 的測試目錄。
我也是最近一段時間開始接觸測試。很久之前看了阮大神寫的 mocha 教程,不過也就看看,寫寫簡單的 demo。
前同事留下的測試,是基于瀏覽器的,主要還是功能測試。這里不詳細說怎么在瀏覽器端使用 mocha 測試了。因為涉及到交互的反饋、追蹤,所以采用的方式是,先用 iframe 加載待測頁面,然后用 contentWindow 的方式拿到 iframe 的環境,再做一些操作。手動觸發一些功能,然后再去判斷相應的變化有沒有發生。
本地啟動了一個 server,瀏覽器里跑了幾遍測試。最后發現的問題是,有一個點擊測試怎么都過不了。于是又開啟了閱讀代碼的過程。
最后發現了問題所在,頁面使用的是自己封裝的 tap 事件,整個事件系統也是對原生 Element 原型的拓展。可是怎么觸發 tap 呢?前同事用了 touchend。可是并沒有用啊, tap 事件的觸發可是結合了從 touchstart 開啟一系列事件參數的判斷的。
后來我就想,瀏覽器端功能測試,能不能也拿到命令行上面來呢?
從 mocha 轉到 ava正在此時,我想起了 jsdom 這個大神級作品。
一開始打算用 mocha + jsdom 跑一把。折騰了幾次發現,mocha 這家伙不好適應異步的工作,這事情很難搞啊。
可能要交代下我做了什么,嗯,我加載了一個 jquery 腳本,這樣就得外部文件,于是就有異步場景了。試了好多遍,mocha 還是沒能實現我的期望。(你也可以拿 mocha 試試看,多試幾次,如果單純靠那個 done 你就能成功,那么請私信我喲。)
又想想白天亂逛 github 的時候,在一些個項目中看到了 ava 這個測試工具。搜索一番,據說正適用于異步場景。
好,那就來試試看唄。前因交代清楚了,下面開始正式進入教程階段。
開始講 demo我將自己的 demo 放到了 github 上,地址是https://github.com/AngusFu/jsdom-ava-demo。你可以直接克隆項目,然后在本地跑起來。
因為是 demo,項目內容很簡單,兩個 js,一個用于測試 html 文件。
測試場景先說測試場景:頁面上有一個紅色背景的 div,通過原生的 addEventListener 綁定了 click 事件。點擊之后,將背景色變換為綠色。就醬簡單?對,主要就這個,一方面我是想測試下 jsdom 對事件系統和 css 解析的支持(手動觸發事件,css 解析和值變化),一方面是想試試這種異步場景下怎么更好地測試。
那些對測試腳本運行速度有非常嚴格要求的同學請想好了再往后看。因為根據我的經驗,jsdom + ava 這倆組合起來,速度確實慢得不行。我還沒仔細探究原因,但想來無非以下幾點:
測試腳本要經過 babel 6 編譯一遍,有耗時;
jsdom 系統比較龐大,解析起來費勁;
我使用了 jsdom 的 jQueryify 方法從外部加載了 jQuery 文件(但這方法確實給力);
ava 本身其他方面的問題;
暫且忍著點。
核心 html 如下:
測試工具安裝
下面來談工具的安裝。
首先安裝 jsdom,這倒是很簡單:
$ npm install --save jsdom
接著安裝 ava,最好先全局安裝一遍:
$ npm install -g ava $ npm install --save ava
然后為了方便使用 npm test 命令,執行下面的命令:
$ ava --init
這一行的目的是將 ava 命令放到你的 package.json 中的 scripts 字段中,方便之后使用 npm test 直接開啟跑測試。當然你也可以不管這一步,我就比較喜歡自己敲 ava xx.js 這樣子。
編寫測試好了,環境安裝完畢。下面來看腳本。
import fs from "fs"; import { jsdom } from "jsdom"; import test from "ava";
ava 在運行時會通過 babel 6 對測試腳本進行編譯,因此完全可以自由發揮,generator、async & await 什么的都盡情地用吧。而且作者也是建議和支持這樣做的,簡單明了的測試腳本,重要性有時候可能和測試本身一樣重要。
引入 fs 是為了讀取我們的 html 文件。
關于 jsdom 的用法,更多的可以參考 https://github.com/tmpvar/jsdom,看項目的文檔。這里我使用的是簡單易懂的 require("jsdom").jsdom 形式,便于以同步的形式解析生成我們需要的 window 對象,如下:
var window = jsdom(fs.readFileSync("./test.html")).defaultView;
一個挺好用的方法是 jsdom.jQueryify,能向頁面注入 jQuery。不過這是個異步的方法(廢話),所以這里我使用了 Promise,也是為了方便之后使用 async & await 語法。
function jsdomTest() { return new Promise(function (resolve, reject) { jsdom.jQueryify(window, "http://apps.bdimg.com/libs/jquery/2.1.4/jquery.js", function () { resolve(window.jQuery); }); }); }
ava 的測試用例寫起來也挺簡單,來看代碼:
test("點擊測試", async t => { var $ = await jsdomTest(); var $div = $("#div"); var colorBeforeClick, colorAfterClick; console.log(colorBeforeClick = $div.css("background-color")); $div.trigger("click"); console.log(colorAfterClick = $div.css("background-color")); t.not(colorBeforeClick, colorAfterClick, "bgColor changed"); });
test 的第一個參數是測試用例的名稱,第二個參數是一個函數,該函數會注入 t 對象。我們所有的斷言都是通過這個注入的 t 進行的。
友情提示:ava 的文檔地址,https://github.com/avajs/ava,也有中文版,但是沒更新同步,所以建議還是看英文,否則用了一些過時的 API,以后升級之后追悔莫及。
來說上面的代碼。首先我們使用的是 async & await 語法,整個看起來比回調函數嵌套要整潔許多,整個流程看起來也相對清楚。
第一步是先等待 jQuery 注入成功,拿到 $。其實這一步可有可無,我純粹是為了測試 jsdom API,并且懶得手動寫 dispatch 事件的代碼才這么干的。
接下來就開始 DOM 查詢,然后先獲取 div 當前的背景色并打印出來。接著手動觸發 click 事件,然后再次獲取 div 的背景色并打印。最后將觸發點擊前后的兩個顏色值拿來對比。
依葫蘆畫瓢,差不多就這么搞定了。
打開命令行,進入工作目錄,然后開始測試:
$ ava -v parallel.js
相信我,-v 參數可以讓你的命令行界面顯得比較安靜一些。
如果你想要使用 npm test 這樣的命令來測試,請進一步閱讀文檔進行相關配置(將上面的 ava 換成 nom test是沒用的哦)。這里主要還是為了簡便。
友情提示友情提示第二波:會不會懷疑,觸發點擊事件之后,顏色立馬就變了?不存在延遲、異步么?答案是 yes,真的不存在。假如你和我一樣在這里猶豫了,那么說明存在這樣兩種可能性:
js 基礎不夠牢,對相關機制的了解還不透徹
你被各種異步玩怕了(hybrid / RN 后遺癥 )
當時為了應對“潛在的異步”(啊我想到了迫害狂想癥),我特意做了幾百毫秒的 setTimeout 延時。結果呢,斷言的謂詞(not、same、notSame等等)各種正向、反向都試了一遍,測試永遠通過。什么鬼?說好的良好的異步支持呢?后來再去看文檔,發現人家寫得清清楚楚:
You must define all tests synchronously. They can"t be defined inside setTimeout, setImmediate, etc.
所有測試必須同步定義。不能放在 setTimeout、setImmediate 等方法里面。
所以,真的,認真讀文檔是很有必要的。
真正遇到要延時的,怎么辦?我想,Promise 會解救你的。
并行與串行ava 聲稱是很高效的。通常情況下,同一個文件里測試都是并行的,并不一定按照順序執行。
還以上面的代碼為例。為了測試一下,我選擇了投機取巧。不是并行嗎?那我就檢測 jQuery 存不存在就不行了嗎?因為我們的 test 中,是異步加載 jQuery 的。所以如果測試是并行的,那么不一定能夠檢測到 window.$ 的存在。
所以就有了 parallel.js 這個文件。添加的測試用例如下:
test("串行測試", function (t) { console.log(window.$) t.true(!!window.$, "串行失敗"); });
可是,如果我就要串行呢?
還好作者也想到了這種情況。將所有的 test 改成 test.serial 即可(見 serial.js)。
需要說明的是,所謂的串行執行,只是在同一個測試文件中存在,同時測試多個文件的時候,就總體而言仍然是并行的。
結尾ava 還有很多的用法和需要注意的地方。最好的辦法還是看文檔,然后自己寫 demo,反復領會,并應用在實際業務中。
上面提到的內容,可能有不少錯誤。希望懂行的大神們能夠提出來。
突然想到古人說,“茍日新,又日新,日日新”。
雖然經過今人考證,這也許只是類似甲骨文的祭祀記錄的誤讀。但幾千年來,這種“新”的精神始終在。
程序世界里,變化更是無時不在。今天的工具,明天也許就會被淘汰。
其實說到底,能夠解決需求,能夠方便高效使用的,才是最好的。
向做出這些工具的大神們致敬。
更新 a 標簽點擊事件的坑a 標簽的點擊事件用了事件代理,然后通過手動觸發無效。
經測試,在瀏覽器也有這種問題。
解決辦法是直接使用 $("a")[0].click(),原生的 click 方法比較靠譜。
參考: http://stackoverflow.com/questions/773639/how-can-i-simulate-an-anchor-click-via-jquery
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/8726.html
摘要:單元測試,測試一個簡單的組件。接口測試,用戶信息接口測試。學習借鑒,一些使用做測試的開源項目。這里使用到的內置斷言斷言結果值等于我們想要的預期值,則測試通過。在里放入一個函數,函數自動執行,里面執行的結果必須拋出錯誤,則測試通過。 目錄 1、為什么選擇 AVA ?2、API 概覽。3、準備工作。4、單元測試,測試一個簡單的工具函數。5、使用 Promise、Async/await、Ob...
摘要:詳情在線是一個簡單的在線詳情一套前端架構庫說不上快速,但其集成了自定義元素可觀察對象路由等,是一款輕量級的庫。和等都有使用它。詳情這是一本涵蓋和內容的新書,可在線閱讀或付費下載電子書。 01. 2018 JavaScript 測試概覽 文章介紹了JavaScript測試的關鍵術語、測試類型、工具和方法,并簡要分析了工具jsdom、Istanbul、Karma、Chai、Wallaby等...
摘要:詳情在線是一個簡單的在線詳情一套前端架構庫說不上快速,但其集成了自定義元素可觀察對象路由等,是一款輕量級的庫。和等都有使用它。詳情這是一本涵蓋和內容的新書,可在線閱讀或付費下載電子書。 01. 2018 JavaScript 測試概覽 文章介紹了JavaScript測試的關鍵術語、測試類型、工具和方法,并簡要分析了工具jsdom、Istanbul、Karma、Chai、Wallaby等...
摘要:詳情在線是一個簡單的在線詳情一套前端架構庫說不上快速,但其集成了自定義元素可觀察對象路由等,是一款輕量級的庫。和等都有使用它。詳情這是一本涵蓋和內容的新書,可在線閱讀或付費下載電子書。 01. 2018 JavaScript 測試概覽 文章介紹了JavaScript測試的關鍵術語、測試類型、工具和方法,并簡要分析了工具jsdom、Istanbul、Karma、Chai、Wallaby等...
閱讀 1802·2023-04-26 00:47
閱讀 1553·2021-11-11 16:55
閱讀 2623·2021-09-27 14:04
閱讀 3560·2021-09-22 15:58
閱讀 3561·2021-07-26 23:38
閱讀 2137·2019-08-30 13:47
閱讀 1988·2019-08-30 13:15
閱讀 1152·2019-08-29 17:09