How to disable parallelization of xunit assemblies - c#

I have a solution written on c#, .netcore 2.2 and the testing framework is xunit that looks pretty much like this:
-src
--controllers
--services
-test
--controllers.integrationtest
--services.integratiotest
we are performing some integration test with two distinct dlls (controllers.integrationtest.dll & services.integrationtest) that use the same database (solutionname.test)
now, when I run "dotnet test" on the solution, it seems that the two dlls are trying to access the same resource (database) and one dll gets a deadlock.
The thing is that I want to disable the parallel execution of the dlls when I run "dotnet test" to avoid that deadlock, so I search that up and the documentation says that to disable parallel execution of dlls you have to:
Add a xunit.runner.json in the root of the csproject which I did and works fine. (this is working on visual studio because I tested it with another feature that deletes the "_" character of test names: [methodDisplay])
Configure xunit.runner.json file to copy always or preserve newest in visual studio so that gets copied on bin folder (as any appsetings.json file)
I've read that you can place an assembly attribute in the assemblyInfo.cs file that by the way it seems that was replaced by the plain csproj so I'm a bit confused.
The ultimate goal that I want to achieve is that when devops use dotnet test the integration test doesn't blow up on concurrency problems.

In xUnit the default value for ParallelizeAssemblies is false so I can only assume that a behavior of dotnet test is causing both to be executed together.
Try and run the tests using dotnet vstest. This requires the DLLS to have been built.
dotnet vstest **/*test.dll

Related

Some Unit Tests are not running in ADO Pipeline (tests from other test projects successfully run). Dotnet test using moq

I have a solution, it has 4 projects, each project has a corresponding test project in a "tests" solution
I've noticed that sometimes a test fails locally but passes the CI build, and depending where the test is located, sometimes it does successfully fail on CI build.
Our ADO pipeline steps looks like:
Here is a csproj from a test project that is running successfully:
Here is a csproj from a test project that isnt running:
Any ideas? I have narrowed down some test classes that I know are running, but I cant tell what is different about those class' csproj versus the ones that are not running.
Turns out the test project that was not running was created outside of other projects:
when i manually move it in finder, and try to replace the reference paths in the csproj to reflect how the paths in the functioning test projects are laid out, the project refuses to load.
anyone know how to easily and safely refactor/move this project??
the best solution here is to create a new project, name it similarly (or name it whatever) then delete the old one once its running properly, and finally rename the new one to the old name

XamarinAndroid task in Azure DevOps pipeline failing without reason

I have a Xamarin Forms app for Android, which works perfectly fine when I build it locally in VS. I've set up a pipeline to build it in Azure DevOps, too, but the XamarinAndroid#1 task keeps failing without any actual error messages; it just stops. The corresponding "error message" in the pipeline view is just "No message found for this issue". I even added a VSBuild#1 task before, which successfully compiles all projects (including unit tests, which all succeed).
The failing task itself is nothing special, pretty default stuff:
- task: XamarinAndroid#1
inputs:
projectFile: '**/*droid*.csproj'
outputDirectory: '$(outputDirectory)'
configuration: '$(buildConfiguration)'
jdkOption: 'JDKVersion'
It even used to work, too, before adding an indirect dependency to another library, which in turn has a few NuGet dependencies. Both NuGetToolInstaller#1 and NuGetCommand#2 also work perfectly fine in the beginning of the pipeline, finding, installing, and verifying all external packages. And as mentioned before, locally everything works fine, and even the plain VS build task has no problem building everything. I can even see in the build log of the XamarinAndroid-task that the newly added library builds without any errors. Only when it claims to build my actual Xamarin project does it silently die.
The last few lines of that build log are these:
...
CoreGenerateAssemblyInfo:
Skipping target "CoreGenerateAssemblyInfo" because all output files are up-to-date with respect to the input files.
CssG:
Skipping target "CssG" because it has no outputs.
CoreCompile:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\Roslyn\csc.exe /noconfig /unsafe- /checked- [... all the build options in the world ...]
Using shared compilation with compiler from directory: C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\Roslyn
XamlC:
Compiling Xaml, assembly: obj\Release\netstandard2.0\[My Main Xamarin Project].dll
Finishing: XamarinAndroid
Any pointers to what could be the problem, where to look (is it my project, a Nuget dependency, or the pipeline definition itself?), or how to at least get an error message out of this?
So after the (semi-legal ^^) discussion in the comments with #jdweng I found the culprit: I was indeed using different frameworks in the various libraries, which somehow let the pipeline build fail.
Since DevOps agent jobs (to my understanding) always run on blank, fresh VMs, legacy files could not have been a problem (plus various un-/checkings of "clean" options didn't change anything, either). It's also important to note that everything was only about the pure building (a.k.a converting a *.sln file to an *.apk file), no actual deployment happened yet, and obviously no files were manually exchanged between local and remote machines, as everything was always built from scratch.
Detailed project structure before:
XamarinMainProject both .Net Standard 2.0
& XamarinMainProject.Android
'-> ViewModelLibrary .Net Framework 4.6.1
'-> OneCodeLibrary .Net Framework 4.6.1
'-> TheOtherLibrary .Net Standard 2.0
Interestingly everything worked fine (locally AND on DevOps) when TheOtherLibrary was not included in the build. But as soon as it was referenced, the DevOps Build failed as described above, while locally everything just kept on going as expected.
Now I have recreated the two 4.6.1 projects as .Net Standard 2.0 and the pipeline is happy, too.
This of course raises several questions still:
Why did it work locally (and even on DevOps with a VSBuild task), but not on DevOps for the XamarinAndroid task?
Almost more importantly: Why was there no error message at all (let alone a helpful one)?
Should this be reported as bug to Xamarin (and if so, any hints on where to do so)?

How do I install NUnit 3 console on Windows and run tests?

I want to run tests from a console like this (being in any directory, the DLL file can be for a different .NET version):
$ nunit3-console test.dll
I googled a lot, but can't find how to set up this.
The official tutorial has nothing useful and is complete zero. Following it gets me nowhere: https://github.com/nunit/docs/wiki/Installation
It is hard to find, because there is a lot of outdated documentation, either for NUnit2 or NUnit3.
Steps:
Official NUnit3 console installers are here: https://github.com/nunit/nunit-console/releases (path is different than in docs)
Download NUnit.Console-*.msi package and install
Add to system PATH variable this: C:\Program Files (x86)\NUnit.org\nunit-console
Open command line
Type:
$ nunit3-console test.dll
// For running multiple test assemblies in parallel see: https://stackoverflow.com/a/45486444/1453525
I am using NUnit3-console.exe with Selenium WebDriver to run my automation, all of which is written in C#. I have multiple environments set up under discreet logins of Windows Server 2012.
NUnit-Console doesn't have to be "installed", although the .msi is readily available. Instead, I use the .zip and extract the files to a directory, C:\Nunit, rather than allowing the invocation to resolve from the PATH. All invocations are from a Windows Forms scheduler in the form -
C:\Nunit\NUnit3-Console.exe -work:C:\Users\xxxx\Automation\TestResults\ -out:TestResult.xml --where "name =~ 'yyyy'" --p environment=qa;browser=Firefox;browserSizeX=1200;browserSizeY=800 "C:\QA_Libraries3\zzzz.dll"
The test parameters are passed on the command line and the NUnit results plus results from the test are extracted from the TestResult.xml which is distinct for each user (environment).
What I do and recommend is to add nuget package NUnit.ConsoleRunner. Note that there are similarly named packages (NUnit.Runners, NUnit.Console) that might work too, but I know that NUnit.ConsoleRunner for sure has the nunit3-console.exe in it ... well at least the version of the package that I'm using (3.4.1) does :) Sadly, nunit versioning and packaging seems to be messy. There are lots of old docs and packages that seems to overlap. And I can't find good/solid up-to-date docs.
Anyway, once you get that package then you can run the exe that's now under your packages directory. For me it's packages\NUnit.ConsoleRunner.3.4.1\tools\nunit3-console.exe. This works well for calling from a build automation script that is in the solution folder or knows how to find the solution folder.
There's another option that although is not a direct answer to your question does get to what I assume is your desire: to run your nunit3 tests from the command line. If you add package NUnit3TestAdapter, then you can use Visual Studio's built in runner, vstest. If you open a Developer Command Prompt (or PowerShell), then it can be run as 'vstest.console' (without path info since the exe is in the path env var). Of course it has its own command syntax to learn.
I realize this thread is a bit dated, but here is how I run a specific SINGLE test.
install nunit-console (https://github.com/nunit/nunit-console/releases/latest)
Open a powershell window and run nunit3-console.exe with "--test" option set to reference the specific test you want to run (including namespace and class). and finally, provide the location of the assembly where the test can be found.
Example (paths need to be adjusted to point to your specific files):
& "C:\Program Files (x86)\NUnit.org\nunit-console\nunit3-console.exe" --test=MyApp.Mvc.WebTests.CardsControllerTests.TheNameOfYourTestMethod "c:\src\MyApp.Mvc.WebTests\bin\Debug\MyApp.Mvc.WebTests.dll"
Hope this helps someone.

NUnit failed to load DLL

I am getting the following error message when trying to run unit tests in Visual Studio:
NUnit failed to load w:\Repos\trading.tools\Trading.Tools.Test\bin\x64\Debug\Trading.Tools.Test.dll
I am using
Visual Studio Community 2013
NUnit Adapter 3.4.0.0
NUnit 3.4.1
The weird thing is, that I have another project which is set up the same way as this one and it works just fine.
I also downloaded NUnit 3.4.1 and installed it. When I run
nunit3-console.exe Trading.Tools.Test.dll
everything works just fine.
Any ideas what I can do?
Many thanks
Konstantin
Edit #1
Here is the full console output from Visual Studio when trying to run all test.
Test run will use DLL(s) built for framework Framework45 and platform X86. Following DLL(s) will not be part of run:
Trading.Tools.Test.dll, Trading.Tools.dll are built for Framework Framework45 and Platform X64.
Go to http://go.microsoft.com/fwlink/?LinkID=236877&clcid=0x409 for more details on managing these settings.
NUnit Adapter 3.4.0.0: Test discovery starting
NUnit failed to load w:\Repos\trading.tools\Trading.Tools.Test\bin\x64\Debug\Trading.Tools.Test.dll
Assembly contains no NUnit 3.0 tests: w:\Repos\trading.tools\Trading.Tools\bin\x64\Debug\Trading.Tools.dll
NUnit Adapter 3.4.0.0: Test discovery complete
As you can see it is very obvious that NUnit expects a x86 build, but I build for a x64 platform. And again, my x64 build works just fine if I execute it using nunit3-console.exe.
What I see in the csproj file is this:
<Reference Include="nunit.framework, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\NUnit.3.4.1\lib\net45\nunit.framework.dll</HintPath>
</Reference>
The weird thing here is that it specifies using Version=2.6.4.14350 but referencing a 3.4.1 dll.
So the next question from this point is how can I make NUnit execute my x64 build? Any ideas?
I had a similar issue, the key is the fact that it is the Test Runner in Visual Studio that is stating that only x86 assemblies will be tested. I am assuming from this that it then forces the use of the x86 NUnit runner. To change this (in VS2015 and VS2017 at least), go to Test > Test Settings > Default Processor Architecture > X64.
You can also set the execution target in the runsettings file. You then have to select that file. This should make the solution more stable.
A runsettings file which only set this can look like:
To enable it, do as shown in the figure below:
When you select it from the test menu (1), it will be added as the selected one in the menu (2), and a Rebuild will then make the test appear in the Test Explorer (3)
There is an extra bonus by using a runsettings file, and that is that it will then run properly on the TFS Build system, if you use that. I have written a blog post on that issue, see http://hermit.no/how-to-control-the-selection-of-test-runner-in-tfsvsts-making-it-work-with-x86x64-selected-targets/
I couldn't execute my tests and found that to be one of the issues. It turns out that my TestFixture was internal. Just switching it to public solved my case.
After unsuccessfully trying all other responses above, the following worked for me:
In my case the .NET project and solution is on a mounted drive (I use a MacBook and Parallels for .NET development). The mount also contains the /bin/debug and /bin/release locations where NUnit was attempting to read the "test" DLL from.
The fix was to move the solution/project files to the C: drive of my Windows image. The tests were discovered immediately.
Apparently the shared/mounted location was not to its liking. I don't know why, since the mount is permanent and read/writable to all users on the Windows image. I suspect file permissions problems or maybe somehow the entire mount is not accessible to the user/process running the NUnit discovery logic.
I happened to get this error when writing the unit test method. And noticed the root cause that one of the dependent dll was missing to load. This error("NUnit failed to load the .dll") was shown in the Output("Test") window after modifying the test method code and trying to run it. After updating the nuget package for the dependent dll, nunit started picking the test project dll and test cases got executed.
Today I was running into this issue as well (on a .NET Framework 4.8 based NUnit project). The solution for me was to also install the Microsoft.NET.Test.Sdk package.
To get to the root cause, it may help to attempt to run your tests using the NUnit CLI.
In my case, the CLI logged a bind failure I didn't see in Visual Studio. After I had fixed that, my tests ran correctly via CLI and VS.
I got this error in a .Net 6.0 Asp.Net solution and here's how I solved it.
It was only occurring in one Test project whose tests wouldn't run, the other Test projects were running fine in Test Explorer and in Debug.
The tests that were failing to be detected had "Test Not Run":
In the Output is the error:
NUnit Adapter 4.3.1.0: Test discovery starting NUnit failed to load [dll path]
No test is available in [dll path]
What I did was comment out each class and bring them back one by one until the Tests would STOP to RUN. Then with the failing class put a break point on a [Test] method.
If you can't hit the break point then its failing in this classes [SetUp]. Put a BreakPoint in the [SetUp] and use F11 to step off the edge of the method, ie F11 off the final curly brace..
AND THEN you get a prompt saying which DLL it can't load.
In my case it was “couldn’t load a DLL Microsoft.AspNetCore.Mvc.Core”
Referencing the DLL via Package Manager resolved the problem.
Edit: if this happens in a Unit Test you may want to reference the Microsoft.AspNetCore.App FrameworkReference rather than the Microsoft.AspNetCore.Mvc.Core package reference:
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>

Prevent MSTest from copying / deploying every dll

When running MSTest from Visual Studio - the unit test execution time is relatively quick.
When running MSTest from the command line, with /testsettings flag - the execution takes forever and that is because it spends 95% of its startup time copying the dll's to its Out folder. Is there a way to prevent this?
The default Local.testsettings in the project has no modifications to it (which also means it is empty). However, if I try to use that same file from the command line, MSTest complains about missing DLL's that the Unit Test reference.
Have you tried disabling deployment in the test settings? When it is disabled, the tests should be run in-place rather than on copied assemblies. (See http://msdn.microsoft.com/en-us/library/ms182475.aspx for details.)
try MSTest.exe /noisolation http://msdn.microsoft.com/en-US/library/ms182489.aspx

Categories

Resources