# Jest > 此內容參考自 [Jest | 讓 Jest 為你的 Code 做測試-基礎用法教學](https://medium.com/enjoy-life-enjoy-coding/%E8%AE%93-jest-%E7%82%BA%E4%BD%A0%E7%9A%84-code-%E5%81%9A%E5%96%AE%E5%85%83%E6%B8%AC%E8%A9%A6-%E5%9F%BA%E7%A4%8E%E7%94%A8%E6%B3%95%E6%95%99%E5%AD%B8-d898f11d9a23) 與 [Day17 | 不知道對不對,就把邏輯通通測起來 feat. Jest](https://ithelp.ithome.com.tw/articles/10222357)。 ### Jest 安裝懶人包 1. 開啟命令提示字元,cd 到想要安裝 Jest 的資料夾 2. 輸入 `npm init -y`,在 `node.js` 環境下建立一個 `package.json` 檔案 3. 輸入 `npm install --save-dev jest`,透過 npm 套件管理工具下載 Jest 測試框架到專案的執行環境中 4. 打開 `package.json`,並將 `"scripts"` 中的 key `"test"` 的值改為 `"jest"`: ``` //...略 scripts: { "test": "jest" } //...略 ``` 改好之後,只需在終端機中輸入 `npm run test`,Jest 便會尋找專案中副檔名為 `.test.js` 結尾的檔案進行測試 ### 基本語法範例 ``` js test('two plus two is four', () => { expect(2 + 2).toBe(4); }); ``` + test 函式用來描寫一個單元測試,它擁有兩個參數: + 第一個參數,用來敘述此單元測試的功能或者邏輯 + 第二個參數是一個 function,function 內的 `expect()` 的參數為要測試的值或函式;`toBe()` 為一個 matcher,參數為 `expect()` 測試的期望值。 + 以上面基本語法為例:`'two plus two is four'` 用來描述此測試的功能(二加二等於四);`expect(2 + 2)` 的 2 + 2 為要測試的內容;`toBe(4)`的 4 為 2 + 2 的期望值。 ### 示範 #### 在專案資料夾底下,有一個 `main.js` 檔案,我在裡面寫了一個簡單的加法函式: ``` js //in main.js function add(a, b) { return a + b } ``` #### 我想用 Jest 測試 add 函式,先將它 export 出去: ``` js function add(a, b) { return a + b } module.exports = add ``` #### 在專案資料夾底下建立一個 `main.test.js` 檔案,import add 函式並寫入測試 function: > Jest 運行時會尋找專案中副檔名為 `.test.js` 結尾的檔案進行測試 ``` js const add = require('./main') test('a + b = 5', () => { expect(add(3, 2)).toBe(5); }); test('a + b = 10', () => { expect(add(5, 5)).toBe(10); }); ``` #### 在終端機輸入 `npm run test` 方可進行自動化測試,以下為測試結果: ``` js PASS ./main.test.js √ a + b = 5 (7 ms) √ a + b = 10 (1 ms) Test Suites: 1 passed, 1 total Tests: 2 passed, 2 total Snapshots: 0 total Time: 2.877 s Ran all test suites. ``` #### 若我們將第一個 test 函式中的 `toBe(5)` 改為 `toBe(6)`並重新執行測試: ``` js FAIL ./main.test.js × a + b = 5 (7 ms) √ a + b = 10 ● a + b = 5 expect(received).toBe(expected) // Object.is equality Expected: 6 Received: 5 2 | 3 | test('a + b = 5', () => { > 4 | expect(add(3, 2)).toBe(6); | ^ 5 | }); 6 | 7 | test('a + b = 10', () => { at Object.test (main.test.js:4:23) Test Suites: 1 failed, 1 total Tests: 1 failed, 1 passed, 2 total Snapshots: 0 total Time: 6.758 s ``` 會顯示 fail,並指出測試結果應為 5 而不是 6。 ### 更多常用的 matchers > 此篇內容引用自 [十分鐘上手前端單元測試 - 使用 Jest](https://wcc723.github.io/development/2020/02/02/jest-intro/)。 編寫測試時需要讓值符合期望,Jest 中的 expect 後方可以使用 `matchers`(匹配器)作為條件驗證,如先前的範例 `expect(...).toBe(...)` 中的 `toBe()` 就屬於 matchers,作為各種不同條件的驗證使用。 #### 測試是否為 `null`、`true`、`false`、或者 `undefined`: + `toBeNull`:matches only null + `toBeUndefined`: matches only undefined + `toBeTruthy`:matches anything that an `if` statement treats as true + `toBeFalsy`:matches anything that an `if` statement treats as false #### 物件對比: ``` js const boy = { name: 'Leo' } console.log(boy === {name: 'Leo'}) // false ``` 這邊得到 false 的結果與變數儲存模型有關,詳情可複習 [從 Object 的等號真正的理解變數(變數儲存模型)](https://github.com/TsaiChihWei/learning-blog/issues/4)。 在 Jest 也是相同概念,如若直接使用 `toBe()` 來比對物件一樣會得到 fail 的結果。 若單純想對比物件內的值則可使用 `toEqual()`,範例: ``` js test('object assignment', () => { const data = {one: 1} data['two'] = 2 expect(data).toEqual({one: 1, two: 2}) }) ``` #### 數值比對 ``` js test('two plus two', () => { const value = 2 + 2 expect(value).toBeGreaterThan(3) expect(value).toBeGreaterThanOrEqual(3.5) expect(value).toBeLessThan(5) expect(value).toBeLessThanOrEqual(4.5) // toBe and toEqual are equivalent for numbers expect(value).toBe(4) expect(value).toEqual(4) }); ``` #### `toMactch` 字串包含 使用 `toMatch()` 測試一個字串有無包含特定字串: ``` js test('there is no I in team', () => { expect('team').toMatch('I') }) ``` 測試會 fail,因為字串 `'team'` 沒有包含 大寫 `I`,或也可使用**正規表達式**: ``` js test('but there is a "stop" in Christoph', () => { expect('Christoph').toMatch(/stop/) }) ``` 測試會通過,因為字串 `Christoph` 有包含 `stop`。 #### `toContain` 判斷一個陣列是否含有某值 ``` js // pass the test const arr = ['a', 'b', 'c'] test('if arr includes specific value', () => { expect(arr).toContain('b') }) ``` ### describe `describe` 的用途是提供一個群組的描述,將多個 test 包在一起,讓程式看起來更有結構性 ``` js //...略 describe('test reverse', () => { test('123 reverse should be 321', () => { expect(reverse('123')).toBe('321') }) test('!!! reverse should be !!!', () => { expect(reverse('!!!')).toBe('!!!') }) test('"" reverse should be ""', () => { expect(reverse('')).toBe('') }) }) ``` > [延伸題:如何產生覆蓋率報告?](https://medium.com/enjoy-life-enjoy-coding/%E8%AE%93-jest-%E7%82%BA%E4%BD%A0%E7%9A%84-code-%E5%81%9A%E5%96%AE%E5%85%83%E6%B8%AC%E8%A9%A6-%E5%9F%BA%E7%A4%8E%E7%94%A8%E6%B3%95%E6%95%99%E5%AD%B8-d898f11d9a23)