LoginSignup
114
81

More than 5 years have passed since last update.

テストはなぜ開発を遅くするか、テストを書かない理由はある!ない?

Last updated at Posted at 2018-08-01

背景

スピード感重視なのでテストは書かない。テストはなぜ開発を遅くするか
の記事を拝読して、思うところがあったので、まとめてみる。

考察したい分類/内容

上述の記事の、以下の「まとめ」にはものすごく賛同できる。

「テストを書く」の齟齬を解消しよう。
「テストを書く」の意味は私とあなたで全く異なる。

齟齬が生じる一番大きな理由は、
各位の「前提事項」が全く異なるからだと考える。

一方で、途中の記事内容については、
前提となるプロジェクトの状態の考慮が少なすぎて、
人によっていろいろな解釈が生じてしまい、
賛同する人、しない人に分かれそうな印象であった。

「テストを書く理由」を主張する優れた人はいっぱいいる。
が、宗教的な信仰で神が居る前提で話が始まるように、
主張時に、「テストを書く」の意味は私とあなたで全く異なる
というどの点が異なるのかを相互に理解不足であるために、
「テストを書きたがらない人」と平行線のように交わらない。

本投稿では、どの点が異なると、
「テストを書く」ことへの意識が変わるのか、
プロジェクト/プロダクト/テストの性質を分類考察する。

例えば、テストを書かない人は、
こういう属性のプロジェクトの話をしているのかもしれない、
など想像をすることで、
テストを書く人へも、書かない人へも、
双方の主張のミゾを多少埋められるかもしれない。

プロジェクトの性質による違い

  • 超少人数の新規構築タイプ

    • リアルタイムで仕様が変わる
    • 何らかのプロジェクト管理プロセスが不要なレベル
    • 1~3人程度の少人数
  • 中規模開発/アジャイル

    • ほぼ全員コードが書ける/読める
    • ピザ2枚が分け合える人数
  • 大規模開発/ウォーターフォール

    • 複数のレイヤーで役割分担
    • 人数も多くスキルもバラバラ


大規模でもマイクロサービス化してアジャイルできるよね、
とか、分類していくとキリがないため、ざっくり3分類まで。

多くの人が最初に議論に挙げそうな観点はこの分類である。
しかし、「テストを書く」の意義を考える上では、
実はちょっと扱いにくい分類

後述の分類に影響を与える場合が多いため、
この分類が「間接的に効いている」ため、
「テストを書く」議論がカオス化するのだと思う。

以降で、「テストを書く」の意義に
直接的に影響を与えている特性を検討してみよう。

既存コード有無(新規orメンテ)の違い

  • 新規構築時

    • テストを書く前提であれば、
      後から書く意味はあまりないため、
      テストファーストで構築していく、ことを想定する。
    • この場合、テストを書くコストは低くなる
  • メンテナンス時(既にテストの無い実装がある)

    • テストファーストは実施出来ないため、
      障害対応やメンテナンス時に、
      少しずつテストコードを追加する、ことを想定する。
    • この場合、実質的にはリファクタリングを伴い、
      最悪全リプレイスになってしまうため、
      テストを書くコストは高くなる。
      いやいや長い目で見ればそのコストは回収できる、
      などの議論を呼ぶこともある。

テスト対象/確認観点の違い(最重要)

  • BL(ビジネスロジック)やDB操作の単体テスト

    • テストコードは作成しやすい。
    • 適切に機能分割されているという前提ならば、
      テストコードを書くべき、と最も主張出来る箇所。
  • UIや、PL(プレゼンテーション・ロジック)の単体テスト

    • テストコードを作成しても、
      人間の目で見ないとあまり効果がない場合が多い。
    • 表示用のオブジェクト(HTMLのdom等)に想定通りの文字列が入っているか、
      といった機械視点の確認まではテストコードで可能だが、
      その表示上の位置、改行箇所が自然か?
      的な確認は結局人がやることになり、議論が分かれるところ。
  • 結合/連結テスト

    • プロダクトの内容によって特性は大きく異なる。
      最も議論が分かれるところ。
    • UIの単体テストについても言えることだが、
      例えば、「Selenium」などのブラウザ操作自動化ツールでの
      「テストコード」について、議論に含めているのか除外しているのか、
      人によって感覚が違うかもしれない。
    • 「モック」や他の前提条件のエミュレートが、
      どこまで容易/有効であるか、にも依存する。
    • 機種/バージョン/環境依存の確認をここで実施したい場合、
      「テストコード」だけでなく「テストコード実行環境構築」
      が重要になってくる点に注意。
  • 総合/システム/運用テスト

    • 実データの豊富なバリエーションや、
      特殊な操作時の例外挙動、性能確認、
      複数の機種/ブラウザバージョン/複数環境での確認、
      UIのレスポンス/操作感の確認など目的は多岐にわたる。
      外部システムをモック化してしまっては意味が薄いため、
      そもそもテストコードを書くこと自体が難しく、
      テストコードだけでOKとは出来ない。
      ここは、テストコードを書く書かないの、議論の対象外と考える。


必ずしも「工程」の話をしているわけではない。
そのテストは「何のためにやるの?」という話。
例えば、作っているプロダクトの性質として、
「BL」部分が最も複雑で、その品質を確保することが重要であれば、
テストを書くことの、コスト対効果が高くなる。
一方で、「BL」はたいした処理が無くて、結合/連結以降の
品質確保が最も困難であるプロジェクトの場合は、
テストを書くことの、コスト対効果が低い、ということになる。

その他:影響しそうな要素

  • 各担当者の「テストコード学習のコスト」

    • 参加メンバーにどの程度のテスト知識があるか?
    • Java,Python,Ruby,JavaScript.Swiftなどなど、
      複数の言語を使っていると学習コストは上昇
    • プロジェクトごとに使う言語が違うと学習コストは上昇
    • SI案件では、自社サービスに比べ学習は実施しにくい、など。
  • プロダクトで使用している技術の性質

    • (開発チームにとって)新技術を使った開発か?
    • AIや分析案件、または性能が重要であるなど、
      モノヅクリとしての性質がテストコードに向いているか?
  • プロダクトに求められている「品質」の意味

    • 主要な処理が動けばOK?
    • 超レアケースも含めて一切のバグは許されない?
    • どのくらいの寿命やメンテナンス頻度を想定?
    • 例えば、あるゲームのチュートリアルを作る場合、
      想定通りに動くことより、分かりやすくユーザが飽きないこと、
      のほうが重要で、極端な話、実際のゲームと少し違う挙動でも良いし、
      ゲーム本体が変わっても、必ずしもメンテする必要はない。
  • プロジェクトや企業の文化

    • リファクタリングをどの程度許容するか?
    • (最近は居ないと信じたいが)コードのステップ数で
      生産性を見ているなどの習慣があるか?
    • 何の観点で工数見積を実施するか?
    • カバレッジの評価に対する考え方
    • テストケース表やレポートが納品物扱いになっているかどうか?


これらは、テストを書く書かないという以外にも、
「テストすること自体」や「テストを学習すること」
に対して、価値観が異なる可能性がある。

結論

誤解を恐れずにステレオタイプな印象だけで言えば、
「テストを書く人」のほうが技術レベルが高い場合が多い。
また、テストファーストのプロジェクトの方がバグが少ない。

そのため、「テストを書かない人」(及びそのプロジェクト)を
「遅れている」扱いしがちであり、
テストコード崇拝者TDDの尖兵は数多く居る。
(なんでも絶対書くべきだ、的な人)

彼らの主張が間違っているわけではない。
ただし、上記で挙げた分類や考察のように、
テストを書くことで得られる費用対効果は、
プロダクトの特性、テスト対象によって、大きく異なる。

一方、「テストを書くと遅くなる」と主張する人は、
テストコードの費用対効果が高い箇所に目をつぶり、
テストコードの費用対効果が低い箇所ばかり見ている可能性がある。
また、そもそもテストを書いたことがない、
書き方を知らないなど、知識不足もあるかもしれない。

書く書かない、0か1か、みたいな二元論はやめて、
自分のプロジェクトの特性をよく見極め、
最も効果の高いところにはテストを導入し、
効果の低いところまで無理強いはしない、
ようにすれば、もう少し幸せな世界があるのではないか?

テストを書くことで得られる効果を実感しやすく、
また、部分的ならば導入/学習コストも低くおさえられる。

なぜこのプロジェクトでは
テストコードを書くべき or 書かないべき、なのか、
盲目的に「書く」「書かない」と主張するのではなく、
得られる効果と、書くためのコストを、
テストしたい要素ごとに考慮し、
個別特性に応じて考えていくべきである。
良いと思った側に「改善」していくことが望ましい。

レガシープロジェクトに対しても、
例えば「共通ライブラリ」のコードに対しては、
テストコードを導入してみよう、などの進め方。

そうした考慮の時の考え方の一つとして、
今回挙げた分類/考察が何かの参考になれば幸いである。
テストは目的ではなく手段。本来の優先度を考えて適した手段を採用したい

おことわり

こういうポエム的な投稿をするのは全く本意ではない。
書いたそばから消したいくらい。
面白さに欠けている気がするし、
ストローマン論法のマトにしかならない。

ex.「俺、雨の日って嫌いなんだよね」
⇒「お前は干ばつで穀物が育たなくてもいいって言うのか?」
日本人は普段は曖昧なクセに、議論は極端に攻撃的。

こんなツマラナイ記事を読む時間があるならば、
こっちの記事でしりとりの考察を
読んでいただいたほうが多分面白いし、楽しい。

あくまでもいち個人としての見解を延べただけであり、
0か1かでは無いと言っているように、
「ここに延べた内容が100%正しい異論は認めない」
などと主張する気は全く無い。
全部にテストを書きたい人は書けば良いし、
書きたくない人はずっと書かないでいいと思う。

まとめ

「テストを書く」の「費用対効果」は
プロダクトの特性、テスト対象によって、大きく異なる。
0か1かの二元論はやめて、テストしたい要素ごとに個別に考え、
お互いの考え方を尊重しましょう。


114
81
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
114
81