初学者が書いたテストはリポジトリに含まれるべきではないのか？


この記事は[Testing Technology Advent Calendar 2023](https://qiita.com/advent-calendar/2023/testing-tech)の13日目の記事です。

## 本記事について

先日Xで**メンテナンスコストが高くなるのに質の悪いテストをリポジトリに含めるのか**?といったポストを見かけ少しモヤっとしたためそのことについて考えてみただけの記事です。

この記事はおそらく筆者が個人的に思ったこと、考えたことを書くポエムになると思いますがもし何かご意見・ご感想をいただけるようであればコメントいただけると嬉しいです🙌

## 対象読者

- テスト初学者
- テストについて普段いろいろ考えている方
- テストが好きな方

## 質の悪いテストがあることによる弊害

書籍「単体テストの考え方/使い方」では単体テストは**資産ではなく負債**と書かれています。これはプロダクションコードも同様であり、テストも例外ではなく、コードは書けば書くほど負債となっていくのです。

とはいえ、プロダクトを成長させるには当然コードは書き続けていかなければならないですし、持続可能なコードを保つには**単体テストを書くこと**は不可欠です。

そのため、単体テストは**ただ書けばいい**というわけではなく、**質の良い単体テストを書く**ということを心がけなければなりません。

現代の開発現場では単体テストを書くことがほぼ当たり前になってきましたが、次の段階として**質の良い単体テストを書く**ということが求められているように感じます。

こういった事情があるため**質の悪い単体テスト**がリポジトリに置かれるのは**望まれることではないでしょう**。質の悪い単体テストがどういったものでなぜ置かれるべきではないのかを詳しく知りたい方は「単体テストの考え方」を読まれることをおすすめしますが、最も大きな弊害は**リファクタリングへの耐性**が損なわれ、メンテナンスコストが高くなるということだと思います。

リファクタリングは**プロダクションコードが持続的に成長していくために必須の行程**のため、その難易度が上がるということは非常に大きな問題となりえます。

そのため、もしテストを書き慣れていない開発者が書いた質の悪い単体テストがあったとしたらそれはなるべくなら**配置したくない**テストということになります。なぜなら、その**テストが存在する利益よりも存在することによる負債の方が高くつく**からです。

## じゃあテスト初学者はテストなしで開発すればいいの？

そんなわけはなく、テストは**開発手法**の一種であり開発過程からテストを書くという行程を省略するようなことは容認できないでしょう。例え質の悪いテストになったとしても単体テストを書かないで開発を進めるよりも書きながら開発を進める方が大体の場合は良いでしょう。

そもそも、単体テストを書くことを上達させるには**単体テストを書くしかない**ので、書かなければいつまでたっても上達することはできないと筆者は考えます。

そのため、**単体テストを書けば負債になり、書かなければ上達しないという困難な問題**に向き合わなければなりません。

## テスト初学者ができること

では、単体テスト初学者ができることはないのか少し考えてみました。

### 単体テストについて学ぶ

単体テストについて学ぶには「テスト駆動開発」や最近話題になった「単体テストの考え方/使い方」など有名で大変有益な書籍があるのでそれらを読むことで質の良い単体テストに近づくでしょう。

しかし、内容についてはそれなりにテストを書いてこないとピンとこないようなところもありもし理解できないようであれば無理に理解しようとせず、まずは**単体テストを書くという体験を増やした方が良い**と思います。逆に「テスト駆動開発」なんかはテストを最初に書くというテストファーストというわかりやすいルールがあり、これは下手にテストに関しての持論が芽生えてしまうとスッと入ってこないと思うので変な持論を持つ前のまっさらな状態で取り組むと素敵なTDD開発者になれると思います。(筆者はテスト駆動開発は良いものだと思ってますがテストファーストでテストは書いてないです。)

とはいうものの、**質の良い単体テストを書くには質の良い単体テストが何なのかを知る必要がある**と単体テストの考え方でも述べられており、いずれはちゃんと理解する必要があるのも事実です。

### プライベートで練習する

実務で使用しているプロダクションリポジトリが使えないなら**個人的なコードで練習する**といったことが考えられます。上記で挙げたテスト駆動開発なんかは書籍に書いてあるサンプルコードが多く書いてあるので、**手元で実際に書いた方が良い**と思います。テスト駆動開発に書いてあることを読んだだけでは理解しきれないことがあると思うため、これは実際に書いた方が良いです。

「単体テストの考え方」もサンプルコードは書いてあるので実際に書いてみても良いでしょう。

:::note info
筆者が会社のテックブログでテスト駆動開発を読んだ感想を記事にしてるので何かの参考に一応載せておきます。
:::

https://engineering.cocone.io/2023/01/19/impressions_of_tdd/

書籍のサンプル以外にも簡単なデモプロジェクトやOSS開発などを通して**単体テストの練習**をするのは単体テストの上達につながるでしょう。

## テスト評価者ができること

開発者だけではなくチームや組織などそのテストを評価する側ができることはないか考えてみました。

### テストコードもレビューする

プロダクションコードだけではなくテストコードまでレビューしている組織は多くないのではないかと思います。(そんなことなかったらすみません。)プログラミングの上達にメンバーや先輩エンジニアにレビューをしてもらうのと同様に**テストもレビューしてもらう**ことで何が良いテストで何が悪いテストなのかが理解できテストの上達につながるでしょう。

ただし、その弊害として**レビュワーの負担が増える**ということが考えられるのと**レビュワーも単体テストに関しての理解が求められる**のでハードルが上がるようにも思います。

こういった問題はもしかしたらAIで解決しないかなと思ったりもします。

### テストに関しての勉強会などを開く

開発者個人個人がテストを学ぶことも大事ですが、組織やチームとして単体テストの勉強会のようなものを開くのもありかもしれません。ただ、これも業務の時間を使って開催することになると思うので組織や開発メンバーの負担が増えることになるでしょう。

## まとめ

だらだらと書いてきましたが以下まとめです。

- 書いたテストコードは**負債**になるという意識が必要
- 現代の開発においてテスト初学者は書籍やプライベートリポジトリで学習する必要がある
- 組織やチームでも単体テストの質を向上させるような取り組みが必要なのかもしれない

そもそも、**質の良いテストを追求するとより良い設計とは**という思考になりがちなので本当の初学者には難易度が高いでしょう。偉そうに書いてきましたが筆者もテストや設計についてまだまだ学習中です。

理想を追求するなら**質の悪いテストはプロダクションリポジトリに含めたくはない**ので実装者はテストについて学び、組織やチーム側もテストの質が上がるような取り組みをすることで**質の良いテストに導いていく**ことが大事でしょう。

しかし、現実問題それを実現するには開発者個人に学びを強制する必要がありますし、組織の負担も大きくなるので、やっぱりある程度は妥協して例え質の悪いテストだとしてもリポジトリに含めざるを得ないのではないかと思います。

今回は以上です🐼

## おまけ

CopilotやChatGPTといったAIによる開発支援の進歩が凄まじい現在、単体テストの質を一定以上に保つのにAIが使われていくのではないかと筆者は思ったりします。AIである程度期待通りの単体テストを出力させるには**AIが出力しやすいプロダクションコードを実装する**ことが大事でしょう。結局これは人がテストコードを書くのと同様、**副作用のない純粋関数**のような入力に対して予測可能な出力が定まるコードを書くことかなとも思います。

質の悪いテストのメンテナンスに苦しむことになるなら、**AIに一定以上の質の単体テストを書いてもらう時代**が来るのかもしれません。そして、そのような未来が来ればAIがテストを生成しやすいようなプロダクションコードの実装が求められるようになるでしょう。

- AIによる単体テストの生成
- AIが生成しやすいようなコード実装

この２つは今後のAIを中心とした開発において重要なものになるかもしれないなとこの記事を通して感じました。