簡體   English   中英

單元測試我如何指出被測類的邏輯錯誤

[英]Unit Testing how I think to point logical mistake on class which is under test

我正在閱讀《單元測試的藝術》一書,嘗試理解基於狀態的測試邏輯。在一個示例中,有一個計算器類,例如

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);
    }

}

因此,在此之前,一切都很好,但可以說,我正在寫一個與該類一樣多的計算器類,並且我制作了類似

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);
    }
}

可以說,當我編寫代碼以及為此編寫單元測試時,我並沒有很好地意識到如何捕捉以下錯誤? 因為錯誤是2加法之后的總和不會為零,如以下過程

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; 
}


我希望你能理解我的意思。
謝謝。

基本上,您不能確定所有邊緣情況。 但是,您可以指定要執行的代碼並編寫干凈的代碼。 如果一個計算器應該在求和之后重設它的和,那么這就是應該進行測試的“規范”的一部分,它是某人發明的“要求”,因此應該容易記住寫下一個測試。

困難的是通過某種編碼方式創建的所有極端情況。 我曾經進行過編程面試,在其中我會為候選代碼編寫單元測試。 我以為我有一套很好的測試來證明某些方法可行。 但是我很快發現,人們可以以難以引入邊緣測試的方式編寫代碼(例如某些事情在第9次失敗,並且似乎每次都應該起作用)。 因此,主要來說,如果您遵循TDD的建議,編寫測試,編寫使代碼通過的代碼,進行重構以使代碼整潔,那么您就不會出錯。

請記住,這不是魔術子彈,也不是允許您編寫完美代碼的魔術公式。 您仍然需要考慮考慮自己在做什么。

聽起來您基本上已經有了一個測試用例:

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

它實際執行加法的測試將在其他測試中進行-這只是測試,在您首次調用Sum之后,它將重置內部狀態。

該測試應失敗:

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

直到在調用Sum()之后更改代碼以重置總和。 但是,我寧願創建一個單獨的方法Clear()而不是重設getter中的和。

TDD步驟

  1. 想想您希望計算器做什么。
  2. 為此編寫一個測試。
  3. 編寫代碼以通過測試。

如果我理解正確,下面的示例代碼就是您的實現,並且有一個錯誤; 它不會像正確的實現那樣將總和值重置為零,從而產生錯誤。 您的問題是,如何為此編寫單元測試?

public int Sum()
{

  return sum;

}

假設我已正確解釋了您的問題,則只需編寫一個測試即可檢測第二次調用時該值是否為零:

add(11)
add(12)
sum() => ignore result
sum() => Should be zero

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM