この記事はTesting Technology Advent Calendar 2023の13日目の記事です。
本記事について
先日Xでメンテナンスコストが高くなるのに質の悪いテストをリポジトリに含めるのか?といったポストを見かけ少しモヤっとしたためそのことについて考えてみただけの記事です。
この記事はおそらく筆者が個人的に思ったこと、考えたことを書くポエムになると思いますがもし何かご意見・ご感想をいただけるようであればコメントいただけると嬉しいです🙌
対象読者
- テスト初学者
- テストについて普段いろいろ考えている方
- テストが好きな方
質の悪いテストがあることによる弊害
書籍「単体テストの考え方/使い方」では単体テストは資産ではなく負債と書かれています。これはプロダクションコードも同様であり、テストも例外ではなく、コードは書けば書くほど負債となっていくのです。
とはいえ、プロダクトを成長させるには当然コードは書き続けていかなければならないですし、持続可能なコードを保つには単体テストを書くことは不可欠です。
そのため、単体テストはただ書けばいいというわけではなく、質の良い単体テストを書くということを心がけなければなりません。
現代の開発現場では単体テストを書くことがほぼ当たり前になってきましたが、次の段階として質の良い単体テストを書くということが求められているように感じます。
こういった事情があるため質の悪い単体テストがリポジトリに置かれるのは望まれることではないでしょう。質の悪い単体テストがどういったものでなぜ置かれるべきではないのかを詳しく知りたい方は「単体テストの考え方」を読まれることをおすすめしますが、最も大きな弊害はリファクタリングへの耐性が損なわれ、メンテナンスコストが高くなるということだと思います。
リファクタリングはプロダクションコードが持続的に成長していくために必須の行程のため、その難易度が上がるということは非常に大きな問題となりえます。
そのため、もしテストを書き慣れていない開発者が書いた質の悪い単体テストがあったとしたらそれはなるべくなら配置したくないテストということになります。なぜなら、そのテストが存在する利益よりも存在することによる負債の方が高くつくからです。
じゃあテスト初学者はテストなしで開発すればいいの?
そんなわけはなく、テストは開発手法の一種であり開発過程からテストを書くという行程を省略するようなことは容認できないでしょう。例え質の悪いテストになったとしても単体テストを書かないで開発を進めるよりも書きながら開発を進める方が大体の場合は良いでしょう。
そもそも、単体テストを書くことを上達させるには単体テストを書くしかないので、書かなければいつまでたっても上達することはできないと筆者は考えます。
そのため、単体テストを書けば負債になり、書かなければ上達しないという困難な問題に向き合わなければなりません。
テスト初学者ができること
では、単体テスト初学者ができることはないのか少し考えてみました。
単体テストについて学ぶ
単体テストについて学ぶには「テスト駆動開発」や最近話題になった「単体テストの考え方/使い方」など有名で大変有益な書籍があるのでそれらを読むことで質の良い単体テストに近づくでしょう。
しかし、内容についてはそれなりにテストを書いてこないとピンとこないようなところもありもし理解できないようであれば無理に理解しようとせず、まずは単体テストを書くという体験を増やした方が良いと思います。逆に「テスト駆動開発」なんかはテストを最初に書くというテストファーストというわかりやすいルールがあり、これは下手にテストに関しての持論が芽生えてしまうとスッと入ってこないと思うので変な持論を持つ前のまっさらな状態で取り組むと素敵なTDD開発者になれると思います。(筆者はテスト駆動開発は良いものだと思ってますがテストファーストでテストは書いてないです。)
とはいうものの、質の良い単体テストを書くには質の良い単体テストが何なのかを知る必要があると単体テストの考え方でも述べられており、いずれはちゃんと理解する必要があるのも事実です。
プライベートで練習する
実務で使用しているプロダクションリポジトリが使えないなら個人的なコードで練習するといったことが考えられます。上記で挙げたテスト駆動開発なんかは書籍に書いてあるサンプルコードが多く書いてあるので、手元で実際に書いた方が良いと思います。テスト駆動開発に書いてあることを読んだだけでは理解しきれないことがあると思うため、これは実際に書いた方が良いです。
「単体テストの考え方」もサンプルコードは書いてあるので実際に書いてみても良いでしょう。
筆者が会社のテックブログでテスト駆動開発を読んだ感想を記事にしてるので何かの参考に一応載せておきます。
書籍のサンプル以外にも簡単なデモプロジェクトやOSS開発などを通して単体テストの練習をするのは単体テストの上達につながるでしょう。
テスト評価者ができること
開発者だけではなくチームや組織などそのテストを評価する側ができることはないか考えてみました。
テストコードもレビューする
プロダクションコードだけではなくテストコードまでレビューしている組織は多くないのではないかと思います。(そんなことなかったらすみません。)プログラミングの上達にメンバーや先輩エンジニアにレビューをしてもらうのと同様にテストもレビューしてもらうことで何が良いテストで何が悪いテストなのかが理解できテストの上達につながるでしょう。
ただし、その弊害としてレビュワーの負担が増えるということが考えられるのとレビュワーも単体テストに関しての理解が求められるのでハードルが上がるようにも思います。
こういった問題はもしかしたらAIで解決しないかなと思ったりもします。
テストに関しての勉強会などを開く
開発者個人個人がテストを学ぶことも大事ですが、組織やチームとして単体テストの勉強会のようなものを開くのもありかもしれません。ただ、これも業務の時間を使って開催することになると思うので組織や開発メンバーの負担が増えることになるでしょう。
まとめ
だらだらと書いてきましたが以下まとめです。
- 書いたテストコードは負債になるという意識が必要
- 現代の開発においてテスト初学者は書籍やプライベートリポジトリで学習する必要がある
- 組織やチームでも単体テストの質を向上させるような取り組みが必要なのかもしれない
そもそも、質の良いテストを追求するとより良い設計とはという思考になりがちなので本当の初学者には難易度が高いでしょう。偉そうに書いてきましたが筆者もテストや設計についてまだまだ学習中です。
理想を追求するなら質の悪いテストはプロダクションリポジトリに含めたくはないので実装者はテストについて学び、組織やチーム側もテストの質が上がるような取り組みをすることで質の良いテストに導いていくことが大事でしょう。
しかし、現実問題それを実現するには開発者個人に学びを強制する必要がありますし、組織の負担も大きくなるので、やっぱりある程度は妥協して例え質の悪いテストだとしてもリポジトリに含めざるを得ないのではないかと思います。
今回は以上です🐼
おまけ
CopilotやChatGPTといったAIによる開発支援の進歩が凄まじい現在、単体テストの質を一定以上に保つのにAIが使われていくのではないかと筆者は思ったりします。AIである程度期待通りの単体テストを出力させるにはAIが出力しやすいプロダクションコードを実装することが大事でしょう。結局これは人がテストコードを書くのと同様、副作用のない純粋関数のような入力に対して予測可能な出力が定まるコードを書くことかなとも思います。
質の悪いテストのメンテナンスに苦しむことになるなら、AIに一定以上の質の単体テストを書いてもらう時代が来るのかもしれません。そして、そのような未来が来ればAIがテストを生成しやすいようなプロダクションコードの実装が求められるようになるでしょう。
- AIによる単体テストの生成
- AIが生成しやすいようなコード実装
この2つは今後のAIを中心とした開発において重要なものになるかもしれないなとこの記事を通して感じました。