Модульное тестирование, как я думаю, чтобы указать логическую ошибку на классе, который тестируется - PullRequest
1 голос
/ 31 января 2012

Я читаю книгу «Искусство модульного тестирования» и пытаюсь понять логику тестирования на основе состояния. В примере с предметом был класс калькулятора, например

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.

Так, как я думаю, чтобы получить эту логическую ошибку, когда я пишу модульный тест.это ошибка) тогда я вернусь и увижу точку, и я изменю класс калькулятора как

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


Я надеюсь, вы понимаете, что я пытаюсь сказать.
Спасибо.

Ответы [ 4 ]

2 голосов
/ 31 января 2012

По сути, вы не можете точно найти все крайние случаи.Тем не менее, вы можете указать, что вы собираетесь делать, и написать чистый код.Если калькулятор должен сбрасывать свою сумму после запроса ее суммы, то это часть «спецификации», для которой должен быть тест, его «требование», придуманное кем-то, так что должно быть легко запомнить, чтобы написатьtest для.

Более сложная вещь - это все крайние случаи, созданные способом кодирования чего-либо.Раньше я проводил собеседования по кодированию, где я писал тесты для кода кандидатов.Я думал, что у меня есть хороший набор тестов, чтобы доказать, что что-то работает.Но я быстро обнаружил, что люди могут кодировать вещи способами, которые затрудняют тестирование для крайних случаев (например, что-то не получится в 9-й раз, когда оно делает что-то, что должно работать каждый раз).Таким образом, в основном, если вы последуете совету TDD, напишете тест, напишите код, чтобы он прошел, рефакторинг, чтобы сделать код чистым, вы не ошибетесь слишком далеко.

и помните, что этоне волшебная пуля, это не волшебная формула, которая позволяет вам писать идеальный код.Вам все еще нужно думать думать думать о том, что вы делаете.

1 голос
/ 31 января 2012

Если я вас правильно понимаю, приведенный ниже пример кода является вашей реализацией и содержит ошибку; Он не сбрасывает значение суммы в ноль, как это делает правильная реализация, выдавая ошибку. Ваш вопрос, как написать для этого модульный тест?

public int Sum()
{

  return sum;

}

Предполагая, что я правильно интерпретировал ваш вопрос, вы должны просто написать тест, который определяет, является ли значение нулевым при повторном вызове:

add(11)
add(12)
sum() => ignore result
sum() => Should be zero
1 голос
/ 31 января 2012

Этот тест не пройден:

   [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. Написать код для прохождения теста.
1 голос
/ 31 января 2012

Похоже, у вас уже есть тестовый пример:

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

Тест, который фактически выполняет добавление, будет выполнен в других тестах - это просто проверка того, что после первого вызова Sum происходит сброс внутреннего состояния.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...