Welcome Guest! To enable all features please Login or Register.



MSTest AssemblyInitialize & TestContext
#1 Posted : Wednesday, December 8, 2021 10:59:01 PM(UTC)
Rank: Newbie

Groups: Registered
Joined: 6/19/2017(UTC)
Posts: 5
Location: Norway

Thanks: 1 times
Visual Studio 2022
nCrunch 4.11
MSTest v2 2.2.7
.net 5

We use a AssemblyInitialize attribute to initialize some global stuff for our tests.
In there we are accessing TestContext.TestRunResultsDirectory to store some temporary database files.

The problem is that when running our tests through nCrunch, the TestContext object is completely empty.
Is this as expected? Is there another way of getting hold of this information?

#2 Posted : Thursday, December 9, 2021 12:27:59 AM(UTC)
Rank: NCrunch Developer

Groups: Administrators
Joined: 4/16/2011(UTC)
Posts: 6,614

Thanks: 869 times
Was thanked: 1183 time(s) in 1103 post(s)
Hi, thanks for sharing this.

There's a bit of history behind why this is the way that it is. The properties in the TestContext here (namely ResultsDirectory, which is the one you're after) get populated by MSTest when it sets up a temporary deployment directory prior to the tests being run. Various resources and dependencies are copied to this deployment directory, presumably for the purpose of creating a relatively isolated environment for the test code to run thereby reducing the risk of it interfering with other files in the solution.

This process has been around since at least VS2008 (and possibly even earlier). In terms of implementation, it's actually quite an expensive process in that it involves copying a lot of files around. It also introduces a lot of strange edge cases related to file copy order, etc. The process also changes depending on the version of VS being used.

This is very different to how every other test framework functions, in which the working directory is generally set to the build output directory of the test assembly and resources are accessed relative to this (avoiding the need for copying and sandboxing, unless the user builds their own system for this).

When .NET Core was released with VS2017, the above deployment system was not implemented for the .NET Core runner. Instead, the TestContext was backed by a much reduced class with almost none of the available properties you've shown. This meant that MSTest2017 behaved much more similar to other test frameworks (i.e. NUnit, xunit, etc).

It seems that with VS2019, MS have quietly reintroduced the deployment system into MSTest for .NET Core. As such, it's in VS2022 too. I haven't examined all the tiny details behind how it's been implemented yet, but I presume there are a number of subtle differences as they would probably have re-engineered it.

Unlike with other test frameworks, NCrunch implements support for MSTest through a custom emulator designed to behave like MSTest. The design goal of the emulator is to be as close as we can make it to MSTest, with some practical considerations. For example, we don't support datasource driven tests, but we do a better job of the parameterised datarow tests. This emulator is a complex beast because it needs to emulate the behaviour of all versions of MSTest released in the last 13 years, including handling some very weird things that you wouldn't normally expect MSTest to do. It isn't really possible to maintain such a solution without making some serious concessions. There are also risks involved where NCrunch users become accustomed to unintentional differences in the emulator and design their own code around this, and we then can't fix the emulator without breaking them.

Up until now, I wasn't aware that the deployment system had been reintroduced for .NET Core. I'm considering reintroducing it in the emulator, but there are some concerns here:

- We've been out of alignment here for nearly 3 years and up until now, no one has mentioned it. This suggests that very very few people are relying on the deployment behaviour for MSTest under .NET Core (I actually expect most people are using NUnit/xunit).
- If we reintroduce deployments, we risk breaking working code running on every site that has been using NCrunch on .NET Core since 2017.
- Internally, deployments are not a nice thing to implement. They detrimentally impact the performance of the runner (increasing wait times for test results), while increasing the risk of file locking exceptions during clean-up, workspace clutter, etc.
- By putting the deployments back in, we make NCrunch's MSTest runner as fragmented as VS's runner, making it harder for people to understand why the runner is behaving the way it is due to all the frequent changes between major versions.

So for now, I'm going to sit on the fence with this issue. If more people come forward with problems caused by the misalignment, we'll reimplement the deployments under .NET Core. Right now, it looks like we'll do more harm than good by doing this.

So in terms of how to handle this in your solution, I would implement a fallback that uses Directory.GetCurrentDirectory whenever the TestResultsDirectory returns null. This would allow the code to run under NCrunch, and the results would be written to one of NCrunch's workspaces.
1 user thanked Remco for this useful post.
vegar on 12/13/2021(UTC)
Users browsing this topic
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

YAF | YAF © 2003-2011, Yet Another Forum.NET
This page was generated in 0.031 seconds.
Trial NCrunch
Take NCrunch for a spin
Do your fingers a favour and supercharge your testing workflow
Free Download