2013-05-13 60 views
2

NUnit,有沒有什麼方法可以表明Datapoint(s)Attribute只應用於一個理論,如果在同一TestFixture類有多個理論?在NUnit中,我怎麼能指出'數據點'只適用於一個理論?

原因我想問的是,我通常遵循一個單元測試慣例,其中一個測試類(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))); 
    } 

} 

編輯

上面這個例子是不是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 2015-01-20 07:16:38

+0

類似於[XUnit的PropertyData](http://www.tomdupont.net/2012/04/xunit-theory-data- driven-unit-test.html) – StuartLC 2015-05-06 07:31:04

回答

3

我不相信有要求NUnit的使用相同類型不同的理論不同的數據點的任何直接的方式。然而,有兩種可能的方法可以解決:

首先是使用不同TextFixture類爲需要不同的數據點值測試:

[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 

} 

第二種方法需要多一點的工作,但可以說是給更可讀代碼是包裝每個數據點集合在不同的結構,例如:

// 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

沒問題,很高興幫助。 – 2013-06-04 19:29:30

+0

如果答案有用,您能否將其標記爲您接受的答案? – 2013-06-11 23:09:05

+1

我已經接受,但仍然想看看是否有聲明的方式來限制數據源的目標:) – StuartLC 2013-06-12 04:16:40

相關問題