在我以前的
javascript fullstack
項目中,單元測試一直是分裂的碘菜,react
前端用jest凹蜈,node.js
后端用mocha限寞。由于在前端使用jest
時,所體會到的簡潔仰坦,讓我一直有沖動想用jest
來一統(tǒng)江湖履植。在最近的一個項目中,我做到了悄晃,對比mocha
玫霎,我有下面一些體會。
配置簡潔
jest
幾乎是可以零配置的妈橄。它會自動識別一些常用的測試文件pattern庶近,比如__test__
、*.spec.js
眷蚓、 *.test.js
等鼻种。我的nodejs項目的配置文件只有下面幾行,下面是指package.json
文件:
"scripts": {
"test": "jest"
},
"jest": {
"testEnvironment": "node"
}
testEnvironment
這個配置是對于nodejs項目是必須的沙热,如果不配置叉钥,在async的單元測試中如果拋出異常,則系統(tǒng)不會立刻停止篙贸,而只會超時投队,并且不會定位錯誤位置。
配置完后爵川,就可以用yarn run test
來運行測試了蛾洛。
測試代碼簡潔
- 在
mocha
中我們必須要describe
,比如:
descibe('suiteA', () => {
before(() => {})
it('testA', () => {
})
it('testA', () => {
})
)
可是文件已經把一個個suite
分開雁芙,為什么還要describe
轧膘,所以jest
可以省略describe
,如下:
beforeAll(() => {})
it('testA', () => {
})
it('testA', () => {
})
-
jest
幾乎內置了所有單元測試需要的庫兔甘,比如mock
和expect
谎碍,無需像mocha
一樣需要引入一堆。
易于和babel集成
為了能使用更多的純nodejs
暫時不支持的語法(比如:import
)洞焙,越來越多的nodejs
項目使用babel
來編譯項目蟆淀。在jest
中支持babel
只需要安裝jest-babel
,即運行:yarn add jest-babel
澡匪。
內置豐富的expect
而jest
內置expect
熔任,甚至比chai
[1]更豐富,比如:
- 支持snapshot唁情,這個是
jest
的killing feature
比如我們要寫一個JSON轉XML函數(shù)jsonToXml: string => string
疑苔,而且輸入和輸出都相對長,我們可能會這樣寫測試用例:
it('make sure transform works', () => {
const input = `{
"name": "ron",
"job": "programmer",
"tags": ["javascript", "functional programming"],
}`
const expectedOutput = `
<user><name>ron</><job>programmer<job/><tags><tag>javascript</tag><tag>functional programmer</tags></tags></user>
`
expect(jsonToXml(input)).toEqual(expectedOutput)
})
請問此時你的眼睛花了沒甸鸟?更麻煩的是惦费,當要修改函數(shù)時兵迅,所有的校對又要重新來一遍。
jest
針對這種場景提出了更好的解決方案snapshot
薪贫,上面的用例可以這樣寫:
it('make sure transform works', () => {
const input = `{
"name": "ron",
"job": "programmer",
"tags": ["javascript", "functional programming"],
}`
expect(jsonToXml(input)).toMatchSnapshot()
})
其原理就是恍箭,jest
會把需要expect
的內容(即expected result)自動保存到一個自動生成的文件中,在以后每次運行測試用例時都會比較以前保存的內容瞧省。如果修改了函數(shù)扯夭,則測試用例會fail,但若確定這是by design
鞍匾,則可以運行jest -u
來更新自動保存的文件交洗。
- 更好地對promise的支持,特別是對
reject
的支持
it('fetchData() rejects to be error', () => {
// make sure to add a return statement
return expect(Promise.reject('octopus')).rejects.toBeDefined();
});
test('fetchData() rejects to be error', async () => {
const drinkOctopus = new Promise(() => {
throw new DisgustingFlavorError('yuck, octopus flavor');
});
await expect(drinkOctopus).rejects.toMatch('octopus');
});
- 其它還有比如:
expect.objectContaining
候学、expect.arrayContaining
等
webstorm已經支持jest
之前藕筋,我沒有轉jest
的一個很重要的原因是webstorm
不支持,不過在2017.1的版本中已經支持jest
了梳码。
jest還在頻繁地更新中
mocha
似乎已經處于維護階段隐圾,而jest
還在高頻地開發(fā)中,一定會迭代出更多的新功能掰茶。
總結
在我遷移的這2個月中暇藏,jest
讓我可以更簡潔地測試,并沒有感覺到用什么mocha
可以做濒蒋,而jest
不能做或者做起來比較困難的盐碱。我想是時候和陪伴了我多年的mocha
說bye bye
了。
-
一個專門的
assert
庫沪伙,mocha
不內置expect
瓮顽,因此一般使用mocha
時會使用chai
?