「単体テスト」という用語が引き起こした認識齟齬について

本記事はソフトウェアテスト Advent Calendar 2021 2日目の記事です。
## はじめに
### ご挨拶
ソフトウェアテストのカンファレンスにはここ数年よく足を運んでいますが、ソフトウェアテストの記事は初めて書きます @yassai です。今年も始まりましたAdvent Calendar、まだまだ2日目ということで、フルスロットルなゴリゴリ技術系記事ではなくポエムチックなコラムを目指して、今回は用語の認識齟齬について書きました。認識齟齬自体はよくある話ですが、こんな基本的な用語でも人によって受け取り方が違うんだなぁとびっくりしたので、ぜひ皆様にも共有したいと思います。なお、話に登場する弊社社員は、私を含め全員が開発者 or PMで、基本設計～開発・テスト～運用保守まで幅広くこなすが、QAなどの専門分野はないエンジニアとお考えください。

### 前日談
**「単体テストは必須です！単体テストをやりましょう」**

社内勉強会にて発表者にこう言われたら、ソフトウェアテスト界隈の方々はこう思うのではないでしょうか？「いや、当たり前じゃん…。そもそも単体テストやらないでリリースとか、そんな事ありえる？」と。リリース後に一体どうやって運用保守やってたんだ、障害が頻発して新規開発がストップしてしまうのではと気になってヒアリングしたところ、 `単体テスト` という用語の定義が異なることが明らかになりました。

## 「単体テスト」という用語の定義
[JSTQBシラバス最新版(2018V3.1.J03)](http://jstqb.jp/syllabus.html#syllabus_foundation)にはpp.31-33に単体テスト(シラバス内ではコンポーネントテスト)の記述があります。要約すると、単体テストとは以下の特徴を持っています。

- 様々なテスト活動のまとまりを指す"テストレベル"という概念があり、複数あるレベルの内の一つが単体テスト。
- 単体テストのテスト対象は、クラスやモジュールなど。
- 単体テストの担当者は、一般にはプロダクトコードの開発者だが、そうでない場合もある。
- 特にアジャイル開発では、自動化されたテストコードを記述する場合がある。

私の中で `単体テスト` とは、あくまでテスト粒度の話であり、手法については(テストコードの記述が強く推奨されるものの)定義に含まれないものと考えていました。たとえ手動によるテストというレガシーなやり方であったとしても、粒度さえ適切ならばそれはそれで単体テストであると考えていました。一方で相手の中では違っていて、 `単体テスト` の定義とは、"テストコードを記述して動作確認するテスト"という具体的な手法についても定められた、より広い定義だったのです。つまり前日談に記載した

> 「単体テストは必須です！単体テストをやりましょう」

とは、実は「手動による動作確認ではなく、テストコードを書いて動作確認しましょう」という意味だったのです。なるほど～、そこで認識違ったか～、納得しましたﾁｬﾝﾁｬﾝ…となれば良かったのですが、認識齟齬は別なところでも起きていました。

## 受け取り方が人によって違う？
同じPJの同僚にこの話をしたところ、どうも `単体テスト` という用語は人によって受け取り方がまちまちだということに気付きました。

- PM「 `単体テスト` は粒度の話だが、(単体テストの英訳の) `ユニットテスト` は粒度+手法(自動テスト)という印象」
- 開発者1「 @yassai と同じ認識だけど、まあテストコード書かないってことないですしねぇ…。手法も定義に含まれるのかなぁ？」
- 開発者2「考えたこと無い。」

なんで認識がこんなバラバラなんだよと思って俄然興味が湧いてきたので、社内でちょっとしたアンケートを取ってみました。

======アンケートここから======

あなたは新しく参画したビジネスパートナーであるAさんとBさんに個別にお話をしました。下記質問内のA・Bさんの発言を基に、質問に回答してください。客観的な回答ではなく、あなたがどう感じたか・どう思ったかを回答してみてください。

(1)Aさん「前の現場では、開発(コーディング)と単体テストをしていました。」
   この発言を聞いて、あなたが感じた内容に最も近い選択肢を選んでください。

(2)Bさん「前の現場では、開発(コーディング)とユニットテストをしていました。」
   この発言を聞いて、あなたが感じた内容に最も近い選択肢を選んでください。

( @yassai 注: (1)(2)の選択肢は同一で、下記4つから一つを選ばせた)

- 担当箇所のコーディングと動作確認を行っていた
- 担当箇所のコーディングだけでなくテストコードを書いて動作確認していた
- CI/CDによる自動テストを実施していた
- その他(自由記述)

======アンケートここまで======

このアンケート結果が下の図です。

![figure1-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130268/1f3fe062-d0a2-339c-cdd8-df7c113571e8.png)


まず `(1)Aさんの印象` を見ると、手動/自動関係なく動作確認を行ったと考えた人が8人いた一方で、明確にテストコードを書いたと考えた人は10人でした。意見が真っ二つですね。このことから「単体テストという言葉を聞いた時に、手法を考慮しない人と、テストコードの記述まで明確に想像する人がいる」といえます。
次に `(2)Bさんの印象` を見ると、手動/自動関係ないと考えた人は5人と減った一方、テストコードを書いたと考えた人は11人と微増、そして面白いことに、CI/CDツールによる自動テストの実施までやっていると考えた人が2名出てきました。このことから「ユニットテストという言葉を聞いた時には、テストコードの記述やCI/CDによる自動化という手法まで想像する人がいる」といえます。
更に(1)と(2)で個人内で回答がどう変化したかを追うため、円グラフから棒グラフに変換して更に回答の変化別に集計したのが下の図です。

![figure3_fin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130268/b09a277d-a696-d07f-6d0c-1efcfe3a9847.png)


(1)→(2)で回答を変化させた人は8名/20名でした。(1)で手動/自動関係ないと考えたが(2)で回答が変化した人は5人いて、うち4人が自動テストに回答を変えていました。(1)で自動テストと回答して(2)で手動/自動関係なしと回答を変化させた人が2人いるのがちょっと上手く解釈できてないです。この結果から「単体テストとユニットテストの言葉の定義が異なる人が相当数いる」ということがわかりました。

## まとめ
`単体テスト` という基本的な用語が、テスト粒度を指すのか、テスト手法まで指すのか、その定義が人によって異なるとは、全く思いもよらなかったことでした。定義が手法にまで及んだことは、開発者がテストコードを書くという習慣が浸透してきたという証左であるとも言えるでしょう。その意味では、この変化はとても喜ばしいことなのかもしれません(ただ個人的には、単体テストの定義はやはり粒度の話までに留めた方が良いのではと思っていますが…)。

QAという職種も段々と広まりつつあるように、今後は技術の細分化がますます進んでいきます。自分にとってあまり詳しくない分野がこの先多くなることは避けられないでしょう。「こんな基本用語、エンジニアなら誰だって知ってるでしょ」と思っていても、実は特定の分野の人にしか通じない、もしくは別の分野では異なる定義がされていて、思いがけない認識齟齬にぶつかるということがよく見られるようになるかもしれません。認識齟齬をなくすには、まずは用語の定義から。この基本の大切さを改めて思い知らされました。