前回の投稿では、FizzBuzz問題を題材として取り上げ、テストコードを使ってテスト駆動開発をするのに挑戦しました。
テスト駆動開発、私はJavaを習いたてということもあり、まだまだ未知なものだなという印象でした。
一方、私はテストエンジニアとして長らく従事しているので、FizzBuzz問題ではどのようなテストケースを作れば良いのか、少し頭を悩ませました。
シンプル且つ、カバレッジの広いものを作るべきだと思うのですが、そこにはテストのパターンをきちんと考えることが必要だと思ったからです。
テストを考える時、プログラムの処理を考える必要があるかどうか
テストタイプにも依ると思うのですが、例えばFizzBuzz問題で考える時に、
- 3の倍数はFizzを返す
- 5の倍数はBuzzを返す
というものと、
- 15の倍数はFizzBuzzを返す
これら、どっちを先に処理するか、プログラマーの頭の中を考える必要があるかな、と思いました。
というのも、私はJavaでプログラミングした時、後者を先に書きました。
15の倍数でFizzBuzzを通過するケースの時は、3や5の倍数ではあるけれどそちらは通過してしまうから、考慮しなくても良い、つまりケースとして、テスト条件に45を選んだ時、FizzBuzzを返すこと、は期待結果として設けるべきで、FizzやBuzzを返さないことというものは期待結果として選択しない、ということになります。
そもそも1つの結果しか返さないこと、というのが仕様として明記されていれば、↑こんな考え方でも良いでしょうけど、「1つの結果しか返さない」という仕様は記載されていない場合は、「結果が1つしか出てこないこと」というのを期待値として挙げておく必要があるのかもしれないです。
その辺がプログラミング中に分からなくて、ちょっともやもやしました。
同値クラスで分ける場合
私がJSTQBで理解した同値クラスというのは、結果のまとまりで見る、ということでした。
なので、
- 数字をそのまま返す
- Fizzを返す
- Buzzを返す
- FizzBuzzを返す
- エラーを返す
この5つをそれぞれのまとまりと見立て、適当なテスト条件をピックアップすれば良いのか、と思います。
- 数字をそのまま返す:1、2、99、100
- Fizzを返す:3、39
- Buzzを返す:5、20
- FizzBuzzを返す:15、45
- エラーを返す:0、101、☆
FizzBuzz問題で難しいのは、45です。3の倍数でもあるし、5の倍数、15の倍数でもあるような数字です。これはどっかの同値クラスでまとめてテストしちゃうのが手っ取り早いのでしょうけど、Fizzを返すこと、というテストの目的に対して3を入れて正解を見るパターンと、45を入れて不正解を見るパターン、両方やるのが一番カタいのかなぁと思います。
どっちみち15の同値クラスで45を見るのだから、3の同値クラスでやる必要はないだろう、というのはテストアプローチとして(効率的にやっちゃおうぜ的な考え方)は良いのでしょうけど、いったん全部出してみようぜ、っていう時には忘れずに盛り込んでおくべきだと思います。