Тесты на большее количество входов - PullRequest
1 голос
/ 03 сентября 2010

Я использую MSTest для тестирования, и когда я хочу применить больше входных данных, тогда тест выглядит следующим образом:

[TestMethod]
public void SumTest()
{
  // data to test
  var items = new [] {
    new { First = 1, Second = 1, Expected = 2 },
    new { First = -1, Second = 1, Expected = 0 },
    new { First = 1, Second = 2, Expected = 3 },
    new { First = 1, Second = -1, Expected = 0 },
  };

  ICalculator target = GetSum(); // can be in the loop body

  foreach(var item in items)
  {
    var actual = target.Sum(item.First, item.Second);
    Assert.AreEqual(item.Expected, actual);
  }
}

Я чувствую, что этот вид тестирования не является правильным способом.Т.е. я хотел бы разделить тестирование, генерацию данных и само тестирование.

Я знаю, что в MSTest есть поддержка "тест на основе данных", но мне этого недостаточно:

  1. Коллекция items не может быть сгенерирована с использованием какого-либо алгоритма.
  2. Я не могу использовать непримитивные типы.

Так что вы предлагаете для такого рода тестов?

Мне бы хотелось иметь что-то подобное, но я не уверен, что это правильный путь и поддерживает ли какой-либо каркас тестирования этот сценарий.

[TestData]
public IEnumerable<object> SumTestData()
{
  yield return new { First = 1, Second = 1, Expected = 2 };
  yield return new { First = -1, Second = 1, Expected = 0 };
  yield return new { First = 1, Second = 2, Expected = 3 };
  yield return new { First = 1, Second = -1, Expected = 0 };
}

[TestMethod(DataSource="method:SumTestData")]
public void SumTest(int first, int second, int expected)
{
  // this test is runned for each item that is got from SumTestData method
  // (property -> parameter mapping is no problem)
  ICalculator target = GetSum();
  var actual = target.Sum(first, second);
  Assert.AreEqual(expected, actual);
}

Ответы [ 3 ]

3 голосов
/ 03 сентября 2010

NUnit поддерживает этот сценарий:

public static IEnumerable SumTestData() {
    return new List<TestCaseData> {
        new TestCaseData( 1,  1,  2),
        new TestCaseData(-1,  1,  0),
        new TestCaseData( 1,  2,  3),
        new TestCaseData( 1, -1,  0)
    };
}

[Test]
[TestCaseSource("SumTestData")]
public void SumTest(int first, int second, int expected) {
}

Параметры могут быть любого типа. Конструктор TestCaseData принимает массив параметров param, поэтому вам просто нужно убедиться, что ваши тестовые значения могут быть преобразованы в фактические типы параметров метода тестирования.

Метод непористых параметризованных испытаний (автор @RobertKoritnik)

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

public static IEnumerable SumTestData() {
    yield return new TestCaseData( 1,  1).Returns(2);
    yield return new TestCaseData(-1,  1).Returns(0);
    yield return new TestCaseData( 1,  2).Returns(3);
    yield return new TestCaseData( 1, -1).Returns(0);
}

[Test]
[TestCaseSource("SumTestData")]
public int SumTest(int first, int second)
{
    return Sum(first, second);
}
2 голосов
/ 03 сентября 2010

http://xunit.codeplex.com/ может делать такие вещи: см. Подробности атрибута [Теория] http://xunit.codeplex.com/wikipage?title=Comparisons

выглядит примерно так:

        [Theory]
        [InlineData(SourceType.BackupFile, "RestoreMode")]
        [InlineData(SourceType.ExistingDatabase, "MonitorMode")]
        public void ShouldShowProperReportDependentOnSource(SourceType sourceType, string commandMode)
        {...}
0 голосов
/ 03 сентября 2010

MSTest (и NUnit) позволяет идентифицировать методы, которые выполняются либо перед каждым тестом, либо при создании экземпляра класса теста.

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

В MSTest вы можете использовать TestInitializeAttribute, чтобы идентифицировать метод, который запускается перед каждым тестом, и вы можете использовать ClassInitializeAttribute, чтобы идентифицировать метод, который запускается один раз при создании класса теста.

...