"We need to talk about testing" を読んだ
Dan Northさんの We need to talk about testing を読んだ。
ここ最近読んだ、テストや品質系のブログ記事でダントツによかったのでメモを残しておく。
ちなみに Dan North さんは、 Behaviour Driven Development (BDD) の産みの親でもある。
TL;DR
You are testing if and only if you are increasing confidence for stakeholders through evidence.
(意訳)
ステークホルダーの不安を検証の結果を以て解消させている場合に限りテストを行っていると言える。
テストに関する誤解
テストは未だに多くの場面で「長いテスト項目リストを手動で実行する開発プロセスの最後のフェーズのこと」を指すことがある。
しかし近年、Testing From A Holistic Point Of View でも述べられているように、テストというのは上記のテストの実行だけに留まらずあらゆる品質の保証を様々なフェーズにおいて支援することを指すようになってきている。
国内では、メルペイの「全員品質」 (品質保証について語るときにメルペイQAエンジニアの語ること) だったり SHIFT ASIA の シフトレフト・ライトのテストアプローチで何ができる? だったりとちらほら「テスト」という活動が指す範囲を見直す動きが見られるようになってきた。
また多くの会社で 「QAエンジニア」という職種の募集も見られるようになってテストや品質の保証に関する関心が高まっているように見える。
また JSTQB Foundation Level シラバス の中でもテストの7原則としてテストのシフトレフトに触れている箇所がある。
早期テストで時間とコストを節約 早い段階で欠陥を見つけるために、静的テスト活動と動的テスト活動の両方をソフトウェア開発ライフ サイクルのなるべく早い時期に開始すべきである。早期テストは、シフトレフトとも呼ばれる。ソフト ウェア開発ライフサイクルの早い時期にテストを行うことにより、コストを低減または削減できる
このように国内外で「テスト = テストの実行」から「テスト = 全体の品質の保証」という考えかたに範囲が広がりつつあると考えている。 (最初からそうだったという意見もあると思うがあくまでも観測範囲においてその認識が広まってきたという感想。)
Dan North さんが書いた We need to talk about testing は、こういった背景を前提にテストの目的を改めて整理しようという記事になっていると感じた。
テストの目的
Whenever we change software—adding a new feature, changing or replacing a feature, making “under-the-hood” changes to improve things—we incur risk. For any change, there is a non-zero likelihood that we cause a Bad Thing to happen.
(意訳)
ソフトウェアに昨日の追加や改修やリファクタリングなどの変更を行う際には、必ずリスクが生じる。常に「悪いことが起こる」可能性を秘めている。
記事中でのこの主張は、様々な本ですでに触れられている話でもあるし経験から納得する人も多いと思う。
パッチサイズを小さくしてそのリスクを下げようというアジャイルな方法論などあるが0にはならなず、ソフトウェアに対する変更は常にリスクがあると言える。
加えて、「悪いこと」には様々な観点がある。
例えば、有名どころだと X 25010:2013 (ISO/IEC 25010:2011) での整理のようにこんだけ観点がある。
- システム/ソフトウェア製品品質
- 機能適合性
- 機能完全性
- 機能正確性
- 機能適切性
- 性能効率性
- 時間効率性
- 資源効率性
- 容量満足性
- 互換性
- 共存性
- 相互運用性
- 使用性
- 適切度認識性
- 習得性
- 運用操作性
- ユーザエラー防止性
- ユーザインタフェース快美性
- アクセシビリティ
- 信頼性
- 成熟性
- 可用性
- 障害許容性(耐故障性)
- 回復性
- セキュリティ
- 機密性
- インテグリティ
- 否認防止性
- 責任追跡性
- 真正性
- 保守性
- モジュール性
- 再利用性
- 解析性
- 修正性
- 試験性
- 移植性
- 適応性
- 設置性
- 置換性
- 利用時の品質
- 有効性
- 効率性
- 満足性
- 実用性
- 信用性
- 快感性
- 快適性
- リスク回避性
- 経済リスク緩和性
- 健康・安全リスク緩和性
- 環境リスク緩和性
- 利用状況網羅性
- 利用状況完全性
- 柔軟性
要するに一重に「品質」と言ってもいわゆる不具合のことも指せば、ユーザービリティや機能が存在するかの利用者視点も品質の観点のひとつなのである。
またここで重要なのは、関わる全ての人が全ての観点を気にしているわけではないという事実である。
例えば、法務部みたいなところは法律に関係あるようなリスクが気になるし、一方で技術に責任を持っているような立場からはシステム自体の品質が気になるだろう。
こんな具合で様々なステークホルダーが様々な観点をそれぞれ気にしている (不安に思っている) のである。
そこで Dan North さんは本文の中でテストの定義を以下のように述べている。
The purpose of testing is to increase confidence for stakeholders through evidence.
(意訳)
テストの目的は、検証を以てステークホルダーの不安を解消することである。
この主張での自分の解釈は、「我々がビジネスを前進させるために(自分たちを含む)ステークホルダーが懸念している不確実性を解消して、安全にかつ全員が合意した上でユーザーにプロダクトを届けるために『テスト』という活動が存在するのである」である。
You are testing if and only if you are increasing confidence for stakeholders through evidence.
(意訳)
ステークホルダーの不安を検証の結果を以て解消させている場合に限りテストを行っていると言える。
冒頭でも述べたように逆にこの活動につながらないものは、自己満足であり少なくとも「テスト」の活動ではないと Dan North さんは主張している。
例えば、儀式的なユニットテストや結合テストやデグレテストなどは「テスト」ではないということになるだろう。自分たちが書いたコードが書いた通りに動くことを保証したい場合についてはそれは自分たちをステークホルダーとして捉えた場合のテスト活動に当てはまるだろう。
最近の自分のチームでは、以下のような表を「観点」+ 「ステークホルダー」 -> 「検証手段」の順番で埋めていくことで「なぜその検証を行うのか、なぜその品質を保証したいのか」の目的を見失わないようにしている。
観点 | ステークホルダー | 検証手段 |
---|---|---|
ユーザービリティ | チーム | ユーザーインタビュー |
XXX というコア機能が正常に動作するか | プロダクトオーナー | シナリオテスト X番のテスト観点 |
A外部サービスとの結合観点 | チーム | 外部結合テスト |
セキュリティ項目 X | セキュリティチーム | シナリオテスト Y番のテスト観点 |
… | … | … |
… | … | … |
自分がよく見る失敗としては、テストレベル (内部結合テスト、外部結合テスト、シナリオテスト、…) を先に決めて誰がそのテストを担当するかを決めてからテストの実行をするような決め方である。
これは上の表でいえば「検証手段」から埋めているようなもので目的のないテストを実行することになってしまい、品質も不十分なカーゴ・カルトなテストを実行することにつながりかねない。
特に「XXXテストでは何を見るんですか?」のような発言が聞こえた時には「危険だな」と思うようにしている。
テストの目的をまず考えることが重要なのであるということをこの記事を通して改めて言語化することができた。
(余談) TDD についての誤解
Dan North さんは We need to talk about testing の中で TDD についての誤解にも触れていてそこも面白かった。
Test-driven development, or TDD, is a method of programming where the programmer writes small, executable code examples to guide the design of an API or code feature. This approach is a great way to take small, deliberate steps, and to focus only on what is necessary to get the example code working. It tends to produce narrow interfaces and well-structured, navigable code, as long as the programmer remembers to refactor and tidy up as each new example starts to work.
(意訳) テスト駆動開発 (TDD) は、実行可能な小さなコードを作っていくことで、API設計 またはコード設計をガイドするという手法。このアプローチは、意図的に小さくステップを踏むことでコードに必要最小限のものに焦点を合わせる点においてとても良いアプローチである。TDDを利用してリファクタリングと整理を繰り返すと、最小なインターフェースと適切に構造化された可読性の高いコードになる傾向があります。
上記のように、 TDD は「ユニットテストをコードと一緒に書く」が重要なのではなく 「実際に動かしながら作ることで良いインターフェースや設計にクラスを導く」 ことが主な効果と説明している。
また、TDD のこころ という発表の中にもあるようにテストコードを最初に書くというのは、「自分が最初のユーザー」になりそのクラスのインターフェースがシンプルで良いものになるというのが真髄なのである。
この目的を忘れてしまうと、カーゴ・カルト的に 「テストを先に書くことこそがTDD」 という思考に陥りかねないので何事も目的が大事という話なのかもしれない。
その他に書いていること
例えば、以下のリストのような多くの人が勘違いないしは、的確に答えることができない質問にも答えているので本文もぜひ読んで欲しい - Why don’t we just automate all the testing? - Is test coverage a useful metric? - What does it mean to “shift testing left”? - When and where should we be testing? - How much is enough testing?