Having worked with C# for quite some time now writing desktop applications, I've begun making the transition over to .NET standard. In my professional working experience, it was a much slower transition because of product requirements and time, but in my own personal development there's no reason why I couldn't get started with it. And call me crazy, but I enjoy writing coded tests for the things I make. My favorite testing framework for my C# development is xUnit, and naturally as I started writing some new code with .NET Standard I wanted to make sure I could get my tests to run. But I did hit a little snag with my xUnit tests not running... Let's check it out!
xUnit Tests - The Example
Here's an example of some C# code I wrote for my unit tests of a simple LRU cache class I was playing around with:
[ExcludeFromCodeCoverage]
public sealed class LruCachetests
{
[Fact]
public void Constructor_CapacityTooSmall_ThrowsArgumentException()
{
Assert.Throws<ArgumentException>(() => new LruCache<int, int>(0));
}
[Fact]
public void ContainsKey_EntryExists_True()
{
var cache = new LruCache<int, int>(1);
cache.Add(0, 1);
var actual = cache.ContainsKey(0);
Assert.True(
actual,
$"Unexpected result for '{nameof(LruCache<int, int>.ContainsKey)}'.");
}
}
Pretty simple stuff. I know that for xUnit in Visual Studio, I need to get a nuget package for the test runner to work right in the IDE. Simple enough, I just need to add the "xunit.runner.visualstudio" package alongside the xunit package I had already included into my test project.
Ready to rock! So I go run all my tests in the solution but I'm met with this little surprise:
[3/24/2020 3:59:10.570 PM] ========== Discovery aborted: 0 tests found (0:00:00.0622045) ==========
[3/24/2020 3:59:20.510 PM] ---------- Discovery started ----------
Microsoft.VisualStudio.TestPlatform.ObjectModel.TestPlatformException: Unable to find C:[redacted]binDebugnetstandard2.0testhost.dll. Please publish your test project and retry.
at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Hosting.DotnetTestHostManager.GetTestHostPath(String runtimeConfigDevPath, String depsFilePath, String sourceDirectory)
at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Hosting.DotnetTestHostManager.GetTestHostProcessStartInfo(IEnumerable`1 sources, IDictionary`2 environmentVariables, TestRunnerConnectionInfo connectionInfo)
at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.ProxyOperationManager.SetupChannel(IEnumerable`1 sources, String runSettings)
at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.ProxyDiscoveryManager.DiscoverTests(DiscoveryCriteria discoveryCriteria, ITestDiscoveryEventsHandler2 eventHandler)
[3/24/2020 3:59:20.570 PM] ========== Discovery aborted: 0 tests found (0:00:00.0600179) ==========
Executing all tests in project: [redacted].Tests
[3/24/2020 3:59:20.635 PM] ---------- Run started ----------
[3/24/2020 3:59:20.639 PM] ========== Run finished: 0 tests run (0:00:00.0039314) ==========
Please publish your test project and retry? Huh?
As any software engineer does, I set out to Google for answers. I came across this Stack Overflow post: https://stackoverflow.com/q/54770830/2704424
The Solution To My xUnit Troubles
And fortunately, someone had responded with a link to the xUnit documentation: Why doesn't xUnit.net support netstandard?
The answer was right at the top!
https://xunit.net/docs/why-no-netstandard
netstandard
is an API, not a platform. Due to the way builds and dependency resolution work today, xUnit.net test projects must target a platform (desktop CLR, .NET Core, etc.) and run with a platform-specific runner application.
My solution was that I changed my test project to build for one of the latest .NET Frameworks... and voila! I chose .NET 4.8 as the latest available at the time of writing.
My next attempt at running all of my tests looked like this:
Executing all tests in project: [Redacted].Tests
[3/24/2020 3:59:20.635 PM] ---------- Run started ----------
[3/24/2020 3:59:20.639 PM] ========== Run finished: 0 tests run (0:00:00.0039314) ==========
[3/24/2020 4:08:14.898 PM] ---------- Discovery started ----------
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.1 (32-bit Desktop .NET 4.0.30319.42000)
[xUnit.net 00:00:00.40] Discovering: [Redacted].Tests
[xUnit.net 00:00:00.47] Discovered: [Redacted].Tests
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.1 (32-bit Universal Windows)
[3/24/2020 4:08:16.289 PM] ========== Discovery finished: 2 tests found (0:00:01.3819229) ==========
Executing all tests in project: [Redacted].Tests
[3/24/2020 4:08:17.833 PM] ---------- Run started ----------
[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v2.4.1 (32-bit Desktop .NET 4.0.30319.42000)
[xUnit.net 00:00:00.41] Starting: [Redacted].Tests
[xUnit.net 00:00:00.66] Finished: [Redacted].Tests
[3/24/2020 4:08:19.337 PM] ========== Run finished: 2 tests run (0:00:01.4923808) ==========
And I was back on my path to success! Hopefully, if you run into this same issue you can resolve it in the same fashion. Happy testing!