開発者のテストとテストエンジニアの機能テスト

前から薄々思っていたのですが、両者はケースの作り方が全く異なります。

期待値のあるテストとその限界

開発者の考えるテストケースは想定した入力に対して期待した出力があるかというもの。ユーザ操作などの入力に対して、処理・分岐・値の更新・APIコール・メッセージの送信・ログの記録…等、設計したことが実際に行われているかを確かめるものです。ユニットテストがまさにそうです。ASSERT(result==expected)というのは
「ある条件で、あることをすると、こうなるはずだ。」
というものです。

テストエンジニアがエンドユーザの行える操作を駆使して行う機能テストにも同じ考えで作られるケースがあります。例えば「ユーザが○○画面の戻るボタンをしたら△△画面に移るか?」というのも結局人間の言葉で書いているだけでASSERT(result==expected)と同じ発想です。抽象度が異なるだけでやることは同じ。

もちろんこの発想だと、設計通りか?を確かめることはできますが、設計し忘れたことが無いか?を確かめることはできません。処理1,2,3をやればいいと考えていれば、4を忘れていたという欠陥は検出できません。機能Aに関するテストは機能Aに関することだけとしていれば、機能Bに影響してしまうという欠陥は検出できません。完璧なテストなど作れない本質的な理由です。こういった問題は設計の段階で人数(視点)を増やして気づきやすくすることによって解決すべきもので、テスト自体は誰が行っても同じ結果になることが望ましいと思っていました。しかしそれは間違いだと実感するようになりました。

期待値の無いテスト

文書化されていない全くオリジナルのケースを行ってバグをよく見つける人がいます。開発スキルが優れているわけではありません。どうしてその操作をしようと思ったのか聞いても「たまたま」「なんとなく」という曖昧な答えが返ってきます。世間的にこういったスキルを持つ人種が存在するようです。"テストエンジニア 直観力"で調べると出てきます。
息の長いエンジニアでゆこう: 女性の直感力が生きるIT分野 -テストエンジニア-

私はとても重要なことに気づきました。彼らの作るテストケースとは
「どうなるかわからないけどやってみよう」
という姿勢から生まれたものなのです。テストとは「ある条件で、あることをすると、こうなるはずだ。」という期待値が無ければならない発想とは全く違います。そもそも「どうなるかわからないけどやってみよう」というのは設計者としては言ってはならないことだと思います。「原因はわからないけどここを変えたら直るかな?」と、あての無い試行錯誤をする人はチェンジニアと揶揄されたりします。

しかし事実、彼らの作る突飛な発想のテストケースによって我々設計者は非常に助けられています。設計者の発想では何人がかりでも非常に想定しにくいケースを拾うのは彼らしかいません。設計者はこうしたケースからあらかじめ何に気をつければよいかを学ぶべき…なのですが、中には学びようが無いことも少なくない気がします。「次から気をつけて下さい」と言われても「何に?」というオチにならざるを得ない場合がある気がします。

とは言っても、バグを見つける突飛なテストケースを思いつくスキルは形式知にできません…と諦めては前に進めません。色々なプロジェクトから突飛なテストケースを集めれば共通項がわかるかもしれません。今のところは、もしチームに期待値の無いテストで多くのバグを見つけるテストエンジニアがいるならば大事にすべきかと思います。つかみ所の無いテーマですが、今後も考えてゆくつもりです。