使用Jest測試JavaScript (入門篇)

1 什麼是 Jest?

Jest是 Facebook 的一套開源的 JavaScript 測試框架, 它自動集成了斷言、JSDom、覆蓋率報告等開發者所須要的全部測試工具,是一款幾乎零配置的測試框架。而且它對一樣是 Facebook 的開源前端框架 React 的測試十分友好。前端

2 安裝Jest

2.1 初始化package.json

shell中輸入如下命令,初始化前端項目並生成package.jsonios

npm init -y

2.2 安裝Jest及相關依賴

shell中輸入如下命令,安裝測試所須要的依賴:正則表達式

npm install -D jest babel-jest babel-core babel-preset-env regenerator-runtime

babel-jestbabel-coreregenerator-runtimebabel-preset-env這幾個依賴是爲了讓咱們能夠使用ES6的語法特性進行單元測試,ES6提供的 import 來導入模塊的方式,Jest自己是不支持的。shell

2.3 添加.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 &lt; 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,爲什麼不使用asyncawait的語法來精簡咱們的異步測試代碼呢? 可是別忘記都須要調用expect.assertions方法

參考資料

【1】 Jest官方文檔(https://jestjs.io/zh-Hans/)
【2】 Jest Crash Course - Unit Testing in JavaScript(https://www.youtube.com/watch...

來源:http://www.javashuo.com/article/p-erwjgruk-hu.html

<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 &lt; 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
相關文章
相關標籤/搜索