2012-01-31 13 views
1

ユニットテストの帳簿を読んで、状態ベースのテストロジックを理解しようとしました。件名の例では、ユニットテスト中のクラスで論理ミスを指摘する方法を確認する

public class Calculator 
{ 
    private int sum=0; 
    public void Add(int number) 
    { 
     sum+=number; 
    } 
    public int Sum() 
    { 
     int temp = sum; 
     sum = 0; 
     return temp; 
    } 
} 

及び本は、私たちはこれをテストする方法を示しなど:

[TestFixture] 
public class CalculatorTests 
{ 
    private Calculator calc; 

    [SetUp] 
    public void Setup() 
    { 
     calc = new Calculator(); 
    } 

    [Test] 
    public void Sum_NoAddCalls_DefaultsToZero() 
    { 
     int lastSum = calc.Sum(); 
     Assert.AreEqual(0,lastSum); 
    } 

    [Test] 
    public void Add_CalledOnce_SavesNumberForSum() 
    { 
     calc.Add(1); 
     int lastSum = calc.Sum(); 
     Assert.AreEqual(1,lastSum); 
    } 

    [Test] 
    public void Sum_AfterCall_ResetsToZero() 
    { 
     calc.Add(1); 
     calc.Sum(); 
     int lastSum = calc.Sum(); 
     Assert.AreEqual(0, lastSum); 
    } 

} 

だからこれまで、すべてが素晴らしいですが、私はそのクラスと同じくらい電卓クラスを書いmは言うことができます、と私は

のような方法を作りました
public int Sum() 
{ 

    return sum; 

} 


テストクラス

[TestFixture] 
public class CalculatorTests 
{ 
    private Calculator calc; 

    [SetUp] 
    public void Setup() 
    { 
     calc = new Calculator(); 
    } 

    [Test] 
    public void Sum_NoAddCalls_DefaultsToZero() 
    { 
     int lastSum = calc.Sum(); 
     Assert.AreEqual(0,lastSum); 
    } 

    [Test] 
    public void Add_CalledOnce_SavesNumberForSum() 
    { 
     calc.Add(1); 
     int lastSum = calc.Sum(); 
     Assert.AreEqual(1,lastSum); 
    } 
} 


ようレッツ私はそのためのユニットテストを書くとき、私はそれ以下のバグをキャッチどのようにコードを書くとき、私は良いリアライズをdidntの言いますか?バグは次のような2 addメソッドは、私はユニットテストを書くとき、その論理ミスを取得すると思いますそれでは、どのよう

add(1) 
add(23) 
sum() is 24 now 
add(11) 
add(12) 
sum() => will be 47 but it has to be 23. 

を処理した後、その和がゼロではありませんですので。(私はそれを書く場合はNUnitのは、私に教えてくれるがあります間違い)それから私は戻ってくると私はあなたが私が言うことをしようと何を理解してほしいポイントが表示され、私は

public int Sum() 
{ 
    int temp = sum; 
    sum = 0; 
    return temp; 
} 


のような電卓クラスを変更します。
ありがとうございます。

+0

かなり確実ではありませんの?あなたはそのテストを書く方法を尋ねていますか?または、あなたがそれらのためのテストを書くことができるように起こりうるすべての最悪の事例について、どのように考えていますか? –

答えて

2

基本的にすべてのエッジケースを見つけることはできません。ただし、コードの目的を明確にし、クリーンなコードを書くことができます。計算機がその合計を求めた後にその合計をリセットすることになっていれば、それはテストが必要な「スペック」の一部であり、誰かによって発明された「要件」なので、のテスト。

難しいことは、何かがコード化された方法で作成されたすべてのエッジケースです。私は候補コードの単体テストを書くコーディングのインタビューを行っていました。私は何かが働いたことを証明するための良いテストスイートがあると思った。しかし、私はすぐに、人々は、エッジケースをテストするのが難しいような方法でコードを作成できることを発見しました(何かが毎回動作するはずのようなものを9回目に失敗させるようなもの)。だから、主に、あなたがTDDのアドバイスに従っているなら、テストを書いてコードを書いて渡し、リファクタリングしてコードをきれいにしましょう。

これは魔法の弾丸ではありませんが、これは完璧なコードを書くことを可能にする魔法の数式ではありません。あなたは、あなたがしていることについて考えることを考えて考える必要があります。

+0

はい私は今、 –

1

それはあなたが基本的にはすでにテストケース持っているように聞こえる:

[Test] 
public void CallingSumResets() 
{ 
    var calc = new Calculator(); 
    calc.Add(10); 
    Assert.AreEqual(10, calc.Sum()); 
    Assert.AreEqual(0, calc.Sum()); 
} 

を、それが実際に加算を行うことだというテストは他のテストで行われることになる - これはただの後、あなたがSumを呼び出すことを初めてテストしています内部状態をリセットします。

+0

しかし、私はそれを予測する方法を尋ねます。もし私が失敗すると予測できるのであれば、前にコードと電卓のクラスで作ったことが本の例と同じになるでしょう。 –

+1

@mekici:あなたが意味することは本当にはっきりしません。テストするものを知るための魔法の式はありません。コードの目的について考える必要があります。そのためのテストを書く必要があります。 –

+0

mekici、あなたはそれを予測することはできません、ユニットテストはコーダーがコードを意図しているものを表します。合計を求めるときに和をリセットするケースについて考えることができない場合(このような大量のバグを引き起こす厄介なCommand Queryミックスアップ)、それをテストすることはできません。単体テストはあなたが考えるすべてのものを表します! –

1

このテストは失敗するはずです:

[Test] 
    public void Sum_AfterCall_ResetsToZero() 
    { 
     calc.Add(1); 
     calc.Sum(); 
     int lastSum = calc.Sum(); 
     Assert.AreEqual(0, lastSum); 
    } 

あなたはSum()が呼び出された後に合計をリセットするようにコードを変更するまで。しかし、ゲッターの合計をリセットするのではなく、別のメソッドClear()を作成することをお勧めします。

TDDは

  1. ステップは、あなたが電卓が何をしたいか考えてみてください。
  2. テストを作成します。
  3. テストに合格するコードを書きます。
+0

はい、どう思いますか?私はすでにコードで作ったことを知ることができ、本に書かれたような私の電卓のクラスを変更することができます。 –

+0

私の答えで「TDDステップ」をお読みください。フィーチャを実装する必要があるため、テストを記述します。 –

+0

お返事ありがとうございました –

1

私が正しく理解している場合、以下のサンプルコードはあなたの実装であり、バグがあります。正しい実装がしているように合計値をゼロにリセットせず、エラーを出します。あなたの質問は、これのためのユニットテストを書く方法です?

public int Sum() 
{ 

    return sum; 

} 

私が正しくあなたの質問を解釈してきたと仮定すると、あなたは、単に二回呼び出されたときに値がゼロであるかどうかを検出するテスト記述する必要があります:あなたが求めているもの

add(11) 
add(12) 
sum() => ignore result 
sum() => Should be zero 
関連する問題