ハンズオンでJestに入門

ハンズオンでJestに入門

だいぶ時間が経ってしまいましたが、
7月に行われたもりけん塾のJestハンズオン勉強会の課題に取り組んだので、
備忘録です。

課題はこちら

JavaScriptをJestでテストする

今回の勉強会はJavaScriptをJestを使ってテストするという内容でした。
正直今までテストをするという認識がなかったため、
凄く興味深い内容でした。
今までconsole.logで値が出力されるか、渡っているかで確認していました。

Jestとは

Jest はあらゆる JavaScript のコードベースの正しさを保証するために設計された JavaScript テスティングフレームワークです。親しみやすく、豊富な機能を持つAPIによって簡単にテストを書くことができ、さらには素早く結果を得ることができます。

Jest公式

JavaScriptを簡単にテストできるフレームワークで、Facebook社が開発し続けているツールのようです。
実際に課題に取り組んで、凄くシンプルなコードでテストすることができました。
公式のドキュメントも揃っているので、入りやすかったです。

jestjs.io

Jestを導入

今回は先生に用意していただいたベースを元に取り組みます。

Node.jsがインストールされているかを確認

node -v でバージョン情報が出てくるかを確認します。
v14.17.5とバージョン情報が出たので入っていることを確認できました。

Jestをインストール

早速プロジェクトフォルダにJestをインストールします。
今回ベースを利用しているので、簡易的に入れています。

npm installでPackage Manegerを入れいていきます。
Jestを簡単に実行できるようにpackage.jsonに下記を追加します。

{
  "scripts": {
    "test": "jest"
  }
}

これでnpm testでJestを実行できるようになります。

テストコードを書く

早速課題に取り組みます。
まずはテストをしたいコードをindex.jsに書いていきます。
ここで注意点があり、テストコードを書くファイルは別ファイルとなるため、
呼び出せるようにモジュールとして書く必要があります。
今回はexport/importで書いています。

export function add(a, b) {
  return a + b;
}

importでテストしたい関数を呼び出します。
テストの書き方は

test('テストの説明', () => {
 //テスト内容を書く
  expect(function()).toBe(result);
});

Jestのテストコードは凄くシンプルで、
テストの説明を書いて、あとはJestで用意されているexpect関数内にMatcher(マッチャー)を利用したテストを書いていきます。
公式には”expectation”(期待する)とあるので、Matcherを使って結果(値)が特定の条件時に合致するかをテストするという感じに書いていきます。

今回のadd関数は引数a + bの結果を返す関数なので、
aとbに値が入ったときの結果を書いてテストしていきます。

引数が数値の1と2だった場合、数値の3になることをテストしました。
toBeのMatcherを利用してテストしています。

このコードのテストをindex.test.jsに書いていきます。

import { add } from "./index";

test('adds 1 + 2 to equal 3', () => {
  expect(add(1, 2)).toBe(3);
});

テストコードが書けたらnpm testでJestを実行します。

PASSとテストが通過した(合格した)と表示されました。
PASSの下にはどのテストを実行したのかがわかるように、
先程書いたテストコードのテストの説明の部分が表示されます。

テストの説明は誰が見てもわかるような内容を書いた方が、今後複数のテストを同時に行った時に、
どんなテストが実行されPASSしたがか分かります。
実際に課題を進めていて、テストを7つ同時に実行した時に、どれがどのtest?となってしまったので、
テストの説明はわかりやすく書くことの必要性を感じました。

Matcher (マッチャー)

MatcherはJestで用意されている特別なメソッドになります。
たくさん用意されているので、公式のドキュメントを元に、望む結果になるようなMatcherを選択してテストコードを書いていきます。

今回の課題で利用し、違いを理解する必要があったMatcherです。

.toMatch  文字列に対して正規表現でマッチするか確認
.toBe厳密な等価性でマッチするか確認
ex)’1′ === 1 /false → number === string
.toEqual オブジェクト、配列を再起的に呼び出し、厳密な等価性でプロパティがマッチするか確認

1つのテスト項目を複数

さっきのコードだけだと1つの結果に対してしかテストすることができません。
実際は引数には色々な値が入る可能性があるので、
1つの関数に複数のテストを行いたい時があります。

課題1がこれに当たりました。

export function addString(a, b) {
  if(typeof a === "string" || typeof b === "string"){
    return a + b;
  } else {
    return -1
  }
}

aとbが”a”、”b”の時”ab”となる
aが”a”, bが1の時”a1″が返る
aが1、bが1の時-1が返る

もりけん塾 Jest hands-on課題1より

aとbの引数数値の時、文字列の時と渡ってくる値の型が違う場合やifがfalseの時もテストしたい時があります。
その場合はdescribe(name, fn) を使ってまとめてテストコードを書くことができるようです。

describe('addString', () => {
	describe('If the strings a and b are passed as arguments', () => {
		test('add a + b to match ab', () => {
			expect(addString('a', 'b')).toMatch('ab');
		});
	});

	describe('If the string a and the number 1 are passed as arguments', () => {
		test('add a + 1 to match a1', () => {
			expect(addString('a', 1)).toMatch('a1');
		});
	});

	describe('If the number 1 is passed as two arguments', () => {
		test('add 1 + 1 return -1', () => {
			expect(addString(1, 1)).toBe(-1);
		});
	});
});

describe(name, fn) 関数はnameをテストと同じようにわかりやすいテスト名を、fnにはテストコードを書きます。今回は1つの関数を複数テストをするので、nameは関数名をいれ、詳細なテスト内容をtestないで書くことにしました。
describe()はネストして書くこともできるので、
テストに構造化を持たせつことができるようです。

ネストについてはもりけん塾の森田先生のFBで教えていただきました。
FBを元に調べると公式にもネストして書けることが書いてありました。
describe(name, fn) Jest公式

この形をベースに、Jestで用意されているMatcherメソッドを用いて、
様々なテストが書けるようです。

まとめ

今回の勉強会ではJavaScriptのコードをテストすることについて学びました。
テストをすること自体今まで意識したことがなかったので、
とても新鮮な勉強会でした。

公式を見ていると非同期処理のテストも書けるようなので、
今チャレンジしている課題にもJestを取り入れられるように、
学習して行けたらと思います。

また大きな学びだったのが、
渡ってくる値が複数想定される場合は、
関数を細かく分けておく必要があることに気づけたことです。

今回の課題はとてもシンプルな関数だったので、
テストコードもシンプルなものでしたが、
関数が複雑になればテストも複雑になるなとコードを書きながら実感できました。

関数は適切なサイズで仕事をさせることを意識して、
コードを書いていくように心がけようと思います。
そうすることで、コードの読み手にも、自分にも、テストコード書くことにも、
平和になる気がします。

現在もりけん塾に参加し、JavaScriptの課題に取り組んでいます!
素敵な先生と塾生に囲まれて切磋琢磨な日々を送っています。

森田先生のBLOG:無骨日記
Twetter:@terrace_tech

毎日7時に「おはようございます」の記事で投稿しています。ブロガーです。 先輩芸人の運転手していた29歳の頃、芸人の中でも何か一芸を身に付けたいと思い、初海外単身…
kenjimorita.jp