Chapter 02

なぜテストを書くか、メリットとデメリット

Satoshi Takeda
Satoshi Takeda
2021.02.24に更新

なぜテストを書くか

「なぜ」という問いに対しては開発者が安心して開発するためといった理由が大きいと考えています。

サービスの品質を担保するもの、バグがない保証を示すもの、といった標準化・エビデンスの類ではありません。システムのサービスレベルとして評価、アウトプットの標準化などは受け入れのための試験項目で担保すべき問題でしょう。

誰のため = 自分のため

開発者が書くテストコードは開発において繰り返されるフィードバックサイクルに耐えうるためのものです。また実装から読み取りづらい意図をテストコードがフォローすることもあるでしょう。エッジケースをテストコードで表現しておくことで手離れしたあとも語るべき口が残ります。

そして継続的なテスト実行ができていれば、意図しない変更でミスがあった場合に指摘してくれるので、ゲートキーパーのような役割をすることもあるでしょう。

以上のことを踏まえれば「誰のため」という問いに対しては 「開発者のため」であり「自分のため」である と言えます。明日の自分がアプリケーションを破壊するということがないとも限りません。そのための安全帯です。

どのように、どういった方法で

「どのように」と「どういった方法で」フロントエンドのテストを書くかというのはまさに方針そのものです。

ここで取り上げようとしている、Jest と React Testing Library を選択することによって方針は決定づけられてしまいますが、本来であれば方針を定めてからテストライブラリを選定するのが好ましくはあります。

Web フロントエンドのテストコードについて深い造詣はありませんが、筆者が書き出したころは実行環境を PhantomJS というヘッドレスブラウザを Karma といったテストランナーで起動し Mocha というテストフレームワークを動作さていました。もしくは Mocha 自体をブラウザで実行するといった場合もあります。

背景にはいわゆるクライアント MVC と呼ばれるフレームワークによってレイヤ化されたモジュールが主流だったため、あまり意識することはありませんでしたが、テストの方針らしきものと言えばモジュールの入出力や処理プロセスを意識するようなバックエンドのユニットテストに近い方針だったように記憶しています。

今回の方針

この本で取り上げる React Testing Library を含んだ、testing-library family には方針を決定づけるような共通した思想があります。下記はドキュメントのガイド・原則に書いているものです。

The more your tests resemble the way your software is used,
the more confidence they can give you.

意訳すれば 「テストがソフトウェアの利用方法に似ているほど信頼性が得られる」 といったところでしょうか。テストライブラリ自身が強制するほど強い主張があるわけではありませんが、避けるべきことといったセクションには 「実装の詳細をテストしないようにすることを勧めます(ただし実施してもかまいません)」 と記載があります。今回扱うこのテストライブラリはソフトウェアが利用されるのと同じようなテストを書くことに向いていそうです。

ですので、今回意識したいテストの種類は、コンポーネントに特定の Props や State(を外部から確認する手段などを用いて)に任意の値を代入してコンポーネントの整合性を見るテストの類ではなさそうです。またコンポーネントのハンドラがどう呼ばれたか、引数は何だったかを確認することよりも、ユーザーに操作された後どうなったかをトレースするようなテストを考えていきます。もちろん中には詳細をテストする必要も出てくるので、臨機応変に対応することにはなるでしょう。

前述どおり順序に入れ違いはありますが、今回は採用するテストライブラリの郷に入っては郷に従い 「Web アプリケーションがどのようにユーザーに見えるか・操作されるかをトレースできるテスト」 を方針として据えていくこととしましょう。

くわえて念頭においておく必要がありますが、テストランナー・テストフレームワークは Jest であり、実行が Node.js となるためブラウザ上でユニットテストを実行させるわけではありません。ブラウザ向けの Web API や DOM API は Node.js に存在せず jsdom がケアしているという点は少しだけ織り込んでおきましょう。

メリットとデメリット

Web フロントエンドにおいてユニットテストを書くことはメリットしかありません、というのはお伝えしたいところです(安全にニコニコしながらコンポーネント作りたいですよね?)。しかし実装したコンポーネントすべてに対してテストを完備しようと考えてしまったり、新しい学習要素が増えて本質的なアプリコードが進まないといった時間的・能力的な限界があったりと、メリットもある一方で推進するために障害となるような事象もあるでしょう。

もしハードルを感じる場合は、まず動作が不安定・心配で眠れないコンポーネントに小さくテストコードを書いてみるといった取り組みからでもよいでしょう。アプリは小さなコンポーネントを最終的に統合させる必要がありますが、ユニットテストは小さく始めて小さい安心から得ることができます。積み上げていくことで自信と安全を得ることができるのです。