はじめに
社内でt-wadaさんを招いてTDDオンライン研修を開催していただく機会がありました。そこで学ぶことがたくさんあったので復習をかねてまとめてみました。
(4年前にAngularで試した記事をかいていましたが、TDDに関するポイントのまとめがあまりにも少なかったので、今回はコードではなく、研修で得たポイントをメインにまとめたいと思います。)
環境
- Visual Studio 2019
- C#(xUnit)
TODOリストをかいてみる
今回の研修では整数閉区間を示すクラスを作成するというお題に対してTDDで作成していく、というワークショップがありました。
(おそらく題材はTDD Boot Camp 2020 Online #1と同じ)
さっそくお題を分解していったのですが、…???
t-wadaさんの講義でもおっしゃってましたが、このリストを作成するのが難しい…!
とりあえず、文章を読んでここはテストができそうと見分けのつく簡単なところだけ書き出し、テストコードを書き始めようとしたところで1度目のレビューを受けました。
実はこの進め方は正解みたいです。
TODOリストとはあくまでメモ。そのため何時間も考え込むというのはNGらしいです。テストを書き始めていくと気づいてくることもあります。
気づいたら都度TODOリストに追加していけばいいそうです。
テストコードをかく
上で私が分解したTODOリストのうち、「(整数閉区間は)指定した整数を含むかどうか判定できる」のテストについて今回はピックアップして紹介します。
最初に書いたテストコードがこちら
[Fact]
[Trait("(整数閉区間は)指定した整数を含むかどうか判定できる", "")]
public void 閉区間3_7に整数3を渡すと閉区間に含まれていると判定される()
{
Assert.True(closedRange.IsContain(3));
}
C#だと、「,」とか「[」とかが使えなくて、テストのメソッド名どうしようか困りました。
当然この状態ではまだ何も実装していないので、テストは失敗します。
茶番コード
1秒でも早くこのテストを成功させるように茶番のような実装をします
public bool IsContain(int num)
{
return true;
}
これでテストコードは正しいというテストもできました。
ちゃんと実装
茶番コードでのテスト成功を維持したままちゃんと実装します。
public bool IsContain(int num)
{
if (num <= _upperNumber && num >= _lowNumber)
{
return true;
}
else
{
return false;
}
}
リファクタリング
一行にまとめました。
public bool IsContain(int num)
{
return num <= _upperNumber && num >= _lowNumber;
}
今回のこのテストなのですが、境界値によって少なくとも4通りほどのテストが必要と考えられるかと思います。
この時私はすべての境界値のテストをしてからリファクタリングに入りたいと思ったのですが、実際どのタイミングでリファクタリングをするのがいいのか気になりました。
結論としてはリファクタリングのタイミングに正解はないとのことでした。
リファクタリングのタイミングとしては大きく2つあります。
- できたなと思ったタイミングでリファクタリングをする方法
- ごちゃついてきたなと思ったタイミングで、先にリファクタリングしてから増やしていく方法
t-wadaさん的にはまずごり押ししてからリファクタリングしていくのがおススメとのことです。何ができていくべきかとか見通しが立ってからリファクタリングした方が無駄がないからです。
ただ👆は、短時間で実装しきれるという自信がある場合に取る方法とのことです。
今何やったらいいかわからない…となったら、リファクタリングしてから先に進む方が良い場面もあるそうです。
つまり…
⇒ 両方のタイミングでリファクタリングができるようになろう!
ツリー構造にさせることで見やすくする大切さ
上でテストした内容は下の画像のような形でテストエクスプローラーに表示されます。
レビューすることや品質保証を考えると、このテスト内容をツリー構造にすることは大切になってきます。
私が以前所属していた部署ではソースコードをかけない方がテストをしていたため、このツリー構造によって、ツリーを見ただけで何のテストがされているか、実装されているか分かりそうだなという感想を抱きました。
TDDの不安が解消された、特に印象に残ったコメント
ずっと感じていた不安が解消された、私が個人的に印象に残った言葉を紹介します。
-
事前状態・入力・事後状態・出力 この4つを押さえればだいたいのテストはかける
-
実務では無理にテストからかく必要はない
ただ、テストコードとプロダクトコードをかく時間が近ければ近いほどいい。その日の内ならなお良し -
設計を固くしてテストを容易にする。テスト容易性が高いということは、よいアーキテクチャーといえる。
さいごに
直接講義をしていただけたことによって、モヤモヤが解消されたのが何よりも素晴らしかったなと思いました。
最後にt-wadaさんが質とスピードに関しての講義もあるというお話をされていたので、来年はそちらも触れたいところです。
(忘れないうちに年内にギリギリまとめられて良かった。良いお年を!)
参考
- 見てわかるテスト駆動開発(TDD Boot Camp 2020 Online #1 基調講演/ライブコーディング)
- テスト駆動開発 Kent Beck (著), 和田 卓人 (翻訳)