By default ApprovalTests generate output file to the same location where test class resides, with the file name as ClassType.MethodName.
This behaviour is configured in `UnitTestFrameworkNamer` class, that is default namer for ApprovalTests.
Long test names issue
Tests are usually named as <SUT>_<Context>_<ExpectedResult>. Such combination might be quite long and could sometimes exceed 100 symbols. If we add complex tree structure of project itself, we could easily go beyond 260 max symbols in file path limit – https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file#maximum-path-length-limitation
In our case in addition to above, we also had TFS branches of different length, and was was possible to comiit in one branch, – was not possible to merge to another one due to path length limitation.
Allow to override output file on test method
Overriding default namer consists of 3 steps:
Creating attribute for test method
[AttributeUsage(AttributeTargets.Method)] public class ApprovalFileNameAttribute : Attribute { public string Name { get; } public ApprovalFileNameAttribute(string name) { Name = name; } }
Creating custom Namer for ApprovalTests
/// <summary> /// Allows to override approved/received file names created by `UnitTestFrameworkNamer`. /// Could be useful when the test method name is long to reduce the name length of output files. /// In case attribute is not present on Method name, falls back to `UnitTestFrameworkNamer` /// </summary> public class AttributeBasedFileNamer : IApprovalNamer { readonly UnitTestFrameworkNamer _unitTestNamer = new UnitTestFrameworkNamer(); public string SourcePath => _unitTestNamer.SourcePath; public string Name { get { var customFileNameAtt = Approvals.CurrentCaller.GetFirstFrameForAttribute<ApprovalFileNameAttribute>(); return customFileNameAtt == null ? _unitTestNamer.Name : customFileNameAtt.Name; } } }
In case of attribute does not exist for method, fallback to `UnitTestFrameworkNamer`
Glue it together – Register new namer as default
Approvals.RegisterDefaultNamerCreation(() => new AttributeBasedFileNamer());
You could register it on assembly initialize or in static constructor