最低限使えるJestの使い方
JavaScriptのテストフレームワーク、Jestの「これさえ覚えておけば、とりあえず最低限の使いかたができる」という使いかたです。
とりあえずセットアップする
テストしたいJavaScriptプロジェクトのルートフォルダで、以下のコマンドを実行します。
npm install --save-dev jest
npmが入ってないかたはWindowsの場合はwinget install OpenJS.NodeJS
でインストールしておいてください。
さっそく使う
ルートフォルダ配下にある*.test.js
というファイルを対象にテストを行ってくれます。Visual Studio Codeの場合、vscode-jestという拡張を入れれば。関数の定義の左からボタン
で実行したり、テストエクスプローラー上から直接実行することもできます。
そのまえに今回テスト対象となるソースコード
あらかじめこのようなファイルがmain.jsという名前でルートフォルダに配置されているものとします。
function sum(a,b) {
return a+b;
}
async function throwError(){
throw new Error("test");
}
module.exports = {
sum,
throwError
}
とりあえずテストする
テストコードはtest()
という関数で定義します。第一引数はテストの名称、第二引数に実行コードを書きます。
const main = require("./main");
test("sum()関数に二つの整数を指定した場合、その値を合算した値を返却することを確認する", () => {
expect(main.sum(2, 3)).toBe(5); // main.sum()の実行結果が5であればテスト成功
});
なお、ここでrequire
を使う際の参照パスは、テストファイルからの相対パスとなります。例えばよくあるように、srcフォルダにソースファイル、testフォルダにテストファイルが入っている場合。../
で上のフォルダを参照する必要があります。
例外が発生することをテストする
例会が発生したことを確認するためのテストとしてtoThrow()
がありますが、これがまたちょっと厄介。
非同期実行の関数と同期実行の関数で呼び出し方が変わります。とりあえず非同期実行の場合のみ。
test("throwError()関数を実行すると例外か発生することを確認する。", () => {
expect(main.throwError()).rejects.toThrow(); // 例外が発生したらテスト成功
});
なお、ここではawait文を使ってはいけません。なので・・・
test("throwError()関数を実行すると例外か発生することを確認する。", async() => {
// --------------------------------------------------------------^ いらない
expect(await main.throwError()).rejects.toThrow();
// ----^ いらない
});
こういう風に書くと、構文エラーが出ないので一見動くように見えますが、実際には確実にテストが失敗します。
タイムアウトを指定する
Jestのテストはデフォルト5000ミリ秒でタイムアウトするようになっています。タイムアウトの時間を過ぎるとどのような状態であっても、テスト失敗とみなされます。
それ以上に時間がかかる処理をテストする場合は、テスト関数の第三引数に時間を設定します。
test("長い時間がかかるテスト", () => {
// ながーーい処理
}, 8000);
この場合、タイムアウトは5000ミリ秒から8000ミリ秒になります。
全てのテストを実行する
.\node_modules\.bin\jest
を実行します。package.json
を編集してnpm run jest
などとして実行できるようにしておくと良さそう。
その他、Visual Studio Codeであれば。vscode-jestの機能を使ってテストエクスプローラーから実行することもできます。
実行時の注意
実行時の注意として、中でサーバーなどを立ち上げた場合、ちゃんと終了させる必要があります。
終了していない場合、テストがいつまでたっても終了しない扱いになるのか、再度テストを実行することができません。
test("サーバへの通信確認", async() => {
const express = require('express');
const aport = await require("aport")();
const app = express();
const server = app.listen(aport);
app.put("/testmethod", (req, res) => {
if(req.method == "PUT"){
res.status(200);
res.end();
}else{
res.status(403);
res.end();
}
});
try {
/* HTTPサーバにアクセスする処理 */
} catch (error){
new Error(error);
} finally{
server.close(); // 必須
}
}
上記必須の行がないと、次のテストが実行できません。
この他にもいくつかのリソースは、しっかり閉じないと次のテストが行えない場合がありますので、次のテストが動かせないというときは、閉じ忘れたリソースがないかどうか確認をしてみてください。
Discussion