owned this note
owned this note
Published
Linked with GitHub
# Jest
- [Jest 是什麼?](https://hackmd.io/dsF4WVq1RUCZjVSCmeG9PA?view#Jest-%E6%98%AF%E4%BB%80%E9%BA%BC%EF%BC%9F)
- [初始設定](https://hackmd.io/dsF4WVq1RUCZjVSCmeG9PA?view#%E5%88%9D%E5%A7%8B%E8%A8%AD%E5%AE%9A)
- [取得測試檔案](https://hackmd.io/dsF4WVq1RUCZjVSCmeG9PA?both#%E5%88%9D%E5%A7%8B%E8%A8%AD%E5%AE%9A)
- [Jest 起手式](https://hackmd.io/dsF4WVq1RUCZjVSCmeG9PA?view#Jest-%E8%B5%B7%E6%89%8B%E5%BC%8F)
- [Matcher 匹配器](https://hackmd.io/dsF4WVq1RUCZjVSCmeG9PA?view#Matcher-%E5%8C%B9%E9%85%8D%E5%99%A8%EF%BC%9A)
- [查看測試涵蓋率](https://hackmd.io/dsF4WVq1RUCZjVSCmeG9PA?view#%E6%9F%A5%E7%9C%8B%E6%B8%AC%E8%A9%A6%E6%B6%B5%E8%93%8B%E7%8E%87")
---
#### Jest 是什麼?
Jest 是一個 JavaScript 的測試框架,支持多種框架專案,例如:Babel, TypeScript, React, Vue ... 等。
Jest 可以確保我們的測試擁有獨立的環境,且不需要任何額外的設置,它提供**測試涵蓋率**指標讓我們查看當前的專案所有的測試資訊。
當使用 `create-react-app`, `@vue-cli` 建立 React 或 Vue 專案時,都會幫忙配置好 Jest 設定方便我們後續執行測試的環境。
簡單介紹完 Jest 之後,接下來讓我們了解 Jest 的使用方法與概念吧!
---
#### 初始設定
執行測試之前,先確認有無 Jest 的測試環境:
- 如果是使用 `create-react-app`, `@vue-cli` 的專案,在建立環境時就已經自動幫忙載入 jest ,可以於 **`package.json`** 檔案查找到 jest 套件。
若是發現開發中的專案還沒有安裝 Jest 套件,那麼我們可以執行以下步驟,讓自己的專案也擁有 Jest 套件來執行測試吧!
- 使用 npm 下載 Jest 套件:
```
npm i jest --save-dev
```
- 安裝完 Jest 之後,可於 `package.json` 進行調整設定:
```
"scripts": {
"test": "jest"
},
```
如果是使用 `create-react-app` 建立的專案,可以看到 `package.json` 有初始設定:
```
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "node scripts/test.js"
},
```
---
#### 取得測試檔案
安裝好 Jest 套件之後,接下來就可以使用 Jest 來進行測試啦!
通常會有兩個檔案,一是我們真正開發的檔案,另一為測試整個情境的檔案。
```
|- HelloTest.js // 開發檔案
|- HelloTest.test.js // 測試檔案
```
首先,我們需要讓 Jest 取得到測試檔案:
- 建立 `檔案名稱 + .test.js` 檔案,Jest 可替我們**找到 `.test.js` 結尾的檔案**並運行測試
- 可用同一個資料夾一起管理,或是在每個要測試檔案的層級加上 `.test.js`
- 注意:被測試的檔案需要 export 才能被測試檔案接收並測試唷!
---
#### Jest 起手式
- 基本寫法:
Jest 撰寫測試時,會使用到全域的 `test` 方法,該方法可帶三個參數:
1. 針對測試的描述
2. 測試函式
3. timeout (可依需求新增)
```jsx
test('針對測試的描述', () => {
// 測試函式
},0);
```
測試流程會需要知道我們的**測試目標**是什麼?在導入要測試的函式來模擬運行的過程,最後**驗證**對測試的期望值。
而在針對測試一個情境時,過程可能會出現許多不同的狀況,因此我們需要**驗證我們的執行目標是否符合預期**。
在 Jest 中常用 **`expect(value)`** 方法針對不同預期的結果執行測試行為,並搭配 Jest 提供的 **matcher 匹配器**,來「斷言」某值。
--
先來個簡單的小範例:
假設有個函式 `workingHour()` 回傳工時與天數相乘的算式。
```jsx
// HelloTest.js
const workingHour = (hours, days) => {
return hours * days
}
export defult workingHour;
```
測試可以怎麼寫呢?先觀察我們整個流程與目標、期望。
1. 測試目標 --> 用文字描述我們要做什麼
2. 導入函式 --> 整個函式如何進行的
3. 測試期望 --> 根據期望搭配任何方法進行驗證
因此我們的測試可以這麼撰寫:
```jsx
// 先引入我們要使用的函式
import workingHour from '../workingHour';
// 描述我們想做什麼事,並導入函式,預期斷言值
test('calculate workingHour', () => {
expect(workingHour(8, 20)).toBe(160);
});
```
如此一來就完成了一個簡單的小測試啦!
---
#### Matcher 匹配器:
以下將介紹幾種常見的匹配器。
- **常用匹配器**:
- `toBe` :可以比對**數字**、**字串**等。
```jsx
test('adds 1 + 1 to equal 2', () => {
expect(1 + 1).toBe(2);
});
```
- `toEqual`:比對**陣列**、**物件**內的每個值。
```jsx
test("Object comparison", () => {
const data = {
apple: 1,
banana: 2,
};
data.orange = 2;
expect(data).toEqual({
apple: 1,
banana: 2,
orange: 2
});
});
```
- **各種型別匹配器**:
- `toBeTruthy`, `toBeFalsy` :比對**真假值**,`expect`
斷言是否為真。
```jsx
// 以 null 來做舉例,因為 null 是 falsy 所以斷言會通過
test("is truthy or falsy", () => {
const testNull = null;
expect(testNull).toBeFalsy();
});
```
```jsx
// 也可以透過加 not 匹配器來比對
test("is truthy or falsy", () => {
const testNull = null;
expect(testNull).not.toBeTruthy();
});
```
- `toBeNull` :判斷是否為 **null**
- `toBeUndefined` :是否為 **undefined**
- 補充: 以下為 Falsy
```jsx
false
0
-0
"", '', `` 空字串
[null](https://developer.mozilla.org/zh-CN/docs/Glossary/Null)
[undefined](https://developer.mozilla.org/zh-CN/docs/Glossary/undefined)
[NaN](https://developer.mozilla.org/zh-CN/docs/Glossary/NaN)
```
- `toMatch`: 匹配**正則表達式**的字串
```jsx
test('there is no I in team', () => {
expect('team').not.toMatch(/I/);
});
test('but there is a "stop" in Christoph', () => {
expect('Christoph').toMatch(/stop/);
});
```
- `describe(name, fn)` → `describe` 為**塊級作用域,內層可以撰寫多個相似的 test。**
```jsx
// 針對測試同邏輯的 test,可在最外層包 describe
describe('is truthy or falsy', () => {
test('null', () => {
const testNull = null;
expect(testNull).toBeFalsy();
expect(testNull).not.toBeTruthy();
});
test('undefined', () => {
const testUndefined = undefined;
expect(testUndefined).toBeFalsy();
expect(testUndefined).not.toBeTruthy();
});
});
```
Jest 官方文件還有提供更多的方法可以幫助我們進行想要的測試驗證,不妨點選以下連結,多參考其他方式動手玩測試吧!
[Jest / Expect](https://jestjs.io/docs/expect)
---
#### 查看測試涵蓋率
以下簡單講解如何查看測試涵蓋率:
先前安裝 Jest 套件時,有 `package.json` 進行調整設定:
```
"scripts": {
"test": "jest"
},
```
如此一來我們可以在本地端執行 `npm run test`,之後會跑出一個 **coverage** 資料夾,裡面有 lcov-report 打開 index.html,就可以看到目前的測試涵蓋率囉!
