Frage Testen Sie die Parametrisierung in xUnit.net ähnlich wie NUnit


Gibt es irgendwelche Mittel im xUnit.net-Framework, die den folgenden Features von NUnit ähnlich sind?

[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
}

Dies erzeugt 8 separate Tests in 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"; }

Dies erzeugt 5 separate Tests und vergleicht automatisch die Ergebnisse (Assert.Equal()).

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

Dies erzeugt 6 kombinatorische Tests. Unbezahlbar.

Vor ein paar Jahren habe ich versucht, xUnit und liebte es, aber es fehlte diese Funktionen. Kann nicht ohne sie leben. Hat sich etwas verändert?


75
2018-02-02 10:07


Ursprung


Antworten:


xUnit bietet eine Möglichkeit zu laufen parametrisierte Tests durch etwas genanntes Datentheorien. Das Konzept entspricht dem in NUnit, aber die Funktionalität, die Sie aus der Box herausholen, ist nicht so vollständig.

Hier ist ein Beispiel:

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

In diesem Beispiel führt xUnit den Befehl Should_format_the_currency_value_correctly einmal testen für jeden InlineDataAttribute Jedes Mal übergeben Sie den angegebenen Wert als Argument.

Datentheorien sind ein Erweiterbarkeitspunkt mit denen Sie neue Möglichkeiten zum Ausführen Ihrer parametrisierten Tests erstellen können. Die Art und Weise, wie dies gemacht wird, ist durch neue Attribute erstellen die die Argumente und den Rückgabewert der Testmethoden inspizieren und optional bearbeiten.

Sie können ein gutes praktisches Beispiel dafür finden, wie die Datentheorien von xUnit erweitert werden können AutoFixtureist es AutoDaten und InlineAutoDaten Theorien.


100
2018-02-02 10:21



Lass mich hier noch eine Probe werfen, nur für den Fall, dass es jemandem Zeit spart.

[Theory]
[InlineData("goodnight moon", "moon", true)]
[InlineData("hello world", "hi", false)]
public void Contains(string input, string sub, bool expected)
{
    var actual = input.Contains(sub);
    Assert.Equal(expected, actual);
}

39
2018-04-11 00:48



Bei Ihrer ersten Anfrage können Sie den gefundenen Beispielen folgen Hier.

Sie können eine statische Klasse erstellen, die die für eine Testsammlung erforderlichen Daten enthält

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; }
        }
    }
}

Definieren Sie dann mithilfe des MemberData-Attributs den Test als solchen

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);
    }
}

oder wenn Sie C # 6.0 verwenden,

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

Das erste Argument von MemberDataAttribute ermöglicht es Ihnen, das Mitglied zu definieren, das Sie als Datenquelle verwenden, sodass Sie bei der Wiederverwendung ein hohes Maß an Flexibilität haben.


13
2017-12-19 13:03



Ich habe eine Bibliothek gefunden, die die gleiche Funktionalität wie NUnit bietet [Values] Attribut aufgerufen Xunit.Combinatorial:

Hier können Sie Werte auf Parameterebene angeben:

[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
}

Oder Sie können implizit die minimale Anzahl von Aufrufen berechnen, um alle möglichen Kombinationen abzudecken:

[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
}

4
2018-05-14 21:23



Ich nahm hier alle Antworten auf und nutzte zusätzlich XUnits TheoryData<,> generische Typen, um mir einfache Datendefinitionen für das 'MemberData'-Attribut in meinem Test zu geben, wie in diesem Beispiel:

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


Hinweis: Verwenden von VS2017 (15.3.3), C # 7 und XUnit 2.2.0 für .NET Core


3
2017-09-05 09:23



Gemäß Dieser Artikel In xUnit haben Sie drei "Parametrisierungs" -Optionen:

  1. InlineDaten
  2. Klassendaten
  3. Mitgliedsdaten

InlineData Beispiel

[Theory]
[InlineData(1, 2)]
[InlineData(-4, -6)]
[InlineData(2, 4)]
public void FooTest(int value1, int value2)
{
    Assert.True(value1 + value2 < 7)
}

ClassData Beispiel

public class BarTestData : IEnumerable<object[]>
{
    public IEnumerator<object[]> GetEnumerator()
    {
        yield return new object[] { 1, 2 };
        yield return new object[] { -4, -6 };
        yield return new object[] { 2, 4 };
    }

    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}


[Theory]
[ClassData(typeof(BarTestData))]
public void BarTest(int value1, int value2)
{
    Assert.True(value1 + value2 < 7)
}

MemberData Beispiel

[Theory]
[MemberData(nameof(BazTestData))]
public void BazTest(int value1, int value2)
{
    Assert.True(value1 + value2 < 7)
}

public static IEnumerable<object[]> BazTestData => new List<object[]>
    {
        new object[] { 1, 2 },
        new object[] { -4, -6 },
        new object[] { 2, 4 },
    };

1
2017-07-04 11:25