The folder from which the test is run – how to eliminate minor inconveniences

In one of the projects I am involved in, many business processes rely on file import. In order to guarantee the high quality of the software, we systematically create numerous integration tests in which we import these files. We currently have more than a thousand of them.

An example test might looks like:

// Folder structure:
	/Tests/OrganizationUnit/SomeTestClass.cs
	/Tests/OrganizationUnit/employee.csv
	/Tests/OrganizationUnit/organizationUnit.csv
	/Tests/OrganizationUnit/product.csv

public class SomeTestClass : TestBase
{
	public void GivenEmployeeAndOrganizationUnit_WhenAddProduct_ThenEmailIsSend()
	{
		// Given
		var employee = EmployeeImporter.Import("Tests/OrganizationUnit/employee.csv");
		var organizationUnit = OrganizationUnitImporter.Import("Tests/OrganizationUnit/organizationUnit.csv");

		employee.AddToStructure(organizationUnit);

		// When
		ProductImporter.Import("Tests/OrganizationUnit/product.csv");

		//Then
		EmailSender.Should().SendEmail();
	}
}

Sometimes some tests are similar to others, with minor business modifications in the CSV files, but the sequence of their calls is the same, repeating in many cases:

var employee = EmployeeImporter.Import("Tests/OrganizationUnit/employee.csv");
var organizationUnit = OrganizationUnitImporter.Import("Tests/OrganizationUnit/organizationUnit.csv");

The path to the files is relative, meaning that the SomeTestClass test assumes that these files are in the /Tests/OrganisationUnit/ directory.

When we copy the test folders, changing some parts, it is easy to forget to update the paths to the CSV files. While this may seem like a small thing, when we write 5-6 tests a day, it becomes a nuisance.

To solve this problem, I introduced a simple method:

protected static string GetTestBasePath([CallerFilePath] string sourceFilePath = "")
{
    return Path.GetDirectoryName(sourceFilePath);
}

We can then use this method in test like this:

// Folder structure:
	/Tests/OrganizationUnit/SomeTestClass.cs
	/Tests/OrganizationUnit/employee.csv
	/Tests/OrganizationUnit/organizationUnit.csv
	/Tests/OrganizationUnit/product.csv

public class SomeTestClass : TestBase
{
	public void GivenEmployeeAndOrganizationUnit_WhenAddProduct_ThenEmailIsSend()
	{
		// Given
		var employee = EmployeeImporter.Import($"{GetTestBasePath()}/employee.csv")
		var organizationUnit = OrganizationUnitImporter.Import($"{GetTestBasePath()}/organizationUnit.csv")

		employee.AddToStructure(organizationUnit)

		// When
		ProductImporter.Import($"{GetTestBasePath()}/product.csv")

		//Then
		EmailSender.Should().SendEmail()
	}
}

By using [CallerFilePath] at runtime, we retrieve the path from which the method was called, eliminating the need to remember to update paths in copied tests.