Jest是 Facebook 的一套開源的 JavaScript 測試框架, 它自動集成了斷言、JSDom、覆蓋率報告等開發者所須要的全部測試工具,是一款幾乎零配置的測試框架。而且它對一樣是 Facebook 的開源前端框架 React 的測試十分友好。前端
package.json
在shell
中輸入如下命令,初始化前端項目並生成package.json
:ios
npm init -y
在shell
中輸入如下命令,安裝測試所須要的依賴:正則表達式
npm install -D jest babel-jest babel-core babel-preset-env regenerator-runtime
babel-jest
、 babel-core
、 regenerator-runtime
、babel-preset-env
這幾個依賴是爲了讓咱們能夠使用ES6的語法特性進行單元測試,ES6提供的 import
來導入模塊的方式,Jest自己是不支持的。shell
.babelrc
文件在項目的根目錄下添加.babelrc
文件,並在文件複製以下內容:npm
json
{
"presets": ["env"]
}<h4><strong>2.4 修改<code>package.json</code>中的<code>test</code>腳本</strong></h4> <p>打開<code>package.json</code>文件,將<code>script</code>下的<code>test</code>的值修改成<code>jest</code>:</p>
"scripts": {
"test": "jest"
}axios<h3><strong>3. 編寫你的第一個Jest測試</strong></h3> <p><strong>建立<code>src</code>和<code>test</code>目錄及相關文件</strong></p> <ul> <li>在項目根目錄下建立<code>src</code>目錄,並在<code>src</code>目錄下添加<code>functions.js</code>文件</li> <li>在項目根目錄下建立<code>test</code>目錄,並在<code>test</code>目錄下建立<code>functions.test.js</code>文件</li> </ul> <p>Jest會自動找到項目中全部使用<code>.spec.js</code>或<code>.test.js</code>文件命名的測試文件並執行,一般咱們在編寫測試文件時遵循的命名規範:<strong>測試文件的文件名 = 被測試模塊名 + <code>.test.js</code></strong>,例如被測試模塊爲<code>functions.js</code>,那麼對應的測試文件命名爲<code>functions.test.js</code>。</p> <p><strong>在<code>src/functions.js</code>中建立被測試的模塊</strong></p>
export default {
sum(a, b) {
return a + b;
}
}segmentfault<p><strong>在<code>test/functions.test.js</code>文件中建立測試用例</strong></p>
import functions from '../src/functions';數組
test('sum(2 + 2) 等於 4', () => {
expect(functions.sum(2, 2)).toBe(4);
})前端框架<p><strong>運行<code>npm run test</code>, Jest會在<code>shell</code>中打印出如下消息:</strong></p>
PASS test/functions.test.js
√ sum(2 + 2) 等於 4 (7ms)Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 4.8s<h3><strong>4.經常使用的幾個Jest斷言</strong></h3> <p>上面測試用例中的<code>expect(functions.sum(2, 2)).toBe(4)</code>爲一句斷言,Jest爲咱們提供了<code>expect</code>函數用來包裝被測試的方法並返回一個對象,該對象中包含一系列的匹配器來讓咱們更方便的進行斷言,上面的<code>toBe</code>函數即爲一個匹配器。咱們來介紹幾種經常使用的Jest斷言,其中會涉及多個匹配器。</p> <p><strong><code>.not</code></strong></p>
//functions.test.js
import functions from '../src/functions'test('sum(2, 2) 不等於 5', () => {
expect(functions.sum(2, 2)).not.toBe(5);
})<p><code>.not</code>修飾符容許你測試結果不等於某個值的狀況,這和英語的語法幾乎徹底同樣,很好理解。</p> <p><strong><code>.toEqual()</code></strong></p>
// functions.js
export default {
getAuthor() {
return {
name: 'LITANGHUI',
age: 24,
}
}
}
// functions.test.js
import functions from '../src/functions';test('getAuthor()返回的對象深度相等', () => {
expect(functions.getAuthor()).toEqual(functions.getAuthor());
})test('getAuthor()返回的對象內存地址不一樣', () => {
expect(functions.getAuthor()).not.toBe(functions.getAuthor());
})<p><code>.toEqual</code>匹配器會遞歸的檢查對象全部屬性和屬性值是否相等,因此若是要進行應用類型的比較時,請使用<code>.toEqual</code>匹配器而不是<code>.toBe</code>。</p> <p><strong><code>.toHaveLength</code></strong></p>
// functions.js
export default {
getIntArray(num) {
if (!Number.isInteger(num)) {
throw Error('"getIntArray"只接受整數類型的參數');
}let result = []; for (let i = 0, len = num; i < len; i++) { result.push(i); } return result;
}
}
// functions.test.js
import functions from '../src/functions';test('getIntArray(3)返回的數組長度應該爲3', () => {
expect(functions.getIntArray(3)).toHaveLength(3);
})<p><code>.toHaveLength</code>能夠很方便的用來測試字符串和數組類型的長度是否知足預期。</p> <p><strong><code>.toThrow</code></strong></p>
// functions.test.js
import functions from '../src/functions';test('getIntArray(3.3)應該拋出錯誤', () => {
function getIntArrayWrapFn() {
functions.getIntArray(3.3);
}
expect(getIntArrayWrapFn).toThrow('"getIntArray"只接受整數類型的參數');
})<p><code>.toThorw</code>可可以讓咱們測試被測試方法是否按照預期拋出異常,可是在使用時須要注意的是:<strong>咱們必須使用一個函數將將被測試的函數作一個包裝</strong>,正如上面<code>getIntArrayWrapFn</code>所作的那樣,不然會由於函數拋出致使該斷言失敗。</p> <p><strong><code>.toMatch</code></strong></p>
// functions.test.js
import functions from '../src/functions';test('getAuthor().name應該包含"li"這個姓氏', () => {
expect(functions.getAuthor().name).toMatch(/li/i);
})<p><code>.toMatch</code>傳入一個正則表達式,它容許咱們用來進行字符串類型的正則匹配。</p> <h3><strong>5 測試異步函數</strong></h3> <p><strong>安裝<code>axios</code></strong><br>這裏咱們使用最經常使用的http請求庫<code>axios</code>來進行請求處理</p>
npm install axios
<p><strong>編寫http請求函數</strong><br>咱們將請求<code>http://jsonplaceholder.typicode.com/users/1</code>,這是由<strong>JSONPlaceholder</strong>提供的mock請求地址</p>
// functions.js
import axios from 'axios';export default {
fetchUser() {
return axios.get('http://jsonplaceholder.typicode.com/users/1')
.then(res => res.data)
.catch(error => console.log(error));
}
}
// functions.test.js
import functions from '../src/functions';test('fetchUser() 能夠請求到一個含有name屬性值爲Leanne Graham的對象', () => {
expect.assertions(1);
return functions.fetchUser()
.then(data => {
expect(data.name).toBe('Leanne Graham');
});
})<p>上面咱們調用了<code>expect.assertions(1)</code>,它能確保在異步的測試用例中,有一個斷言會在回調函數中被執行。這在進行異步代碼的測試中十分有效。</p> <p><strong>使用<code>async</code>和<code>await</code>精簡異步代碼</strong></p>
test('fetchUser() 能夠請求到一個用戶名字爲Leanne Graham', async () => {
expect.assertions(1);
const data = await functions.fetchUser();
expect(data.name).toBe('Leanne Graham')
})
```固然咱們既然安裝了
Babel
,爲什麼不使用async
和await
的語法來精簡咱們的異步測試代碼呢? 可是別忘記都須要調用expect.assertions
方法參考資料
【1】 Jest官方文檔(https://jestjs.io/zh-Hans/)
<h4><strong>2.4 修改<code>package.json</code>中的<code>test</code>腳本</strong></h4> <p>打開<code>package.json</code>文件,將<code>script</code>下的<code>test</code>的值修改成<code>jest</code>:</p><h3><strong>3. 編寫你的第一個Jest測試</strong></h3> <p><strong>建立<code>src</code>和<code>test</code>目錄及相關文件</strong></p> <ul> <li>在項目根目錄下建立<code>src</code>目錄,並在<code>src</code>目錄下添加<code>functions.js</code>文件</li> <li>在項目根目錄下建立<code>test</code>目錄,並在<code>test</code>目錄下建立<code>functions.test.js</code>文件</li> </ul> <p>Jest會自動找到項目中全部使用<code>.spec.js</code>或<code>.test.js</code>文件命名的測試文件並執行,一般咱們在編寫測試文件時遵循的命名規範:<strong>測試文件的文件名 = 被測試模塊名 + <code>.test.js</code></strong>,例如被測試模塊爲<code>functions.js</code>,那麼對應的測試文件命名爲<code>functions.test.js</code>。</p> <p><strong>在<code>src/functions.js</code>中建立被測試的模塊</strong></p><p><strong>在<code>test/functions.test.js</code>文件中建立測試用例</strong></p><p><strong>運行<code>npm run test</code>, Jest會在<code>shell</code>中打印出如下消息:</strong></p><h3><strong>4.經常使用的幾個Jest斷言</strong></h3> <p>上面測試用例中的<code>expect(functions.sum(2, 2)).toBe(4)</code>爲一句斷言,Jest爲咱們提供了<code>expect</code>函數用來包裝被測試的方法並返回一個對象,該對象中包含一系列的匹配器來讓咱們更方便的進行斷言,上面的<code>toBe</code>函數即爲一個匹配器。咱們來介紹幾種經常使用的Jest斷言,其中會涉及多個匹配器。</p> <p><strong><code>.not</code></strong></p><p><code>.not</code>修飾符容許你測試結果不等於某個值的狀況,這和英語的語法幾乎徹底同樣,很好理解。</p> <p><strong><code>.toEqual()</code></strong></p><p><code>.toEqual</code>匹配器會遞歸的檢查對象全部屬性和屬性值是否相等,因此若是要進行應用類型的比較時,請使用<code>.toEqual</code>匹配器而不是<code>.toBe</code>。</p> <p><strong><code>.toHaveLength</code></strong></p>let result = []; for (let i = 0, len = num; i < len; i++) { result.push(i); } return result;<p><code>.toHaveLength</code>能夠很方便的用來測試字符串和數組類型的長度是否知足預期。</p> <p><strong><code>.toThrow</code></strong></p><p><code>.toThorw</code>可可以讓咱們測試被測試方法是否按照預期拋出異常,可是在使用時須要注意的是:<strong>咱們必須使用一個函數將將被測試的函數作一個包裝</strong>,正如上面<code>getIntArrayWrapFn</code>所作的那樣,不然會由於函數拋出致使該斷言失敗。</p> <p><strong><code>.toMatch</code></strong></p><p><code>.toMatch</code>傳入一個正則表達式,它容許咱們用來進行字符串類型的正則匹配。</p> <h3><strong>5 測試異步函數</strong></h3> <p><strong>安裝<code>axios</code></strong><br>這裏咱們使用最經常使用的http請求庫<code>axios</code>來進行請求處理</p><p><strong>編寫http請求函數</strong><br>咱們將請求<code>http://jsonplaceholder.typicode.com/users/1</code>,這是由<strong>JSONPlaceholder</strong>提供的mock請求地址</p><p>上面咱們調用了<code>expect.assertions(1)</code>,它能確保在異步的測試用例中,有一個斷言會在回調函數中被執行。這在進行異步代碼的測試中十分有效。</p> <p><strong>使用<code>async</code>和<code>await</code>精簡異步代碼</strong></p>Babelasyncawaitexpect.assertions
【2】 Jest Crash Course - Unit Testing in JavaScript(https://www.youtube.com/watch...