今天要來簡介一下最廣為使用的測試框架 - Jest。其 官方文件 寫得十分平易近人。
首先,於專案中安裝 jest。npm install --save-dev jest
並在 package.json 配置好 scripts
"scripts": {
"test": "jest",
"testwatch": "jest --watchAll"
},
即可執行測試:
npm run test // 單次測試
npm run testwatch // 時時監控測試的更新
Jest 單元測試中,最常用的 Matchers 提供的語法可以針對數字、物件、陣列、字串等去做測試。例如今天我想測試 2 + 2 = 4。我可以使用 toBe 這樣寫:
test('two plus two is four', () => {
expect(2 + 2).toBe(4);
});
想要測試 2 + 2 是否「不等於」5,則加個 not:
test('two plus two is not equal to five', () => {
expect(2 + 2).not.toBe(5);
});
想測試物件的屬性值是否相等,可使用 toEqual:
test('object assignment', () => {
const data = {dog: 'happy'};
data['cat'] = 'cookies';
expect(data).toEqual({dog: 'happy', cat: 'cookies'});
});
想知道條件是否為 null、undefined、true/false,則可以使用 toBeNull、toBeUndefined、toBeTruthy、toBeFalsy:
test('test n to be true/false?', () => {
const n = (a === 'a');
expect(n).not.toBeTruthy();
expect(n).toBeFalsy();
});
也可以做數字上大於、小於、等於的判斷:
test('4 + 4', () => {
const value = 2 + 2;
expect(value).toBeGreaterThan(7);
expect(value).toBeLessThan(9);
});
測試字串時,可以使用正規表達式搭配 toMatch:
test('testing ABCDEF', () => {
expect('ABCDEF').not.toMatch(/G/);
});
欲測試陣列、字串中是否含有某個值,則可用 toContain:
const animalList = [
'dog',
'cat',
'bird',
];
test('testing animalList', () => {
expect(animalList).not.toContain('turtle');
});
Jest 亦有提供非同步測試的方式,並可習慣性加上 expect.assertions 來確保有執行該非同步的測試:
test('fetched test', async () => {
expect.assertions(1); // 加上 assertions(1) 代表至少要執行一次斷言來驗證結果
const data = await functions.fetchData();
expect(data.animal).toEqual('dog');
})
最後,來介紹 Jest 的生命週期: beforeEach()、afterEach()、beforeAll()、afterAll()。可分別於每筆 test 開始/結束時某些行為;或針對所有 test 的開始/結束時執行某些操作。並可搭配 describe 作為範圍鍊去區隔測試。
describe('testing classmates info data', () => {
beforeEach(() => {
return initialClassmatesInfo();
});
afterEach(() => {
console.log('finished running a test');
});
afterAll(() => {
console.log('finished all tests');
});
test('number 19 is John', async () => {
const data = await fetchData();
expect(testingName(19)).toBe('John');
});
test('number 29 is Female', async () => {
const data = await fetchData();
expect(testingGender(29)).toBe('Female');
});
});