2013-05-13 3 views
2

В NUnit, есть ли способ указать, что Datapoint(s)Attribute должен применяться только к одной теории, если в одном классе TestFixture существует более одной теории?В NUnit, как я могу указать, что «DataPoint» применим только к одной Теории?

Причины Я спрашиваю, что я обычно следует модульному тестирование конвенции, где все методы тестового класса (CUT) тестируются на несколько [Test] метод свернутой в класс арматуры в одного теста, и теперь пытаюсь уйти от параметризованных тестов в направлении [Theory].

Или я должен просто продолжать использовать атрибуты Параметрированные тесты Values/Range/Random для таких тестов?

например. Ниже я хочу, чтобы гарантировать, что различные точки данных в теорию для дополнения и делят:

// C.U.T. 
public class BadMaths 
{ 
    public int BadAdd(int x, int y) { return x + y - 1; } 
    public int Divide(int x, int y) { return x/y; } 
} 

[TestFixture] 
public class BadMathsTest 
{ 
    // Ideally I want 2 x different datapoints - one for Add, and a different one for divide 
    [Datapoints] 
    private Tuple<int, int>[] _points = new Tuple<int, int>[] 
     { 
      new Tuple<int, int>(20, 10), 
      new Tuple<int, int>(-10, 0), 
     }; 

    [Theory] 
    public void AddTheory(Tuple<int, int> point) 
    { 
     Assume.That((long)point.Item1 + (long)point.Item2 < (long)int.MaxValue); 
     Assert.That(point.Item1 + point.Item2, Is.EqualTo(new BadMaths().BadAdd(point.Item1, point.Item2))); 
    } 

    [Theory] 
    public void DivideTheory(Tuple<int, int> point) 
    { 
     Assume.That(point.Item2 != 0); // Seems the best I can do - test is inconclusive 
     Assert.That(point.Item1/point.Item2, Is.EqualTo(new BadMaths().Divide(point.Item1, point.Item2))); 
    } 

} 

Edit

Пример, приведенный выше, не является хорошим примером использования Theory - это лучше подходит до TestCaseSource, а с новым оператором Roslyn nameof не требуются атрибуты [DataPoints] или [UsedImplicitly] на исходные данные.

[TestCaseSource(nameof(_points)] 
    public void EnsureAddPoints(Tuple<int, int> point) 
    { .... 
+0

оказывается, что [TestCaseSource] (http://www.nunit.org/index.php?p=testCaseSource&r=2.5) также может использоваться для теорий (например, '[TestCaseSource (" _ pointsForAdd ")]'), a Кажется, что требуется точное соответствие подписи. Вышеприведенный пример не является хорошим примером использования Теории, поскольку «Tuple» связывает x и y зависимо от – StuartLC

+0

Подобно [PropertyNata] XUnit (http://www.tomdupont.net/2012/04/xunit-theory-data- driven-unit-test.html) – StuartLC

ответ

3

Я не верю, что есть какой-либо прямой способ просить NUnit использовать разные точки данных одного и того же типа для различных теорий. Однако есть два возможных пути вы можете работать вокруг:

Первый заключается в использовании различных классов TextFixture для испытаний, которые требуют различных значений DataPoint:

[TestFixture] 
public class BadMathsAdditionTest 
{ 
    // Ideally I want 2 x different datapoints - one for Add, and a different one for divide 
    [Datapoints] 
    private Tuple<int, int>[] _points = new Tuple<int, int>[] 
    { 
     new Tuple<int, int>(20, 10), 
     new Tuple<int, int>(-10, 0), 
    }; 

    // add tests that use these datapoints 
    [Theory] 
    public void AddTheory(Tuple<int, int> point) 
    { 
     Assume.That((long)point.Item1 + (long)point.Item2 < (long)int.MaxValue); 
     Assert.That(point.Item1 + point.Item2, Is.EqualTo(new BadMaths().BadAdd(point.Item1, point.Item2))); 
    } 

} 

[TestFixture] 
public class BadMathsDivisionTest 
{ 

    // Ideally I want 2 x different datapoints - one for Add, and a different one for divide 
    [Datapoints] 
    private Tuple<int, int>[] _points = new Tuple<int, int>[] 
    { 
     new Tuple<int, int>(20, 10), 
    }; 

    // add test that use these datapoints 

} 

Второй способ требует немного больше работы, но, возможно, дает более читаемый код, чтобы обернуть каждый набор DataPoint в других структурах, как это:

// C.U.T. 
public class BadMaths 
{ 
    public int BadAdd(int x, int y) { return x + y - 1; } 
    public int Divide(int x, int y) { return x/y; } 
} 

[TestFixture] 
public class BadMathsTest 
{ 

    public struct AdditionData 
    { 
     public int First { get; set; } 
     public int Second { get; set; } 
    } 
    [Datapoints] 
    private AdditionData[] _points = new AdditionData[] 
    { 
     new AdditionData{First=20, Second=10}, 
     new AdditionData{First=-10, Second=0} 
    }; 


    public struct DivisionData 
    { 
     public int First { get; set; } 
     public int Second { get; set; } 
    } 

    [Datapoints] 
    private DivisionData[] _points2 = new DivisionData[] 
    { 
     new DivisionData{First=20, Second=10}, 
    }; 

    [Theory] 
    public void AddTheory(AdditionData point) 
    { 
     Assume.That((long)point.First + (long)point.Second < (long)int.MaxValue); 
     Assert.That(point.First + point.Second, Is.EqualTo(new BadMaths().BadAdd(point.First, point.Second))); 
    } 

    [Theory] 
    public void DivideTheory(DivisionData point) 
    { 
     Assume.That(point.Second != 0); // Actually you probably want to keep this condition anyway. Second==0 would be a separate test 
     Assert.That(point.First/point.Second, Is.EqualTo(new BadMaths().Divide(point.First, point.Second))); 
    } 

} 
+0

Без проблем, рад, что это помогло. –

+0

Если ответ был полезен, можете ли вы отметить его как ваш принятый ответ? –

+1

Я принял, но все равно хотел бы увидеть, есть ли декларативный способ ограничить цель источника данных :) – StuartLC

 Смежные вопросы

  • Нет связанных вопросов^_^