Every parameterised case has a unique file name with the parameters appended to the file name.
The appending format is _ParamName=ParamValue
repeated for each parameter.
A test with two parameters param1
+ param2
, and called twice with the values value1a
+ value2a
and value1b
+ value2b
would have the following file names:
MyTest.MyMethod_param1=value1a_param2=value2a.verified.txt
MyTest.MyMethod_param1=value1b_param2=value2b.verified.txt
Characters that cannot be used for a file name will be replaced with a dash (-
).
UseParameters
is used to control what parameters are used when naming files. The usual usage is to pass though all parameters (in the same order) that the test method accepts:
[Theory]
[InlineData("Value1")]
[InlineData("Value2")]
public Task UseParametersUsage(string arg)
{
var somethingToVerify = $"{arg} some text";
return Verify(somethingToVerify)
.UseParameters(arg);
}
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);
}
If the number of parameters pass to UseParameters
is greater than the number of parameters in the test method, an exception will be thrown.
[Theory]
[InlineData("Value1")]
[InlineData("Value2")]
public Task InlineDataUsage(string arg)
{
var settings = new VerifySettings();
settings.UseParameters(arg);
return Verify(arg, settings);
}
[Theory]
[InlineData("Value1")]
[InlineData("Value2")]
public Task InlineDataUsageFluent(string arg) =>
Verify(arg)
.UseParameters(arg);
[Theory]
[MemberData(nameof(GetData))]
public Task MemberDataUsage(string arg)
{
var settings = new VerifySettings();
settings.UseParameters(arg);
return Verify(arg, settings);
}
[Theory]
[MemberData(nameof(GetData))]
public Task MemberDataUsageFluent(string arg) =>
Verify(arg)
.UseParameters(arg);
public static IEnumerable<object[]> GetData()
{
yield return new object[]
{
"Value1"
};
yield return new object[]
{
"Value2"
};
}
xUnit only exposes parameter information when the types certain types. For unknown types the parameter information cannot be retrieved from the xUnit context, and instead the parameters need to be explicitly passed in. This is done by calling UseParameters()
.
[UsesVerify]
public class ComplexParametersSample
{
[ModuleInitializer]
public static void Initialize()
{
VerifierSettings.NameForParameter<ComplexData>(_ => _.Value);
VerifierSettings.NameForParameter<ComplexStructData>(_ => _.Value);
}
[Theory]
[MemberData(nameof(GetComplexMemberData))]
public Task ComplexMemberData(ComplexData arg)
{
var settings = new VerifySettings();
settings.UseParameters(arg);
return Verify(arg, settings);
}
[Theory]
[MemberData(nameof(GetComplexMemberData))]
public Task ComplexMemberDataFluent(ComplexData arg) =>
Verify(arg)
.UseParameters(arg);
[Theory]
[MemberData(nameof(GetComplexMemberData))]
public Task ComplexMemberNullableData(ComplexData arg)
{
var settings = new VerifySettings();
settings.UseParameters(arg);
return Verify(arg, settings);
}
[Theory]
[MemberData(nameof(GetComplexMemberData))]
public Task ComplexMemberNullableDataFluent(ComplexData arg) =>
Verify(arg)
.UseParameters(arg);
public static IEnumerable<object[]> GetComplexMemberData()
{
yield return new object[]
{
new ComplexData {Value = "Value1"}
};
yield return new object[]
{
new ComplexData {Value = "Value2"}
};
}
public class ComplexData
{
public string Value { get; set; } = null!;
}
[Theory]
[MemberData(nameof(GetComplexMemberStructData))]
public Task ComplexMemberStructData(ComplexStructData arg)
{
var settings = new VerifySettings();
settings.UseParameters(arg);
return Verify(arg, settings);
}
[Theory]
[MemberData(nameof(GetComplexMemberStructData))]
public Task ComplexMemberStructDataFluent(ComplexStructData arg) =>
Verify(arg)
.UseParameters(arg);
[Theory]
[MemberData(nameof(GetComplexMemberStructData))]
public Task ComplexMemberNullableStructData(ComplexStructData arg)
{
var settings = new VerifySettings();
settings.UseParameters(arg);
return Verify(arg, settings);
}
[Theory]
[MemberData(nameof(GetComplexMemberStructData))]
public Task ComplexMemberNullableStructDataFluent(ComplexStructData arg) =>
Verify(arg)
.UseParameters(arg);
public static IEnumerable<object[]> GetComplexMemberStructData()
{
yield return new object[]
{
new ComplexStructData("Value1")
};
yield return new object[]
{
new ComplexStructData("Value2")
};
}
public struct ComplexStructData
{
public ComplexStructData(string value) =>
Value = value;
public string Value { get; set; } = null!;
}
}
VerifierSettings.NameForParameter
is required since the parameter type has no ToString()
override that can be used for deriving the name of the .verified.
file.
[TestCase("Value1")]
[TestCase("Value2")]
public Task TestCaseUsage(string arg) =>
Verify(arg);
When using a TestFixtureSource the the name provided by NUnit will be as the TestMethodName
.
[TestFixtureSource(nameof(FixtureArgs))]
public class TestFixtureSourceUsage
{
string arg1;
int arg2;
public TestFixtureSourceUsage(string arg1, int arg2)
{
this.arg1 = arg1;
this.arg2 = arg2;
}
[Test]
public Task Test() =>
Verify(
new
{
arg1,
arg2
});
static object[] FixtureArgs =
{
new object[]
{
"Value1",
1
},
new object[]
{
"Value2",
2
}
};
}
Produces TestFixtureSourceUsage(Value1,1).Test.verified.txt
and TestFixtureSourceUsage(Value2,2).Test.verified.txt
.
MSTest does not expose the parameter values via its extensibility context. So parameter values must passed in via settings.
[TestClass]
public class ParametersSample :
VerifyBase
{
[DataTestMethod]
[DataRow("Value1")]
[DataRow("Value2")]
public Task DataRowUsage(string arg)
{
var settings = new VerifySettings();
settings.UseParameters(arg);
return Verify(arg, settings);
}
[DataTestMethod]
[DataRow("Value1")]
[DataRow("Value2")]
public Task DataRowUsageFluent(string arg) =>
Verify(arg)
.UseParameters(arg);
}
UseTextForParameters()
can be used to override the text used for {Parameters}
.
{Directory}/{TestClassName}.{TestMethodName}_{Parameters}_{UniqueFor1}_{UniqueFor2}_{UniqueForX}.verified.{extension}
[Theory]
[InlineData("Value1")]
[InlineData("Value2")]
public Task UseTextForParameters(string arg)
{
var settings = new VerifySettings();
settings.UseTextForParameters(arg);
return Verify(arg + "UseTextForParameters", settings);
}
[Theory]
[InlineData("Value1")]
[InlineData("Value2")]
public Task UseTextForParametersFluent(string arg) =>
Verify(arg + "UseTextForParametersFluent")
.UseTextForParameters(arg);
Results in:
- TheTest.UseTextForParameters_Value1.verified.txt
- TheTest.UseTextForParameters_Value2.verified.txt
- TheTest.UseTextForParametersFluent_Value1.verified.txt
- TheTest.UseTextForParametersFluent_Value2.verified.txt
By default, every parameterised case has 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.
[Theory]
[InlineData("One")]
[InlineData("Two")]
public Task IgnoreParametersForVerified(string arg)
{
var settings = new VerifySettings();
settings.IgnoreParametersForVerified(arg);
return Verify("valueIgnoreParametersForVerified", settings);
}
[Theory]
[InlineData("One")]
[InlineData("Two")]
public Task IgnoreParametersForVerifiedFluent(string arg) =>
Verify("valueIgnoreParametersForVerifiedFluent")
.IgnoreParametersForVerified(arg);
Results in:
- NamerTests.IgnoreParametersForVerified_arg=One.received.txt
- NamerTests.IgnoreParametersForVerified_arg=Two.received.txt
- NamerTests.IgnoreParametersForVerified.verified.txt
And for the second test:
- NamerTests.IgnoreParametersForVerifiedFluent_arg=One.received.txt
- NamerTests.IgnoreParametersForVerifiedFluent_arg=Two.received.txt
- NamerTests.IgnoreParametersForVerifiedFluent.verified.txt