Naming determines the file name for the .received.
resulting .verified.
files.
The format is
{Directory}/{TestClassName}.{TestMethodName}_{Parameters}_{UniqueFor1}_{UniqueFor2}_{UniqueForX}.verified.{extension}
The directory that contains the test. A custom directory can be used via UseDirectory
:
var settings = new VerifySettings();
settings.UseDirectory("CustomDirectory");
await Verify("valueUseDirectory", settings);
await Verify("valueUseDirectoryFluent")
.UseDirectory("CustomDirectory");
Will result in CustomDirectory/TypeName.MethodName.verified.txt
.
The path provided can be absolute or relative to the directory that contains the test.
The class name that contains the test. A custom test name can be used via UseTypeName
:
var settings = new VerifySettings();
settings.UseTypeName("CustomTypeName");
await Verify("valueUseTypeName", settings);
await Verify("valueUseTypeNameFluent")
.UseTypeName("CustomTypeName");
Will result in CustomTypeName.MethodName.verified.txt
.
The test method name. A custom test name can be used via UseMethodName
:
var settings = new VerifySettings();
settings.UseMethodName("CustomMethodName");
await Verify("valueUseMethodName", settings);
Will result in TestClass.CustomMethodName.verified.txt
.
await Verify("valueUseMethodNameFluent")
.UseMethodName("CustomMethodNameFluent");
Will result in TestClass.CustomMethodNameFluent.verified.txt
.
UseMethodName
can also be used to allow multiple calls to Verify in the same method:
[Fact]
public Task MultipleCalls() =>
Task.WhenAll(
Verify("Value1MultipleCalls")
.UseMethodName("MultipleCalls_1"),
Verify("Value1MultipleCalls")
.UseMethodName("MultipleCalls_2"));
To fully control the {TestClassName}.{TestMethodName}_{Parameters}
parts of the file use UseFileName
:
var settings = new VerifySettings();
settings.UseFileName("CustomFileName");
await Verify("valueUseFileName", settings);
Will result in CustomFileName.verified.txt
.
await Verify("valueUseFileNameFluent")
.UseFileName("CustomFileNameFluent");
Will result in UseFileNameFluent.verified.txt
.
Compatibility:
- Not compatible with
UseTypeName
,UseMethodName
, orUseParameters
. An exception will be thrown if they are combined. - Can be used in combination with
UseDirectory
. - Can be used in combination with
UniqueFor*
.
See Parameterised Tests.
UniqueFor*
allows for one or more delimiters to be added to the file name.
[UsesVerify]
public class UniqueForSample
{
[Fact]
public Task Runtime()
{
var settings = new VerifySettings();
settings.UniqueForRuntime();
return Verify("value", settings);
}
[Fact]
public Task RuntimeFluent() =>
Verify("value")
.UniqueForRuntime();
[Fact]
public Task RuntimeAndVersion()
{
var settings = new VerifySettings();
settings.UniqueForRuntimeAndVersion();
return Verify("value", settings);
}
[Fact]
public Task AssemblyConfiguration()
{
var settings = new VerifySettings();
settings.UniqueForAssemblyConfiguration();
return Verify("value", settings);
}
[Fact]
public Task AssemblyConfigurationFluent() =>
Verify("value")
.UniqueForAssemblyConfiguration();
[Fact]
public Task Architecture()
{
var settings = new VerifySettings();
settings.UniqueForArchitecture();
return Verify("value", settings);
}
[Fact]
public Task ArchitectureFluent() =>
Verify("value")
.UniqueForArchitecture();
[Fact]
public Task OSPlatform()
{
var settings = new VerifySettings();
settings.UniqueForOSPlatform();
return Verify("value", settings);
}
[Fact]
public Task OSPlatformFluent() =>
Verify("value")
.UniqueForOSPlatform();
}
[TestFixture]
public class UniqueForSample
{
[Test]
public Task Runtime()
{
var settings = new VerifySettings();
settings.UniqueForRuntime();
return Verify("value", settings);
}
[Test]
public Task RuntimeFluent() =>
Verify("value")
.UniqueForRuntime();
[Test]
public Task AssemblyConfiguration()
{
var settings = new VerifySettings();
settings.UniqueForAssemblyConfiguration();
return Verify("value", settings);
}
[Test]
public Task AssemblyConfigurationFluent() =>
Verify("value")
.UniqueForAssemblyConfiguration();
[Test]
public Task RuntimeAndVersion()
{
var settings = new VerifySettings();
settings.UniqueForRuntimeAndVersion();
return Verify("value", settings);
}
[Test]
public Task RuntimeAndVersionFluent() =>
Verify("value")
.UniqueForRuntimeAndVersion();
[Test]
public Task Architecture()
{
var settings = new VerifySettings();
settings.UniqueForArchitecture();
return Verify("value", settings);
}
[Test]
public Task ArchitectureFluent() =>
Verify("value")
.UniqueForArchitecture();
[Test]
public Task OSPlatform()
{
var settings = new VerifySettings();
settings.UniqueForOSPlatform();
return Verify("value", settings);
}
[Test]
public Task OSPlatformFluent() =>
Verify("value")
.UniqueForOSPlatform();
}
[<Tests>]
let uniqueTests =
testTask "unique" {
let settings = VerifySettings()
settings.UniqueForRuntime()
do! Verifier.Verify("unique", "value", settings)
}
[TestClass]
public class UniqueForSample :
VerifyBase
{
[TestMethod]
public Task Runtime()
{
var settings = new VerifySettings();
settings.UniqueForRuntime();
return Verify("value", settings);
}
[TestMethod]
public Task RuntimeFluent() =>
Verify("value")
.UniqueForRuntime();
[TestMethod]
public Task RuntimeAndVersion()
{
var settings = new VerifySettings();
settings.UniqueForRuntimeAndVersion();
return Verify("value", settings);
}
[TestMethod]
public Task RuntimeAndVersionFluent() =>
Verify("value")
.UniqueForRuntimeAndVersion();
[TestMethod]
public Task AssemblyConfiguration()
{
var settings = new VerifySettings();
settings.UniqueForAssemblyConfiguration();
return Verify("value", settings);
}
[TestMethod]
public Task AssemblyConfigurationFluent() =>
Verify("value")
.UniqueForAssemblyConfiguration();
[TestMethod]
public Task Architecture()
{
var settings = new VerifySettings();
settings.UniqueForArchitecture();
return Verify("value", settings);
}
[TestMethod]
public Task ArchitectureFluent() =>
Verify("value")
.UniqueForArchitecture();
[TestMethod]
public Task OSPlatform()
{
var settings = new VerifySettings();
settings.UniqueForOSPlatform();
return Verify("value", settings);
}
[TestMethod]
public Task OSPlatformFluent() =>
Verify("value")
.UniqueForOSPlatform();
}
For a project executed on both x64 and x86 that targets
<TargetFrameworks>netcoreapp3.0;net48</TargetFrameworks>
Will result in the following files being produced:
UniqueForSample.Runtime.Core.verified.txt
UniqueForSample.Runtime.Net.verified.txt
UniqueForSample.RuntimeAndVersion.Core3_0.verified.txt
UniqueForSample.RuntimeAndVersion.Net4_8.verified.txt
UniqueForSample.Architecture.X86.verified.txt
UniqueForSample.Architecture.X64.verified.txt
The default file extension is .txt
. So the resulting verified file will be TestClass.TestMethod.verified.txt
.
It can be overridden at two levels:
- Method: Change the extension for the current test method.
- Class: Change the extension all verifications in all test methods for a test class.
Usage:
[UsesVerify]
public class ExtensionSample
{
[Fact]
public Task AtMethod() =>
Verify(
target: @"
<note>
<to>Joe</to>
<from>Kim</from>
<heading>Reminder</heading>
</note>",
extension: "xml");
[Fact]
public Task AtMethodFluent() =>
Verify(
target: @"
<note>
<to>Joe</to>
<from>Kim</from>
<heading>Reminder</heading>
</note>",
extension: "xml");
}
Result in:
<note>
<to>Joe</to>
<from>Kim</from>
<heading>Reminder</heading>
</note>
To access the current Namer Runtime
or RuntimeAndVersion
strings use:
Debug.WriteLine(Namer.Runtime);
Debug.WriteLine(Namer.RuntimeAndVersion);
DerivePathInfo
allows the storage directory of .verified.
files to be customized based on the current context. The contextual parameters are parameters passed are as follows:
sourceFile
: The full path to the file that the test existed in at compile time.projectDirectory
: The directory that the project existed in at compile time.type
: The class the test method exists in.method
: The test method.
For example to place all .verified.
files in a {ProjectDirectory}\Snapshots
the following could be used:
Verifier.DerivePathInfo(
(sourceFile, projectDirectory, type, method) => new(
directory: Path.Combine(projectDirectory, "Snapshots"),
typeName: type.Name,
methodName: method.Name));
Return null to any of the values to use the standard behavior. The returned path can be relative to the directory sourceFile exists in.
DerivePathInfo
can also be useful when deriving the storage directory on a build server
A DerivePathInfo
convention can be shipped as a NuGet, for example Spectre.Verify.Extensions which adds an attribute driven file naming convention to Verify.
static DerivePathInfo derivePathInfo = (sourceFile, projectDirectory, type, method) =>
new(
directory: Path.GetDirectoryName(sourceFile)!,
typeName: type,
methodName: method);
static DerivePathInfo derivePathInfo = (sourceFile, projectDirectory, type, method) =>
new(
directory: Path.GetDirectoryName(sourceFile)!,
typeName: type.NameWithParent(),
methodName: method.Name);
static DerivePathInfo derivePathInfo = (sourceFile, projectDirectory, type, method) =>
new(
directory: Path.GetDirectoryName(sourceFile)!,
typeName: type.NameWithParent(),
methodName: method.Name);
static DerivePathInfo derivePathInfo = (sourceFile, projectDirectory, type, method) =>
new(
directory: Path.GetDirectoryName(sourceFile)!,
typeName: type.NameWithParent(),
methodName: method.Name);
public static string NameWithParent(this Type type)
{
if (type.IsNested)
{
return $"{type.ReflectedType!.Name}.{type.Name}";
}
return type.Name;
}
Snapshot file names have to be unique. If a duplicate name is used, then an exception will be throw. This is mostly caused by a conflicting combination of VerifierSettings.DerivePathInfo()
, UseMethodName.UseDirectory()
, UseMethodName.UseTypeName()
, and UseMethodName.UseMethodName()
. If that's not the case, and having multiple identical prefixes is acceptable, then call VerifierSettings.DisableRequireUniquePrefix()
to disable this uniqueness validation
An alternative to the "unique file name in the current test directory".
This approach uses "a unique directory in the current test directory".
Useful when many test produce many files, and it is desirable to have them grouped in a directory.
The file format is:
{CurrentDirectory}/{TestClassName}.{TestMethodName}_{Parameters}_{UniqueFor1}_{UniqueFor2}_{UniqueForX}/{targetName}.verified.{extension}
var settings = new VerifySettings();
settings.UseUniqueDirectory();
await Verify("TheValue", settings);
UseSplitModeForUniqueDirectory
is a global option that changes the behavior of all UseUniqueDirectory
uses.
The received
and verified
are split and each exist in their own directory.
The file format is:
For received files:
{CurrentDirectory}/{TestClassName}.{TestMethodName}_{Parameters}_{UniqueFor1}_{UniqueFor2}_{UniqueForX}.received/{targetName}.{extension}
For verified files:
{CurrentDirectory}/{TestClassName}.{TestMethodName}_{Parameters}_{UniqueFor1}_{UniqueFor2}_{UniqueForX}.verified/{targetName}.{extension}
[ModuleInitializer]
public static void Init() =>
VerifierSettings.UseSplitModeForUniqueDirectory();
Also exclude *.received/
from source control.
eg. add the following to .gitignore
*.received/