133 votes

Paramétrage des tests dans xUnit.net similaire à NUnit

Existe-t-il dans le framework xUnit.net des moyens similaires aux fonctionnalités suivantes de 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
}

Cela génère 8 tests distincts dans l'interface graphique de NUnit.

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

Cela permettra de générer 5 tests distincts et de comparer automatiquement les résultats ( Assert.Equal() ).

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

Cela permettra de générer 6 tests combinatoires. Inestimable.

Il y a quelques années, j'ai essayé xUnit et je l'ai adoré, mais il manquait ces fonctionnalités. Je ne peux plus m'en passer. Est-ce que quelque chose a changé ?

166voto

Enrico Campidoglio Points 17157

xUnité offre un moyen d'exécuter tests paramétrés par le biais de ce qu'on appelle théories des données . Le concept est équivalent à celui de NUnit, mais la fonctionnalité n'est pas aussi complète.

En voici un exemple :

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

Dans cet exemple, xUnit exécute la commande Should_format_the_currency_value_correctly test une fois pour chaque InlineDataAttribute en passant à chaque fois la valeur spécifiée comme argument.

Les théories des données sont une point d'extensibilité que vous pouvez utiliser pour créer de nouvelles façons d'exécuter vos tests paramétrés. La façon de procéder est la suivante création de nouveaux attributs qui inspectent et agissent éventuellement sur les arguments et la valeur de retour des méthodes de test.

Vous trouverez un bon exemple pratique de la façon dont les théories de données de xUnit peuvent être étendues dans le document suivant AutoFixture 's AutoData y InlineAutoData théories.

67voto

Sevenate Points 1116

Permettez-moi de donner un autre exemple, juste au cas où cela ferait gagner du temps à quelqu'un.

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

27voto

LewisM Points 620

Lors de votre première demande, vous pouvez suivre les exemples suivants ici .

Vous pouvez construire une classe statique contenant les données nécessaires à une collection de tests

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

Ensuite, en utilisant l'attribut MemberData, définissez le test comme suit

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

ou si vous utilisez C# 6.0,

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

Le premier argument de MemberDataAttribute vous permet de définir le membre que vous utilisez comme source de données, ce qui vous donne une certaine flexibilité en matière de réutilisation.

26voto

itim Points 89

Selon le cet article dans xUnit, vous disposez de trois options de "paramétrage" :

  1. InlineData
  2. ClassData
  3. Données sur les membres

Exemple InlineData

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

Exemple de ClassData

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

Exemple de données sur les membres

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

14voto

Adam Points 1984

J'ai trouvé une bibliothèque qui produit une fonctionnalité équivalente à celle de NUnit [Values] appelé Xunit.Combinatoire :

Il permet de spécifier des valeurs au niveau des paramètres :

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

Vous pouvez aussi lui demander implicitement de déterminer le nombre minimal d'invocations pour couvrir toutes les combinaisons possibles :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X