-
Notifications
You must be signed in to change notification settings - Fork 377
Add support for running XUnit and MSTest tests with the VSTest runner #5347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Sweet! This repo dogfoods itself right? How do we try this out or verify tests? |
|
This repo doesn't directly dogfood itself, arcade-validation gets this once it is merged. I tested it locally by copying the targets into my nuget cache on top of the arcade.sdk that arcade was using and ran tests. |
Cool, seems risky 😄. In the future it might be good to have a way to unit test these changes. Also, does it support passing args as well? We need to b able to support passing vstest args to turn on loggers etc. |
|
Can we get NUnit as well? The required package references can be seen in NUnit.targets here: |
|
Here's how validation works: https://github.com/dotnet/arcade/blob/master/Documentation/Validation/Overview.md Also, +100 to units tests where possible |
The TestRunnerAdditionalArguments property can be set to add more parameters to VSTest. |
|
cc @jakubch1 |
| <UsingToolNetFrameworkReferenceAssemblies Condition="'$(UsingToolNetFrameworkReferenceAssemblies)' == ''">false</UsingToolNetFrameworkReferenceAssemblies> | ||
| <UsingToolNuGetRepack Condition="'$(UsingToolNuGetRepack)' == ''">false</UsingToolNuGetRepack> | ||
| <UsingToolSymbolUploader Condition="'$(UsingToolSymbolUploader)' == ''">false</UsingToolSymbolUploader> | ||
| <UsingToolMSTest Condition="'$(UsingToolMSTest)' == ''">false</UsingToolMSTest> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this value do? It doesn't seem to be used anywhere, and the "MSTest.targets" just calls "dotnet vstest"... all it does it add a handful of package references... but doesn't use them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this actually shouldn't be here. I intended to remove the "UsingTool" properties for test frameworks. Projects should specify TestRunnerName instead.
|
This seems like a fairly complicated matrix of options we are exposing... and I wonder if we have the capacity to manage all this, or if some of the paths are going to atrophy and not really be useful. But if we can't get everyone using the same runner, we don't have much choice other than to pay this maintenance burden until we can. I expect we're going to break a lot of repositories with arcade updates with a test matrix this large. |
| @@ -0,0 +1,118 @@ | |||
| <Project> | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do we expect to use this runner type? Is there some benefit to using this rather than vstest?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the current implementation xunit tests default to using this runner. This is the runner it was using before I added vstest as an option.
The xunit console runner works correctly for a few cases where vstest doesn't do the right thing. @tmat can elaborate, but I believe it was tests running on desktop don't get the correct runtime framework version so the compat switches are not set how the test expects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are we defaulting to the thing we don't want people using? Is the plan to change the default later and then remove this implementation, so that vstest is the only option?
Is the desktop scenario something that's important for arcade in master to be supporting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the desktop scenario is still important because VS is desktop and some of the repos run inside VS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does that imply some repos are staying on netstandard2.0 forever? That's certainly an expensive proposition from a support perspective.
|
What else is needed here? Can we merge this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure this is the right path forward for enabling the VSTest runner? I added support for VSTest in dotnet/runtime as well but without relying on the /t:Test target and instead "just" enabled the dotnet test scenario.
Asking as our community gave us a strong signal that we should enable the default dotnet CLI verbs instead of adding custom targets, e.g.:
Arcade is the ideal place to enable scenarios like "VSTest", "VS Test Explorer", "Code coverage measurement with coverlet" hence I'm a big fan of this work. Unfortunately with the current state this in, we can't leverage the added features in dotnet/runtime or aspnetcore as we want to support dotnet test.
|
In what way does |
|
The VSTest explorer also works fine. |
| <_TestResultDirectory>$([System.IO.Path]::GetDirectoryName('%(TestToRun.ResultsXmlPath)'))</_TestResultDirectory> | ||
| <_TestResultFileName>$([System.IO.Path]::GetFileName('%(TestToRun.ResultsXmlPath)'))</_TestResultFileName> | ||
|
|
||
| <_TestRunnerCommand>dotnet vstest $(_TestAssembly) --logger:"console%3Bverbosity=normal" --logger:"trx%3BLogFileName=$(_TestResultFileName)" "--ResultsDirectory:$(_TestResultDirectory)" "--Framework:%(TestToRun.TargetFrameworkIdentifier),Version=%(TestToRun.TargetFrameworkVersion)" $(_TestRunnerAdditionalArguments)</_TestRunnerCommand> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be just dotnet test as both dotnet test and dotnet vstest got merged together to dotnet test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these settings should be configured in a .runsettings file which allows to specify additional settings like a datacollector for coverlet code coverage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could make it dotnet test here, but that will do a bunch of work msbuilding the project again when that has already happened. We are required to use dotnet vstest for executing tests in helix because the project files are gone. We do that here (https://github.com/dotnet/helix-diagnostic-prototype/blob/master/src/overrides/Helix.Sdk/CreateXUnitWorkItems.cs#L104). I am using the same logic here for consistency.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You probably misunderstood me. dotnet test supports invoking an assembly now in addition to a project or solution file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that should be updated in the docs then, the dotnet test command docs don't say anything about that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @nohwnd who is part of the VSTest team.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filed microsoft/vstest#2423
| <_TestResultDirectory>$([System.IO.Path]::GetDirectoryName('%(TestToRun.ResultsXmlPath)'))</_TestResultDirectory> | ||
| <_TestResultFileName>$([System.IO.Path]::GetFileName('%(TestToRun.ResultsXmlPath)'))</_TestResultFileName> | ||
|
|
||
| <_TestRunnerCommand>dotnet vstest $(_TestAssembly) --logger:"console%3Bverbosity=normal" --logger:"trx%3BLogFileName=$(_TestResultFileName)" "--ResultsDirectory:$(_TestResultDirectory)" "--Framework:%(TestToRun.TargetFrameworkIdentifier),Version=%(TestToRun.TargetFrameworkVersion)" $(_TestRunnerAdditionalArguments)</_TestRunnerCommand> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you changing the default verbosity which is minimal to normal?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we want logging of what tests are running when so we can diagnose crashes more easily.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test execution order usually isn't in order. If you want to improve diagnosability you want to enable the blame collector: https://github.com/microsoft/vstest-docs/blob/master/docs/extensions/blame-datacollector.md
I was talking about the indirection that you are adding here. You are expecting devs to invoke the |
|
cc @nohwnd |
| <!-- | ||
| Report test status. | ||
| --> | ||
| <Message Text="Tests succeeded: $(_TestAssembly) [$(_TestEnvironment)]" Condition="'$(_TestErrorCode)' == '0'" Importance="high" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
VSTest already does all the test logging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
VSTest output doesn't get placed in the build log.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, that's because of the indirection that I mentioned. I don't we should continue doing this with VSTest and just directly invoke it.
| Ideally we would set ContinueOnError="ErrorAndContinue" so that when a test fails in multi-targeted test project | ||
| we'll still run tests for all target frameworks. ErrorAndContinue doesn't work well on Linux though: https://github.com/Microsoft/msbuild/issues/3961. | ||
| --> | ||
| <Error Text="Tests failed: $(_ResultsFileToDisplay) [$(_TestEnvironment)]" Condition="'$(_TestErrorCode)' != '0'" File="VSTest" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
VSTest already logs the generated log files like trx and html to stdout. Why are we duplicating that logic?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same reason as above, the output from VSTest is written into a txt file, this shows up in the build log as an error and causes the build to fail when tests fail.
|
For F5 and |
| <PropertyGroup> | ||
| <!-- Opt-out features --> | ||
| <UsingToolXliff Condition="'$(UsingToolXliff)' == ''">true</UsingToolXliff> | ||
| <UsingToolXUnit Condition="'$(UsingToolXUnit)' == ''">true</UsingToolXUnit> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UsingToolXUnit [](start = 5, length = 14)
It seems we are still using this property. We also use UsingToolVSTest now. Both should be listed here with their defaults (either opt-in or opt-out).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am only reading UsingToolXUnit as a back-compat for cases where it was set to false for some reason. I will add UsingToolVSTest here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It still should be here, perhaps with a comment. It is useful to see all the values here for reference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UsingToolVSTest is a bit more strange too. Its default changes based on what test framework you are using. Its false by default if you are using XUnit, but it is required to be true if using another test framework.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So then I'm not sure naming it UsingToolXxx is appropriate. These switches are used for repository-wide configuration, not something that should differ project to project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will name it UseVSTestRunner then.
There is no expectation that devs use |
I still don't understand why we want to keep the |
|
Getting rid of /t:Test would require some more significant changes. Some repos use the TestArchitectures to run AnyCPU tests on multiple platforms (32 and 64-bit). Also, we would also need to change build.ps1 to invoke One more thing - there is still one more issue to address before repos can move to vstest: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1002535 |
|
Please don't get me wrong, I'm asking for not leveraging the test target for VSTest but keeping it for xunit.console until we can remove the xunit.console dependency. Regarding the linked issue, I'm sure we can get that fixed near term by collaborating with the vstest folks. They have been very open and helpful in the past. Right, looks like TestArchitectures is very custom tailored. Do our repositories absolutely need that feature? We only run on the current arch in dotnet/runtime for AnyCPU specific libraries and CI then fans out. |
How would you expect this to work? These targets run tests for each TFM separately, I can't set these properties for the whole project. There isn't a single TFM to run tests for, there can be many. |
It can indeed be implemented differently, but it's work that needs to be done. Let's file an issue to deprecate this feature. |
I'm not sure we should add F5 support like that. That should be a VS feature. Typically, one runs tests in VS using Test Explorer or right-click on project "run tests". BTW, what's |
This change adds support for using VSTest as the test runner for XUnit, MSTest, and NUnit tests.
3b8ca84 to
b24094e
Compare
Inside VS you select the TargetFramework from the TargetFrameworkPicker which lists TargetFramework entries for all TargetFrameworks 🤔😅 These properties are part of the inner build hence they are tfm specific. |
Does F5 in vs pick a TFM somehow? I've never had a runnable project with more than one TFM. |
Can you please elaborate on your concerns? We always set those in corefx/runtime to allow F5 debugging for people who prefer that. The Run target is an sdk target which was added recently and uses the RunCommand, RunArguments and RunWorkingDirectory properties. Quite similar to what VS does. |
Feel free to use it in dotnet/runtime if devs find it useful. I'm just saying we should push on VS test team to improve the built-in experience of running tests, so that setting these build props is not necessary. |
|
Can somebody summarize what's blocking this PR. The goal is to get this vstest support merged this week. |
|
I don't think anything is blocking this functionally. This change allows using vstest instead of the xunit console runner so we can use the advanced diagnostic features in vstest. I think that the moving off of using our custom |
|
In that case, I'm going to merge it unless I hear any strong objections. We can look into refactoring the logic later, as it doesn't seem directly tied to this PR. My understanding is that we already do things this way, and this is just broadening our current infrastructure a bit. |
tmat
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
![]()
|
Also docs on how to enable and customize this would be great |
|
The arcade/src/Microsoft.DotNet.Arcade.Sdk/tools/Tests.targets Lines 40 to 44 in 5f124ea
This target should either take We're hitting this when trying to update to arcade in |
@tmat just opened microsoft/vstest#2425 to track this. |

No description provided.