プログラミングにおけるテスト
僕はQiitaとNoteそれぞれでブログを書いていて、それぞれコードがある技術的なものを前者、それ以外をNoteで書くという書き方をしてます。まぁもっと言ってしまうと、ポエミーなヤツはNoteに書くって感じです。
最近よく考えるテーマとしては、テスト(ここでは自動テストを指します)というものがあります。今日の記事はそんなテストに関するポエムというか、筆者の頭の整理のために書いたものです。
どうにもTDDは誤解を受けやすい
TDD(テスト駆動開発)には色々な要素が巻き込まれしまっている分、誤解されやすいものです。
一番誤解されやすいのはテストファーストとの混同です。
最初に落ちるテストを書いて、それに受かるコードを書いて、コードをリファクタリングする、という工程はものすごくキャッチーで知名度が高いものですが、TDDにおいて必須要件ではありません。
そもそも、TDDにおいて、自信があるならテストを省略しても構いません。どう考えても自明だろみたいなテストは書かなくてもいいのです。つまり、TDDでは、カバレッジ(プログラムをテストでカバーする割合)は100%であることを決して要件はしていません。
なぜなら、TDDにおいてテストを書く、あるいはテストファーストを行うのは、設計のためにやる行為に過ぎないからです。主体は設計です。
ユースケースや、APIのIN/OUTを元にテストケースを開発しながら、設計を行うためのものです。もし、すでに設計が固まっているものであれば、それはもうTDDではないのです。
TDDにおいてのテストはユースケースの表明だといえます。もちろんTDDのあとに登場したBDDも同様です。
ユニットテストが望ましい理由
ユニットテストが望ましい理由は幾つかあります。
・ ユニットテストが書きづらい場合は、設計の悪さを示している
・ テストが十分高速である限り、開発のテンポが良くなる
・ 十分なユニットテストがある限り、リファクタリングが当たり前にできる
ユニットテストが書きづらい場合は、対象の関数やメソッドが、複数の責務を抱えているケースがほとんどです。
リファクタリング(外から見た振る舞いを変更せずに中身を変えること)を当たり前のように行うためには最低限なんらかの自動テストが必須です。これはリファクタリングによって外から見た振る舞いが壊れていないことを証明するためのものです。
特にCI/CDが完備していればテストが壊れない限り、リファクタリングを自由に行えます。判子の承認も必要なければ、誰かのレビューも必須ではありません。プロダクト計画とは無関係にコードを改善しつづけることができます。(もちろん重要なリリースの前や、金曜日の夕方のようなタイミングでリファクタリングをpushすることは望ましくはないかもしれません。)
もちろんユニットテストではなくても、「外から見た振る舞い」を再現できる単位のテストであれば、リファクタリングは可能です。ただユニットテストであれば、リファクタリングをテンポよく行えるのです。
リファクタリングは息をするように、水を飲むように、それくらいの当たり前でなければ、リファクタリングは難しく面倒なものに成り果ててしまいます。
たびたび「リファクタリング」と言いつつ外から見た振る舞いを変更することがありますが、リファクタリングと、外から見た振る舞いの変更は決して同時に行ってはいけません。
技術的負債を返済しようとしてそういった誤ったリファクタリングをしがちですが、それは技術的負債の返済におけるアンチパターンの1つです。
レイヤーアーキテクチャとテスト
適切な責務で分割したレイヤーは、テストが書きやすくなります。詳しくはClean Architectureは全てのプログラマにお奨めしたい良著という過去の記事にも書いています。
なぜテストやリファクタリングが重要なのか
今の時代、プログラミングとは決められた固定の何かを作る仕事ではなくなったからです。
コンピュータ関連のテクノロジーもそれ以外の業界も、ビジネスモデルもあらゆるものが日進月歩です。皆さんもさすがにそういった変化を感じていることでしょう。3年前の常識が今でも通用しますか?その常識で将来的なビジネスが成立しますか?
世界的にみてもそういった速度感を持っていない企業は、どんどん負け戦をしいられています。
開発に3年掛けられるような業種は割とレアです。ゲーム開発や銀行なんかはそういった長期間の開発も許されるでしょう。でも多くのビジネスにおいては3年の開発期間は決して許されるものではありませんし、それくらい長い開発はデスマーチ化が常態化しているでしょう。
アジャイルが当たり前になっているのは、そういった背景があるからです。アジャイルソフトウェア開発宣言がなされた2000年代はじめですら、そうだったのです。
ましてや、2020年の今となっては、皆さんも実感していると思いますが、2000年の頃よりも技術やビジネス、ライフスタイルの変化は確実に早くなっています。
TDDやリファクタリングがアジャイル界隈から生み出されたのもそういった、状況の変化に対応する必要があったからなのです。
フロントエンド界隈はテストと抽象化が足りてない
フロントエンド界隈の人はどうも、テストに慣れてないのと、抽象化やレイヤー化といったものに慣れてないなーと感じることがあります。
バックエンド方面では成熟した設計論や開発論が、フロントエンド界隈ではまだ未熟ではないでしょうか?
テストに関して研究も実践も足りてないなーと感じるのです。まぁ僕自身いつでも実践できてるわけでもないですが、そこはそれとしても、業界全体として、取り組みが足りていません。
これは、ビジュアルテスティングといわれるジャンルのSaaSで、こういう取り組みはいいとは思います。ただ、少しコストがかさむのが難点ですかね。同様のOSSもありますが、多少面倒ではあります。
バックエンド界隈の人はもっとフロントエンドに踏み込むべき
そういう意味では、バックエンドでテストやレイヤードアーキテクチャとかに慣れた人がフロントエンドに踏み込むのが最強だと信じてやまないところです。
まぁバックエンドの人には、ウェブ開発においては、フロントエンドが大きな位置を占めてることを認識してほしいなと思ったりもします。
Chrome以外のブラウザがだいたい死に果てたし、何ならポリフィルもあるので、面倒なところ全部パスできるいい時代です。
昔のクソみたいなオモチャのようなJavaScriptの時代とは異なって、最新の言語仕様(ECMAScript)、特に完全上位互換で静的型の概念が追加されたTypeScriptでは他の言語と比べても、十分実用的に開発のできる言語に育っています。
まとめ
なんだか、最後は愚痴混じりのとっちらかった文章ですが、テストは、激動の時代だからこそ必要であり、ビジネスを前にすすめるための重要なエンジンです。そして、そういうものに慣れているバックエンドの開発者は、フロントエンドは、チャレンジすべきフロンティアです。
この記事が気に入ったらサポートをしてみませんか?