読書記録 C#実践開発手法 第1部-第4章

思いっきり更新日を間違えていました。

今回は第4章 ユニットテストに関する読書記録です、と言いたいところですが、ここを読んでいてもテスト駆動開発についてよくわからなかったところがあって、それを補間するために別の本を読み始めています。

ひとまずは読んだ部分について記録していきます。

ユニットテストテスト駆動開発

テスト駆動開発は実際のコードに先駆けてテストコードを作成して、そのテストコードを正しく実行できるような
コードを記述していく、という流れを繰り返していく開発手法です。

先にテストコードを書くことで次のような恩恵を得ることができます。

  • コードとテストコードの協調性が保たれやすくなる
  • リファクタ時に混入するバグの早期発見に役立つ
  • 実装中のクラスをテストすることでよりよい設計が思いつく

では、最初のテストコードの例を示します。

[TestClass]
public class ATest
{
    [TestMethod]
    public void AddNum()
    {
        //テスト対象となるクラスの呼び出し
        var num = new NumClass();
        
        //テスト対象クラスの実行
        num.add(10);

       //期待する動作の記述
       Assert.AreEqual(10,num.get());
    }
}
    

このテストではNumClassにたいして次のことを期待しています。

  • 引数を要求しないコンストラクタを実行できる
  • メンバ変数に値を持ち、初期値は0である
  • 整数値を受け取るaddメソッドでメンバ変数を変更できる
  • getterを持つ

ひとまずはこの程度でとどめておき、これを実行できるようなクラスを作成します。
ここでテスト駆動開発の特徴としては、まずこのテストを失敗するようなコードを作成します。

public class NumClass
{
    public int num;

    public NumClass(){}

    public void add(int a){}

    public int get(){return num;}
}

とりあえずこんな感じのコードを書いておけば、コンパイルエラーを出すことなく作成済みのテストコードに通すことができます。

もちろんテストには失敗しますが、この失敗によって次に修正すべき点が見つかります。
この程度であれば一気に修正して良いとは思いますが、最小限の労力でこのテストを完遂しようとするならば

public class NumClass
{
    public int num;

    public NumClass(){}

    public void add(int a){}

    public int get(){return 10;}
}

このようにgetterでテストが要求する値を返すようにする事になります。

ここまでで

  • NumClassが引数を要求しないコンストラクタを持つ
  • getterを持つ

ことには自信を持つことができます。
そこで次のテストとして

[TestClass]
public class ATest
{
    [TestMethod]
    public void Add2Nums()
    {
        //テスト対象となるクラスの呼び出し
        var num = new NumClass();
        
        //テスト対象クラスの実行
        num.add(10);
        num.add(15);

       //期待する動作の記述
       Assert.AreEqual(25,num.get());
    }
}
    

次のテストコードを追加します。
テストコードの追加によって定数を返すgetterでは全てのテストに対処しきれなくなります。
なので、本格的にaddメソッドを実装して正しく計算が実行できるようなクラスとしていきます。

これ以上のコードは省略しますが、テスト駆動開発ではとりあえず実装してからリファクタリング、という流れになります。

先程の例であれば、少なくとも正常な整数が入力されれば計算可能であることに自信が持てますので

  • エラー入力への対応
  • 他の演算の追加
  • メンバ変数のアクセス権の変更

などのリファクタリングを実行して、既存のテストコードを通せることを確認します。

こうすることでリファクタ時にバグが混入してもテストコードを短い間隔で実行することになるので早急なバグの発見が可能になります。

まとめ

読書記録というよりもテスト駆動開発についての説明になってしまいました。

現時点でわかっていないこととして

  • 設計の変更について言及しているが予めどの程度設計してから開発をすすめるのか
  • 過去のテストコードの修正はどの程度許容されているのか

等が挙げられます。

後は感想になります。

個人的に仕事でもテスト駆動開発を実践してますが、結構開発が楽しくなっているように感じます。

やはり自分の進捗が可視化されるとやる気が出てきますし、テストコードを精査することでどの程度自分のコードができているのかがわかります。
これからもテスト駆動開発についての勉強は進めていくので、何かあればまた記事を作りたいと思います。

次回の更新は3/23を予定しています。