JavaScriptをテストしよう
JavaScriptをテストしよう
本記事について
要約
JavaScriptをテストする方法、特にJasmineというテストフレームワークの使用方法について学びます。また、ビヘイビア駆動型開発(BDD)というテスト設計の方法や、テストを書くことの重要性も解説しています。具体的には、親クラスと子クラスのあるJavaScriptコードのテストスイートを作成する方法を紹介しています。
前提
Trailheadの英語版をChatGPT4(以下、ChatGPT)に投げて返ってきた内容を載せています。もともとはTrailheadのみで学習していたのですが、不自然な日本語や、JavaScript初学者に理解しづらい用語・概念を手っ取り早く調べるとためにChatGPTとやり取りしながらの学習に切り替えました。
ChatGPTに聞くとおおよそ同じような答えが返ってきますが、毎回聞くのも手間ですし、用語なども追加で聞いていることもあるので備忘録を兼ねて残します。
僕と同じようなJavaScript初学者の方に参考になれば幸いです。
対象のTrailhead↓
Test Your JavaScript 単元 | Salesforce Trailhead
学習目標
このユニットを終えると、以下のことができるようになります:
- ビヘイビア駆動型のテストがなぜユニークなのかを説明する。
- Jasmineのテストスクリプトで使用される異なる要素を特定する。
- シンプルなJasmineのテストスイートを作成し、それをスタンドアロンで実行する。
テストするかしないか?
Apexの開発者は、必要なユニットテストの概念にすでに慣れています。しかし現在、JavaScriptをテストすることは完全に任意です。多くの人が「必要がないなら、なぜ面倒を見るのか?」と疑問に思うかもしれません。なにしろ、ほとんどの開発者はテストを書くこと、ドキュメンテーションを書くこと、あるいは熱い石炭の上を歩くことをほとんど同じくらい嫌っています。
だけどここがポイントです:プロジェクトの始めにしっかりとユニットテストを書く時間を取ることは、長い目で見れば間違いなくあなたの時間を節約します。バグを記録し、それを追跡して修正する時間、そしてそのバグが実際に修正されたかをテストする時間を節約します。そしてもちろん、設定しているリリースプロセスを扱う時間も節約します。
良いユニットテストは、バグが世に出る前にそれを潰すのに役立ちます。これが良いことだと言えるでしょうね?
ビヘイビア駆動型開発
ビヘイビア駆動型開発(BDD)は、テスト駆動型開発(TDD)から生まれたプロセスです。BDDはテストをその振る舞いがテストされるように組織化することを含みます。このタイプのテストを設計するときは、「このコードは何をして、それから何を期待するべきかを、文章でどのように説明できるか」と考えてみてください。
そしてビヘイビア駆動型のツールを使ってテストスクリプトを作成します。スクリプトには、テストが何をするべきかを基本的に説明する自然な言語の文章を含めるべきです。また、テストが動作しているかどうかを確認するためのアサーションも含めるべきです。
どのツールを使うべきか?
JavaScriptをテストするためのツールは決して少なくなく、日々そのリストは長くなっています。より人気のあるビヘイビア駆動型ツールの一つはJasmineです。設定も使用も簡単です。
一つのDescribe関数を含むテストJavaScriptファイルのダイアグラムがあり、そのボックスの中にはそれぞれがアサーションボックスを含む2つのさらなるit関数ボックスがあります。
Jasmineではdescribe
関数を使用してテストスイートを作成しますが、実際にはただのJavaScript関数を作成しているだけです。その関数の中で、it
関数を使用して1つ以上のスペック(またはテスト)を指定します。これらもまた単なる関数です。スペック関数の中には、テストがうまく機能したかどうかを確認するためのアサーションを置きます。
これが肯定的なテストと否定的なテストの両方を持つ基本的なテストスイートがどのように見えるかです:
describe("テストスイートはただの関数", function() {
it("これは肯定的なテスト", function() {
expect(true).toBe(true);
});
it("これは否定的なテスト", function() {
expect(false).not.toBe(true);
});
});
Jasmineにはグローバル関数(beforeEach
とafterEach
)が含まれており、これらは各テストスペックが実行される前後にコードを実行するために使用できます。これは特定のユーザーとしてログインしたりログアウトしたりするなど、多くのリソースを必要とするセットアップとティアダウンコードがある場合に便利です。またbeforeAll
とafterAll
という関数もありますが、これらはそれらが一部であるdescribeブロックごとに一度だけ実行されます。
Jasmineテストフレームワークの使用
Jasmineのインストールページでは、いくつかの異なるインストール方法が提供されています。また、GitHubリポジトリから最新版をダウンロードし、libフォルダの内容全体をJavaScriptプロジェクトディレクトリにコピーして解凍することで、スタンドアロンで実行することもできます。
JavaScriptのテストスイートを作成したら、HTMLページから必要なJasmineフレームワークファイルとともにこれを参照して、ブラウザでテストを実行することができます。
どのように動作するかを見るために、クラスの扱いのユニットで見たParent/ChildクラスのコードをテストするJasmineテストスイートを作成したいとしましょう。覚えていない場合のために、Parentクラスのコードは以下のようになります:
class Parent {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
そして、Childクラスのコードは以下のようになります:
class Child extends Parent {
constructor(name) {
super(name);
}
getMessage() {
return 'Hello ' + super.getName();
}
}
Jasmineのlibフォルダをダウンロードして解凍したら、ローカルマシン上に新しいフォルダを作成します。解凍したlibフォルダを、新しく作成したフォルダにコピーします。ここにはテストしたいJavaScriptコードも配置します。今回の場合は、parentとchildのクラスです。
JasmineテストスイートのJavaScriptコードを別のファイルに追加することができます。それは次のようになるかもしれません:
describe("Test Parent Child Classes", function() {
it("Get Message Test", function(){
let someone = new Child('person');
expect(someone.getMessage()).toEqual("Hello person");
});
});
残りの作業は、必要なJasmineファイルとJavaScriptファイルを全てロードするシンプルなindex.htmlファイルを作成することだけです。そのマークアップコードは次のようになるかもしれません:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- ロードするJasmineファイル -->
<link rel="shortcut icon" type="image/png" href="lib/jasmine-3.2.1/jasmine_favicon.png">
<link rel="stylesheet" href="lib/jasmine-3.2.1/jasmine.css">
<script src="lib/jasmine-3.2.1/jasmine
.js"></script>
<script src="lib/jasmine-3.2.1/jasmine-html.js"></script>
<script src="lib/jasmine-3.2.1/boot.js"></script>
<!-- テストするJSファイル -->
<script src="Parent.js"> </script>
<script src="Child.js"> </script>
<!-- Jasmineテストスイート -->
<script src="JasmineTest.js"> </script>
</head>
<body>
<h1> Jasmine Parent Child Testing Demo </h1>
</body>
</html>
Jasmineテストスイートの実行は、ブラウザでindex.htmlファイルをロードするだけで簡単に行えます。これで、自分自身のビヘイビア駆動型JavaScriptテストのセットを設計するための全てが揃いました。