Skip to content

Latest commit

 

History

History
367 lines (287 loc) · 12.5 KB

File metadata and controls

367 lines (287 loc) · 12.5 KB

Xunit V3 Parameterised Tests

UseParameters()

UseParameters() controls what parameters are used when naming files.

Verify.XunitV3 Automatically detect the method parameters for built in types (string, int, bool etc), but for complex parameters UseParameters() is required.

Usage:

For the above scenarios where parameters are not automatically detected:

[Theory]
[InlineData("Value1")]
[InlineData("Value2")]
public Task UseParametersUsage(string arg)
{
    var somethingToVerify = $"{arg} some text";
    return Verify(somethingToVerify)
        .UseParameters(arg);
}

snippet source | anchor

If not all parameters are required, a subset can be passed in. In this scenario, the parameters passed in will match with the method parameter names from the start. For example the following will result in a file named ParametersSample.UseParametersSubSet_arg1=Value1_arg2=Value2.verified.txt

[Theory]
[InlineData("Value1", "Value2", "Value3")]
public Task UseParametersSubSet(string arg1, string arg2, string arg3)
{
    var somethingToVerify = $"{arg1} {arg2} {arg3} some text";
    return Verify(somethingToVerify)
        .UseParameters(arg1, arg2);
}

snippet source | anchor

If the number of parameters passed to UseParameters() is greater than the number of parameters in the test method, an exception will be thrown.

InlineData

[Theory]
[InlineData("Value1")]
[InlineData("Value2")]
public Task InlineDataUsage(string arg) =>
    Verify(arg);

snippet source | anchor

MemberData

[Theory]
[MemberData(nameof(GetData))]
public Task MemberDataUsage(string arg) =>
    Verify(arg);

public static IEnumerable<object[]> GetData()
{
    yield return
    [
        "Value1"
    ];
    yield return
    [
        "Value2"
    ];
}

snippet source | anchor

Unknown parameter types

For unknown types the parameter information cannot be derived. In these scenarios ToString() is used. To use custom text for a parameter use NameForParameter().

public class ComplexParametersSample
{
    [ModuleInitializer]
    public static void Initialize()
    {
        VerifierSettings.NameForParameter<ComplexData>(_ => _.Value);
        VerifierSettings.NameForParameter<ComplexStructData>(_ => _.Value);
    }

    [Theory]
    [MemberData(nameof(GetData))]
    public Task ComplexMemberData(ComplexData arg)
    {
        var settings = new VerifySettings();
        settings.UseParameters(arg);
        return Verify(arg, settings);
    }

    [Theory]
    [MemberData(nameof(GetData))]
    public Task ComplexMemberDataFluent(ComplexData arg) =>
        Verify(arg)
            .UseParameters(arg);

    [Theory]
    [MemberData(nameof(GetData))]
    public Task ComplexMemberNullableData(ComplexData arg)
    {
        var settings = new VerifySettings();
        settings.UseParameters(arg);
        return Verify(arg, settings);
    }

    [Theory]
    [MemberData(nameof(GetData))]
    public Task ComplexMemberNullableDataFluent(ComplexData arg) =>
        Verify(arg)
            .UseParameters(arg);

    public static IEnumerable<object[]> GetData()
    {
        yield return
        [
            new ComplexData("Value1")
        ];
        yield return
        [
            new ComplexData("Value2")
        ];
    }

    public record ComplexData(string Value);

    [Theory]
    [MemberData(nameof(GetStructData))]
    public Task ComplexMemberStructData(ComplexStructData arg)
    {
        var settings = new VerifySettings();
        settings.UseParameters(arg);
        return Verify(arg, settings);
    }

    [Theory]
    [MemberData(nameof(GetStructData))]
    public Task ComplexMemberStructDataFluent(ComplexStructData arg) =>
        Verify(arg)
            .UseParameters(arg);

    [Theory]
    [MemberData(nameof(GetStructData))]
    public Task ComplexMemberNullableStructData(ComplexStructData arg)
    {
        var settings = new VerifySettings();
        settings.UseParameters(arg);
        return Verify(arg, settings);
    }

    [Theory]
    [MemberData(nameof(GetStructData))]
    public Task ComplexMemberNullableStructDataFluent(ComplexStructData arg) =>
        Verify(arg)
            .UseParameters(arg);

