2012-02-02 11 views
67

Czy istnieją jakieś metody w strukturze xUnit.net podobne do następujących cech NUnit?Parametryzacja testu w xUnit.net podobna do NUnit

[Test, TestCaseSource("CurrencySamples")] 
public void Format_Currency(decimal value, string expected){} 

static object[][] CurrencySamples = new object[][] 
{ 
    new object[]{ 0m, "0,00"}, 
    new object[]{ 0.0004m, "0,00"}, 
    new object[]{ 5m, "5,00"}, 
    new object[]{ 5.1m, "5,10"}, 
    new object[]{ 5.12m, "5,12"}, 
    new object[]{ 5.1234m, "5,12"}, 
    new object[]{ 5.1250m, "5,13"}, // round 
    new object[]{ 5.1299m, "5,13"}, // round 
} 

ten generuje 8 oddzielnych testów Nunit GUI

[TestCase((string)null, Result = "1")] 
[TestCase("", Result = "1")] 
[TestCase(" ", Result = "1")] 
[TestCase("1", Result = "2")] 
[TestCase(" 1 ", Result = "2")] 
public string IncrementDocNumber(string lastNum) { return "some"; } 

To spowoduje 5 oddzielnych testów automatycznie porównanie wyników (Assert.Equal()).

[Test] 
public void StateTest(
    [Values(1, 10)] 
    int input, 
    [Values(State.Initial, State.Rejected, State.Stopped)] 
    DocumentType docType 
){} 

Spowoduje to wygenerowanie 6 testów kombinatorycznych. Bezcenny.

Kilka lat temu próbowałem xUnit i podobało mi się, ale brakowało mu tych funkcji. Nie można bez nich żyć. Czy coś się zmieniło?

Odpowiedz

90

xUnit oferuje możliwość uruchomienia parametryzowane testy przez coś zwane teorie danych. Koncepcja jest równoważna z tą, którą można znaleźć w NUnit, ale funkcjonalność, z której wychodzi się z pudełka, nie jest tak kompletna.

Oto przykład:

[Theory] 
[InlineData("Foo")] 
[InlineData(9)] 
[InlineData(true)] 
public void Should_be_assigned_different_values(object value) 
{ 
    Assert.NotNull(value); 
} 

W tym przykładzie xUnit będzie uruchomić test Should_format_the_currency_value_correctly raz dla każdego InlineDataAttribute każdym przejściu określonej wartości jako argumentu.

Teorie danych to punkt rozszerzalności, za pomocą których można tworzyć nowe sposoby uruchamiania sparametryzowanych testów. Sposób ten jest wykonywany przez tworząc nowe atrybuty, które sprawdzają i opcjonalnie działają na argumenty i zwracają wartość metod testowych.

Można znaleźć dobry praktyczny przykład, jak teorie danych xUnit może zostać przedłużony w AutoFixture „s AutoData i InlineAutoData teorii.

+3

Wydaje się, że jest [Brak] (http://stackoverflow.com/questions/507528/use -decimal-values-as-attribute-params-in-c) do użycia literały dziesiętne jako parametry atrybutów. –

+1

@RubenBartelink link nie zostanie znaleziony. Przejdź tutaj: http://blog.benhall.me.uk/2008/01/introduction-to-xunit-net-extensions/ –

+9

Będziesz potrzebował _xUnit.net: Extensions_ (pakiet NuGet) lub w inny sposób '[ Teoria] 'atrybut nie jest dostępny. – Virtlink

34

Pozwól mi rzucić jeszcze jedną próbkę tutaj, na wypadek, gdyby ktoś zaoszczędził trochę czasu.

+0

Czy zapomniałeś nawiasu zamykającego w drugiej linii? – cs0815

+0

@csetzkorn ci prawo, dzięki! – Sevenate

10

Na swoją pierwszą prośbę możesz wykonać następujące przykłady: here.

Można skonstruować statyczną klasę zawierającą dane niezbędne do zbioru testów

using System.Collections.Generic; 

namespace PropertyDataDrivenTests 
{ 
    public static class DemoPropertyDataSource 
    { 
     private static readonly List<object[]> _data = new List<object[]> 
      { 
       new object[] {1, true}, 
       new object[] {2, false}, 
       new object[] {-1, false}, 
       new object[] {0, false} 
      }; 

     public static IEnumerable<object[]> TestData 
     { 
      get { return _data; } 
     } 
    } 
} 

Następnie, przy użyciu atrybutu MemberData zdefiniować test jako taki

public class TestFile1 
{ 
    [Theory] 
    [MemberData("TestData", MemberType = typeof(DemoPropertyDataSource))] 
    public void SampleTest1(int number, bool expectedResult) 
    { 
     var sut = new CheckThisNumber(1); 
     var result = sut.CheckIfEqual(number); 
     Assert.Equal(result, expectedResult); 
    } 
} 

lub jeśli jesteś przy użyciu C# 6.0,

[Theory] 
[MemberData(nameof(PropertyDataDrivenTests.TestData), MemberType = typeof(DemoPropertyDataSource))] 

Pierwszy argument MemberDataAttribute pozwala na d efine członek, którego używasz jako źródła danych, więc masz sporo elastyczności w ponownym użyciu.

3

Znalazłem bibliotekę, która produkuje równoważną funkcjonalność [Values] atrybutu NUnit w nazwie Xunit.Combinatorial:

To pozwala określić wartości parametrów poziomu:

[Theory, CombinatorialData] 
public void CheckValidAge([CombinatorialValues(5, 18, 21, 25)] int age, 
    bool friendlyOfficer) 
{ 
    // This will run with all combinations: 
    // 5 true 
    // 18 true 
    // 21 true 
    // 25 true 
    // 5 false 
    // 18 false 
    // 21 false 
    // 25 false 
} 

Albo można niejawnie mieć to zorientować się minimalne liczba inwokacji obejmujących wszystkie możliwe kombinacje:

[Theory, PairwiseData] 
public void CheckValidAge(bool p1, bool p2, bool p3) 
{ 
    // Pairwise generates these 4 test cases: 
    // false false false 
    // false true true 
    // true false true 
    // true true false 
} 
1

Wziąłem na pokład wszystkie odpowiedzi tutaj nd dodatkowo wykorzystał TheoryData<,> typów generycznych xUnit, aby dać mi prosty, czytelny i definicje danych bezpieczny typ dla atrybutu „MemberData” na moim teście, jak na tym przykładzie:

/// must be public & static for MemberDataAttr to use 
public static TheoryData<int, bool, string> DataForTest1 = new TheoryData<int, bool, string> { 
    { 1, true, "First" }, 
    { 2, false, "Second" }, 
    { 3, true, "Third" } 
}; 

[Theory(DisplayName = "My First Test"), MemberData(nameof(DataForTest1))] 
public void Test1(int valA, bool valB, string valC) 
{ 
    Debug.WriteLine($"Running {nameof(Test1)} with values: {valA}, {valB} & {valC} "); 
} 

Three tests runs observed from test explorer for 'My First Test'


NB Stosując VS2017 (15.3.3), C# 7, & xUnit 2.2.0 NET Rdzeń

Powiązane problemy