なぜ自分が開発したソフトウェアのテストをするのは面倒なのか?
どうも、そろそろ1年目を名乗れなくなりますhalspringです。
「要件定義、仕様策定、設計から開発まで関わったシステム」に対して「自分でテストを設計して実施する」機会があったので、そこで感じたことや考えたことを踏まえて いつものようなテストのエモい話を語ります。
テストは面倒くさい?
この記事を読んでいる方の立場にもよって意見も別れると思います。
貴方は開発を行う立場でしょうか?
貴方はテスト設計を行う立場でしょうか?
それとも、貴方はその両方でしょうか?
恐らくですが、テスト設計をメインに行う立場の人ほど「テストは面倒」とは思わないのではないでしょうか。
そして、開発をメインに行う立場の人ほど「テストは面倒」なのではないでしょうか。
なぜ開発を行う立場に近づくとテストが面倒に感じてしまうのか、今回はそれを考えてみました。
開発するとき無意識にしていること
開発経験のない方でもイメージできると思います。
開発者はエディタを開いてプルリクを出すまでに何をしているでしょうか?
(※ 完全に私個人の見解です )
仕様を確認して、
ロジックを考えて、
コードを書いて、
コーディング規約の確認もしつつ、
動作確認をして、
問題なさそうなのでgit commitして、
プルリクを送る
これだけでしょうか?
いいえ、違います。
書いたコードが1発で正しく動作するなんてことは、よほど仕様がシンプルでない限り稀です。
大抵はうまくいかず、修正をしながらコードを書き進めていきます。
コーディングして、
動作を確認、
不安なところは念入りに、
あぁここclass名変えたんだった...、
コードを直して動作確認、
バリデーションは大丈夫だろうか、
変なメールアドレス入力してみよう、
よし大丈夫だ、次だ次...
概ね、こんな感じではないでしょうか?
ところでこれ、ちょっと何かに似ています。
テストに詳しい方ならお気付きかもしれません、そうです探索的テストです。
修正に当たる部分をissueやバグ票に置き換えるとあまり違いがないようにも思えます。
つまり開発者は、開発中に探索的テストに近いことをしているのです。
テストの順番
実施するテストには順番があります。
もちろん、プロジェクトやテスト戦略によって色々ですが、個人や会社である程度の型は経験則としても持っているかと思います。
例えば「パフォーマンステストをしてからシステムテストをするつもりです」と言われたら、耳を疑いますよね?
「探索的テストをがっつり実施してからシステムテストの設計をしてください」と言われても、気乗りしませんよね?
(スモークテスト的に行うことはありますが)
テストにはそれぞれ目的があり、適したタイミングで適した不具合を見つけることが大切です。
探索的テスト
ちなみに、探索的テストはいつ行うのが良いのでしょうか。
もちろん絶対的な正解はありませんが、
一般に、様々なテストを行った後に補完的に行われることが多いと思います。
JSTQB ALTAのシラバスにも、次のように記載があります。
優れた探索的テストは、しっかりと計画されており、相互作用的で創造的である。探索的テストは、テスト対象の システムに関するドキュメントをほとんど必要としないため、ドキュメントが存在しないか、他のテスト技法では適 切でない場合に使用することが多い。また、多くの場合、他のテストを補完したり、追加のテストケースを開発す るための基準を提供したりするために使用する。
先程も例として書きましたが、仕事でテストをしている方であれば、
「探索的テストをがっつり実施してからシステムテストの設計をしてください」と言われるとなんとなく二度手間感があったりして、面倒臭さが出てくると思います。
( 完全に私自身の見解です )
ところでこの状況、なにかに似てませんか?
そうです、先程の開発しているときの話をしました。その開発の後にテストが待っています。
開発者はコーディングする中で探索的テストのようなテストケースのないテストを行っているため、その後にテスト設計を行うことが億劫に感じるのです。
( ※ 完全に私個人の見解です。 )
では、なぜ探索的テストの後のテスト設計は億劫なのでしょうか。
テスト設計時に無意識にしていること
開発するときにどう考えているかを勝手に考えてみましたが、
次はテスト設計するときにどう考えているか考えてみます。
※ くどいようですが完全に私個人の見解です。
弊チームのボスからとある話を聞き、考えてみたところ、
自分はテスト設計をするときに、ソフトウェアがどう実装されているかを考えていました。
機能の追加や改修があれば、どんなロジックを追加する必要があって、どんなところが複雑になるかを考え、「こんな実装をしているだろう」のイメージを作っていました。
いくつかの「こうすれば実装できる」のイメージから、
・データのやり取りがありそうだから、ここをしっかり見ておきたい
・自分だったらこのあたりでミスしそう
といった感じにリスクや観点を考えています。
その後、改めて仕様書を見てリスクや観点を洗い出し、先程のリスクや観点を比較して漏れがないか考えます。
この記事を読んでいる皆様と自分で どんな流れでテスト設計をしているか異なるとは思いますが、共通して仕様書からいろいろと要素を拾い上げることはしているはずです。
ところで開発者は...
さて、時は実装前まで戻ります。
この記事のはじめにも書きました、コードを書く前に仕様を確認していますよね。
そうです、実装するまでに仕様書を読み込む必要があるわけです。
また、どう実装するか、そのロジックに至るまでも頭に叩き込んであるわけですね。
その後にもう一度 どう実装するか考えたり 仕様書を読み込んだりしたくないわけですよ!
一度頭に入った情報は材料にもなりますがノイズにもなり得ます。(私個人としてはこのノイズがテスト設計のときに思考の妨げになっていました。)
探索的テスト後のテスト設計の二度手間感も同様でここに起因していると思います。
二度手間「感」ではなく、本当に二度手間を掛けているわけです。
どうすれば面倒にならないのか
本当はここで画期的な提案ができればよいのですが、残念ながらここはまだ模索中です。
現状思いつくのはテスト駆動開発です。
ユニットテストを設計・実装しながら開発を進めることで、探索的テストライクな部分がユニットテストに置換されます。
ユニットテストも結局仕様を把握する必要はありますが、テストの順番として違和感が軽減されます。
単体テスト・結合テストを実施してからシステムテストを行うのは至って自然です。
もちろん個人・チームでのやりやすいように 納得感を持って進めていただければ良いとは思いますし、面倒に感じてしまう理由も人それぞれだと思います。
テストが面倒に感じる方は是非一度こういった観点からアプローチをかけ、少しでもテストを好きになって頂けたらと思います。
学んでみると テストは世間で思われているほど悪いやつじゃない と思えるかもしれません。