摘要:針對于類型已經出啦個方法來判斷在各種庫里,也出現(xiàn)了想等語義判斷。在斷言庫里,類型判斷也是必不可少的一部分。測試用例應該會。在下一個測試套件內,還是依照默認值。
前一篇文章,我們已經簡單的闡述了BDD,TDD以及mocha測試框架,chai斷言庫. 這里我們將進一步深入,比較全部的了解測試的API。
前文,我們已經知道了,BDD本身可以比擬為文章的骨架,而chai斷言庫就是骨架里面的血管和肌肉(脂肪). 兩者結合才能寫出一片完美的測試文章。 這里,我們先看一下脂肪是怎么煉成的。
這里我針對expect斷言進行一些講解,順便把一些比較重要的API,梳理一遍。
邏輯指示語法:
not deep any all andnot
取非語法
expect(1).to.not.equal(2); //passdeep
深層檢查,該主要針對于對象和數組類型。 就好比復制一樣,分為深復制和淺復制. 通常情況下,我們直接比較的都是淺層.
像這樣的
//淺層比較 var expect = require("chai").expect; var test1 = { foo:{ bar:1 } } var test2 = { bar:1 } describe("Counter",function(){ it("test",()=>{ expect(test1.foo).to.equal(test2); }) }) //fail //使用深層比較 describe("Test",function(){ it("test",()=>{ expect(test1.foo).to.deep.equal(test2); }) }) //passany
按正常語法看,這里就是任意的意思。通常搭配keys一起使用,用來表示或的意思。
expect(test1).to.have.any.keys("foo","bar");all
這個語法和"any"的使用也差不多,也是用來表示keys的包含狀況
//test1對象的所有keys只有foo和bar expect(test1).to.have.all.keys("foo","bar");
上面的邏輯語法通常和動詞語法一起使用.
常用的動詞語法有:
equal include (alias: contain) satisfy match change
通常,我們使用這里動詞結合名詞來表達一個狀態(tài)
equal顧名思義就是相等的意思唄。直接看一下demo
expect(1).to.equal(1); //相等 expect(2).to.not.equal(3); //不相等include
包含的意思,其實他的alias還有contains,includes。 不過表達的都是一樣的意思,所以推薦直接使用include就可以了。include經常和array,string,以及object使用. 正對于這3種類型,《包含》意味著:
array: 查詢是否包含子項 string: 查詢是否包含子字符串 object: 查詢是否包含子對象
//查詢array是否包含子項 expect([1,2,3,4,5]).to.include(3); //包含sting的子串 expect("good").to.include("oo"); //判斷對象是否包含子對象 expect({first:1,second:2}).to.include({second:2})
還記得上文提到的have嗎? 其實,這個和include是有區(qū)別的。 一般而言,have通常是和keys進行搭配的.
expect({first:1,second:2}).to.have.any.keys("first"); //等價于 expect({first:1,second:2}).to.include.keys("first");
另外,have本身自帶all的效果,所以感覺"all"通常是和include一起搭配.
expect({first:1,second:2}).to.have.keys("first","second"); //等價于 expect({first:1,second:2}).to.have.all.keys("first","second"); //等價于 expect({first:1,second:2}).to.include.all.keys("first","second");satisfy
這個應該可以算是一個萬能assertion. 他的參數是一個函數,接受的參數就是expect里面的內容。 而且該函數的返回值必須是Boolean. 如果你的返回值沒有的話,那么該case是不會通過的。
expect({first:1,second:2}).to.satisfy(function(obj){ return obj.first===1; }); //pass
雖然是萬能的,但是極力不推薦使用,因為是在是太好用了,而造成的problem就是你的測試用例不清晰,沒有很好的可讀性。要知道斷言庫的出現(xiàn)就是讓你的測試用例能夠像文章一樣具有良好的可讀性.
match這個方法其實和string.match是比較類似的。他們都是用來檢測字符串類型,是否滿足正則的測試。
expect("good").to.match(/(oo){1}/); //passchange
用來表征一個對象的值是否被一個函數所改變.
get to the point
//測試對象 var test2 = { bar:1 } function changeValue(){ test2.bar=2; } //測試用例 expect(changeValue).to.change(test2,"bar");
事實上,這個真的沒有什么卵用。用的頻率還是蠻低的。
Okkkkay~
在斷言中還有最重要的一部分,關于number的判斷.
常用的number判斷有:
above(alias: gt) below(alias: lt) least(alias: gte) most(alias: lte) withinabove
above等價于greater than(>=). 但是above能更好的表達語義,所以這里就使用above.
expect(2).to.above(1);below
同理below和above類似. below等價于less than(<=)
expect(2).to.not.below(1); expect(2).to.below(3);least
在中文意譯就為至少為多少~ 翻譯為數學語言就是 (>=) . 這里,我們需要明確一個概念,即,測試用例應該給你最直觀的感受, 我們的用例是給normal people看的,而不是特指針對于數學家,或者程序員看的。
使用最佳語義化的表達就是最重要的.
expect(num).to.least(1); //翻譯一遍就是: num至少為1most
和least相似。我這里就不舉例論證了。
expect(num).to.most(12); //num最多為12within
標識一個數的range. 相當于,數學上的 "[num1,num2]". 判斷你的expect是否在這個區(qū)間內。
expect(1).to.within(1,2); //pass
關于Number這一塊內容我們差不多梳理完了。
是不是很枯燥呀~
恩~ 我也這么覺得
下面,我們再來看一點枯燥的東西唄。 破罐子破摔
類型判斷
要知道,在js中,類型判斷是最奇葩的一個。 針對于類型js已經出啦3個方法來判斷》 instanceof typeof constructor. 在各種庫里,也出現(xiàn)了想isArray,isBoolean,isArrayLike等語義API判斷。 在斷言庫里,類型判斷也是必不可少的一部分。
instanceof ok false true null undefined exist emptyinstanceof
和constructor類型判斷類似。 用來判斷一個對象的原來構造函數是誰。
function changeValue(){} var test1 = new changeValue(); describe("Test",function(){ it("test",()=>{ expect(test1).to.be.instanceof(changeValue); }) })ok/true/exist
上述3個語法的關系應該是:exist>ok>true.
由于3者類似,這里就一起說明了。
exist就是用來判斷一個值是否存在,即,既不是null也不是undefined.
而,ok是用來判斷一個值是否ok(別打我~). 即,該值既不是null,也不是undefined,更不是false
true就很簡單,只有true才能pass. 相當于"==="的效果.
詳看demo:
//exist->pass expect("exist").to.exist; expect(null).to.not.exist; expect(undefined).to.not.exist; expect(false).to.exist; //ok->pass expect("exist").to.be.ok; expect(null).to.not.be.ok; expect(undefined).to.not.be.ok; expect(false).to.not.be.ok; //對于上面的exist //true->pass expect(true).to.be.true; expect(1).to.not.be.true;false/null/undefined/empty
這些都是判斷一個內容是否不滿足時而造出來語法.
看字面形式可以知道,他們分別對應于自己的類型。
false->false
null->null
undefined->undefined
而,empty則是判斷expect的length是否為0. 當然針對于沒有l(wèi)ength屬性的類型。測試用例應該會die。
expect("").to.be.empty; expect(12).to.not.be.empty;
到這里,expect的斷言庫,差不多就這些了。 如果大家還有種想要學習的沖動,可以去mocha官網上學習(認真臉)
BDD額外語法上篇介紹了describe的一些基本語法,但是好像還是紕漏了一些,比較高級的API。
一個為only.一個為skip.還有一個為done
only方法表示在一個block內,只運行該用例的測試。它通常在你滿屏輸出錯誤的時候,進行分開修改bug而使用的. 可以在it或者describe上面使用
describe("Test",function(){ it.only("test",()=>{ expect(1).to.equal(1); }); it("it will output error",function(){ expect(2).to.equal(3); }) }) //在命令行測試會直接pass。 因為第二個測試用例并沒有執(zhí)行skip
該方法,用來跳過某個測試用例。 同樣在正常情況下,我們不會使用這個API。 它的使用情況依然是,調試你在一個Block里,寫出很多個測試時,才會使用.
describe("Test",function(){ it("test",()=>{ expect(1).to.equal(1); }); it.skip("it will output error",function(){ expect(2).to.equal(3); }) }) //第一個會提示pass //第二個會提示pendingdone
這個應該是為js量身打造的.因為js本身就是一門異步語言,而mocha無法污染異步的API,所以這個done就是給我們手動去檢測異步結束而設立的。
來個栗子:
//沒有異步效果,結果會直接輸出I"m testing,而I"ve finished test卻沒有效果 describe("Test",function(){ it("test",()=>{ console.log("I"m testing") setTimeout(function(){ console.log("I"ve finished test"); },200); }); }) //這里我們需要加上一個異步的flag--done describe("Test",function(){ it("test",(done)=>{ //這里加上一個done的參數,表示這是個異步的測試用例 console.log("I"m testing") setTimeout(function(){ console.log("I"ve finished test"); done(); //這里手動告訴mocha我已經測試完了 },200); }); }); 輸出的結果為: //I"m testing //I"ve finished test
而,大部分時候,異步測試并不是去測試setTimeout(are u **?). 最主要測試異步的應該是Promise或者是$.Deferred。不過es6最近風行,我們一樣以Promise作為例子,Deferred的原理和Promise是一樣的.
異步測試Promise測試Promise的時候,我們當然可以使用上述的done方法來mark一下.
describe("Test",function(){ before(function(){ console.log("I"m testing"); }) it("test",(done)=>{ "use strict"; new Promise(function(resolve,reject){ setTimeout(()=>{ resolve("ok"); }, 200) }) .then(function(){ console.log("I"ve finished the test"); done(); }) }); }); //正常情況會輸出: 標識成功 // I"m testing //I"ve finished the test
但是需要注意的是,如果你的異步執(zhí)行時間過長,mocha是不會wait u的。 mocha默認的最低時間是2s。所以,如果你的異步時間超出了。像這樣:
new Promise(function(resolve,reject){ setTimeout(()=>{ resolve("ok"); }, 2000) }) .then(function(){ console.log("I"ve finished the test"); done(); })
他會直接爆出這樣的錯誤.
Error: timeout of 2000ms exceeded
當然,如果你想改變他的默認值設置也可以。
想這樣設置就over了
mocha -t 10000
或者直接測試用例中多帶帶設置:
describe("Test",function(){ this.timeout(100); before(function(){ console.log("I"m testing"); }); it("test",(done)=>{ "use strict"; new Promise(function(resolve,reject){ setTimeout(()=>{ resolve("ok"); }, 2000) }) .then(function(){ console.log("I"ve finished the test"); done(); }) }); }); //由于你的時間設置過短,所以會出現(xiàn)上述一樣的錯誤
這里的this.timeout只能影響到,當前的測試套件。 在下一個測試套件內,還是依照默認值2000ms。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/78674.html
摘要:針對于類型已經出啦個方法來判斷在各種庫里,也出現(xiàn)了想等語義判斷。在斷言庫里,類型判斷也是必不可少的一部分。測試用例應該會。在下一個測試套件內,還是依照默認值。 前一篇文章,我們已經簡單的闡述了BDD,TDD以及mocha測試框架,chai斷言庫. 這里我們將進一步深入,比較全部的了解測試的API。前文,我們已經知道了,BDD本身可以比擬為文章的骨架,而chai斷言庫就是骨架里面的血管和...
閱讀 2907·2021-11-19 09:40
閱讀 3578·2021-10-09 09:43
閱讀 2675·2021-09-22 15:31
閱讀 1724·2021-07-30 15:31
閱讀 782·2019-08-30 15:55
閱讀 3257·2019-08-30 15:54
閱讀 1161·2019-08-30 11:26
閱讀 1907·2019-08-29 13:00