先日の記事「JavaScriptとネイティブの連携にPromiseを使用した事例の紹介」でも触れましたが、Movable Type / PowerCMSで運用中のウェブサイトを10分でアプリ化する「Apliko(アプリコ)」の新テーマ開発を行いました。(ちなみに昨日リリースいたしました。)
開発の中でJavaScript(HTMLで作成した画面)からネイティブの機能を呼ぶ必要があり独自のJavaScriptライブラリを開発したこともご紹介いたしましたが、このライブラリが正しく動作しているのか?を検証する必要がありました。例えばある値をネイティブ側に渡すとアプリ内に正しく保存されるか否かです。
検証をするにあたり最初はフォームを作成してWebViewで表示し手で入力しようかと考えたのですが、フォームを作るのも、都度値をキーボードで入力するのも手間がかかるものです。ここでテスティングフレームワークを利用しテストを自動化することを思いつきました。
Jasmineを使ってテストを記述
最近のテスティングフレームワーク事情を見ると「Jest」が流行っているようですが、以前学習したことがあり、かつブラウザに表示させてすぐにテストが実行できる「Jasmine」を選択しました。「正確かつ効率的にテストを行うこと」が目的でしたので、この選択は間違っていないと考えています。
さて、ある値をネイティブ側に渡すとアプリ内に正しく保存されるか否かですが、次のようなコードでテストができます。値が正しく取り出せるかも一緒にテストをすると都合が良いのでまとめて書きました。
describe("apliko.storage", function () {
it("値の保存と取得ができること", function (done) {
const key = "storagetest";
const value = "123456789";
const promise = apliko.storage.set(key, value); // 値を保存
promise
.then(
function () {
// 値の保存に成功した場合...値を取り出してみる
return apliko.storage.get(key);
},
function () {
fail("値の保存に失敗しました。");
done();
}
)
.then(
function (data) {
// 値の取り出しに成功した場合...受け取った値が保存した値と等しいかチェック
expect(data).toBe(value);
done();
},
function () {
fail("値の取得に失敗しました。");
done();
}
);
});
});
このコード含むHTMLをWebViewで表示すると、実装が正しければテストが成功します。実際にテストを実行した画面は以下の通りで成功です。
上記のコード例ではvalue = "123456789"
のように「123456789
」をネイティブに保存しているのですが、expect(data).toBe("foobarbaz");
のように「foobarbaz
」を返値として期待すると当然テストは失敗します。
25項目をテスト
WebViewでもテストが意図したとおり実行できたので、「encroute.jsのAPI解説」で自動テストが可能な項目はすべてテストを書きました。最終的には25項目をテストしました。
リファクタリングでも役立つ
手探りで制作を進めていたためencroute.jsのAPIに関する処理をViewControllerに500行近くのコードを書いてしまっており、非常にFatなViewControllerになっていました。Swiftの本を改めて読み返した結果、Extensionとして切り出すとコードがすっきりとまとめられることが分かりました。
そこでExtensionとしてコードを切り出しつつ見やすいコードになるよう改善を進めたのですが、FatなViewControllerの頃と同じ動作をするか確認する必要がありました。しかし既にJasmineでテストを書いていたため、テストを再度WebViewで実行するだけで確認ができ、非常に助かりました。
おわりに
今回はプログラムの検証段階になってテストを書きましたが、予めテストを書いて制作を進めるとさらに良かったかなと反省しています。今回の経験を活かし、次の新たなプロジェクトで活かすことができればと考えています。また、Apple公式のUIテスティングフレームワーク「XCTest」についても研究し、アプリの品質向上に役立てることができたらと考えています。