【もりけん塾】Jestハンズオン勉強会
目次
今回の内容はJestについての学習記録です。
7月末にもりけん塾で「Jestハンズオン勉強会」が行われました!
もりけん先生ありがとうございました!
Jest
https://jestjs.io/ja/
導入
公式ドキュメントを見ながら導入を行ってみました。
- Node.jsが入っているか確認
node -vでバージョンがでてくることを確認。
- npm install --save-dev jestでJestをインストール
package.jsonファイルがディレクトリにないです、と言ってる...?
no such file or directory, open '〜'
- npm init -yでプロジェクトフォルダーを作成する
package.jsonが生成されました。
- もう一度npm install --save-dev jestでJestをインストール
無事、node_modulesが生成されました。
- package.jsonに以下を追加する
"scripts": {
"test": "jest"
},
- sum.js / sum.test.jsを作成
公式ドキュメントの例文と同じ様に書きました。
- sum.js
function sum(a, b) {
return a + b;
}
module.exports = sum;
- sum.test.js
const sum = require('./sum');
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
- テストを実行する
npm testで実行。
ターミナルには以下の様にでました↓
PASS ./sum.test.js
✓ adds 1 + 2 to equal 3 (1 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.193 s
Ran all test suites.
無事に導入ができました!
テストの書き方
test(' テストの説明 ', () => {
expect( // 評価したい値 ).toBe();
);
このtoBeの部分がmatcherメソッドといい、値をテストする方法です
関連するいくつかのテストをdescribeメソッドを使用してまとめることもできます
describe(' ', () => {
it('テストの説明', () => {
// /テスト
})
it('テストの説明', () => {
// テスト
})
it('テストの説明', () => {
// テスト
})
})
苦戦した点
- matcherの使い方
matcherそれぞれに特徴があるので
まずはそれらを調べ、実際にテストを行い違いを理解できる様にしました。
toBe
文字列と数値の比較を行いました。
test('toBe Test1' , () => { //PASS
expect('apple').toBe('apple');
});
test('toBe Test2' , () => { //PASS
expect(1).toBe(1);
});
toBeは厳密な等価性をチェックするmatcherなので以下のテストはエラーが出ました
test('toBe Test3' , () => { //FAIL
expect("1").toBe(1);
});
test('toBe Test4' , () => { //FAIL
expect({}).toBe({});
});
toEqual
toEqualも等価性をチェックします
test('toEqual Test1' , () => { //PASS
expect('apple').toEqual('apple');
});
test('toEqual Test2' , () => { //PASS
expect(1).toEqual(1);
});
toBeとの違いは、オブジェクトや配列もチェックできる点です。
//case1
test('toEqual' , () => { //PASS
expect({}).toEqual({});
});
//case2
test('toEqual Test' , () => {
expect(['apple']).toEqual(['apple']); //PASS
});
//case3
const obj1 = { food: 'apple'};
const obj2 = { food: 'apple'};
test('toBe Test' , () => { //FAIL
expect(obj1).toBe(obj2);
});
test('toEqual Test' , () => { //PASS
expect(obj1).toEqual(obj2);
});
https://stackoverflow.com/questions/45195025/what-is-the-difference-between-tobe-and-toequal-in-jest
toContain / toContainEqual
以下の様な関数でテストをしてみます
課題3と同じくfilterを使用し、5以下の数字を配列で返します。
const items = [1,2,3,4,5,6,7,8,9];
function filterNumber(arr) {
return arr.filter((e) => e < 5 );
}
const items = [1,2,3,4,5,6,7,8,9];
test ('toContain Ver', () => { //PASS
expect(filterNumber(items)).toContain(1);
});
test ('toContainEqual Ver', () => { //PASS
expect(filterNumber(items)).toContainEqual(1);
});
どちらもテストが通りました。
どちらも配列内に含まれるアイテムがあるかをテストしてくれました。
違いはなんなのか...以下の内容でテストを行います。
test('toContain Ver', () => //FAIL
expect([{ fruit: 'apple' }, { food: 'curry'}]).toContain({ fruit: 'apple' })
)
test('toContainEqual Ver', () => //PASS
expect([{ fruit: 'apple' }, { food: 'curry'}]).toContainEqual({ fruit: 'apple' })
)
toContainの方はエラーが起こり、toContainEqualの方は無事テストできました。
toContainEqualは配列内に含まれるオブジェクトもテストができるという違いがあることを学びました。
特定の構造と値を持つ要素が配列に含まれていることをチェックしたい場合は
.toContainEqual
を使用して下さい。https://jestjs.io/ja/docs/expect#tocontainequalitem
toThrow
例外が発生したかをチェックします。toThrowの引数にエラーを指定することもできます。
テストケースの書き方
課題のレビューをいただいた際、
テストケースの書き方についてアドバイスを頂きました。
//修正前
test('filterOrange equal orange', () => {
expect(filterOrange(fruit)).toContain('orange');
});
どのようなテストなのかが全然わからないです...適当さが出ている...
もりけん先生からは、
何をして、何をするのかを書いた方がいいと、アドバイスを頂きました。
//修正後
test('If array containing orange is passed, array containing orange return', () => {
expect(filterOrange(fruit)).toContain('orange');
});
アドバイスをもとに修正を行いました。
どのようなテストなのかがわかる様になりました!
誰がみてもどんなテストなのかがわかる様な書き方を心がけます。
まとめ
テストを適切に行う為にも、関数には複数の仕事をさせずに1つの仕事だけさせることが大切だと今回学びました。実際にテストを書いてみて、その意味を理解することができました。
今後も色々なパターンのテストを書いて、より理解を深めていきたいです。
現在、もりけん塾でJavaScriptを中心に学習をしています!
もりけん先生のTwitter:https://twitter.com/terrace_tech
https://kenjimorita.jp/