    public static IEnumerable<object[]> GetStructData()
    {
        yield return [new ComplexStructData("Value1")];
        yield return [new ComplexStructData("Value2")];
    }

    public record ComplexStructData(string Value);
}

snippet source | anchor

Overriding text used for parameters

UseTextForParameters() can be used to override the substitution text used for the {Parameters} part of the file convention.

{Directory}/{TestClassName}.{TestMethodName}_{Parameters}_{UniqueFor1}_{UniqueFor2}_{UniqueForX}.verified.{extension}

The below samples produce:

For the instance case:

  • TheTest.UseTextForParameters_Value1.verified.txt
  • TheTest.UseTextForParameters_Value2.verified.txt

For the fluent case:

  • TheTest.UseTextForParametersFluent_Value1.verified.txt
  • TheTest.UseTextForParametersFluent_Value2.verified.txt

Instance

[Theory]
[InlineData("Value1")]
[InlineData("Value2")]
public Task UseTextForParameters(string arg)
{
    var settings = new VerifySettings();
    settings.UseTextForParameters(arg);
    return Verify(arg + "UseTextForParameters", settings);
}

snippet source | anchor

Fluent

[Theory]
[InlineData("Value1")]
[InlineData("Value2")]
public Task UseTextForParametersFluent(string arg) =>
    Verify(arg + "UseTextForParametersFluent")
        .UseTextForParameters(arg);

snippet source | anchor

Ignore parameters for verified filename

By default, Verify expects every parameterized case to have a unique file name with the parameters appended to the file name. This behavior can be overridden by using IgnoreParametersForVerified(). In this case, the verified file name does not contain the parameter values, meaning it is the same for each testcase.

IgnoreParametersForVerified accepts an array for passing through the parameters. These values are passed to UseParameters. This is required for MSTest, and xUnit. Parameters should not be passed for NUnit, TUnit and Fixie since they are automatically detected.

The below samples produce:

For the instance case:

  • NamerTests.IgnoreParametersForVerified_arg=One.received.txt
  • NamerTests.IgnoreParametersForVerified_arg=Two.received.txt
  • NamerTests.IgnoreParametersForVerified.verified.txt

For the fluent case:

  • NamerTests.IgnoreParametersForVerifiedFluent_arg=One.received.txt
  • NamerTests.IgnoreParametersForVerifiedFluent_arg=Two.received.txt
  • NamerTests.IgnoreParametersForVerifiedFluent.verified.txt

Static IgnoreParameters

VerifierSettings.IgnoreParameters() can be used to globally ignore specific parameters (by name) for all tests. This is useful when a parameter is non-deterministic or irrelevant to the verified output across the entire test suite. It must be called before any test runs, typically in a [ModuleInitializer].

When passing an empty list, all parameters will be ignored. When passing specific parameter names, only those parameters will be excluded from the verified filename. Parameters that do not exist on a given test method are silently skipped.

The received files still contain all parameter values.

[ModuleInitializer]
public static void Init() =>
    VerifierSettings.IgnoreParameters("arg");

Instance

[Theory]
[InlineData("One")]
[InlineData("Two")]
public Task IgnoreParametersForVerified(string arg)
{
    var settings = new VerifySettings();
    settings.IgnoreParametersForVerified(arg);
    return Verify("value", settings);
}

snippet source | anchor

Fluent

[Theory]
[InlineData("One")]
[InlineData("Two")]
public Task IgnoreParametersForVerifiedFluent(string arg) =>
    Verify("value")
        .IgnoreParametersForVerified(arg);

snippet source | anchor

IgnoreParametersForVerified with override parameters

The parameters passed to IgnoreParametersForVerified can be used pass custom parameters to UseParameters.

Instance

[Theory]
[InlineData("One")]
[InlineData("Two")]
public Task IgnoreParametersForVerifiedCustomParams(string arg)
{
    var settings = new VerifySettings();
    settings.IgnoreParametersForVerified($"Number{arg}");
    return Verify("value", settings);
}

snippet source | anchor

Fluent

[Theory]
[InlineData("One")]
[InlineData("Two")]
public Task IgnoreParametersForVerifiedCustomParamsFluent(string arg) =>
    Verify("value")
        .IgnoreParametersForVerified($"Number{arg}");

snippet source | anchor