DotNet Core run test once at time - unit-testing

I'm looking for a way for my xUnits to run tests one at a time (dotnet test (version core 6)). Both from code and configuration.
In particular, the tests will have to be launched via an action on github
Thanks

You could use xunit.runner.json file:
{
"parallelizeAssembly": false,
"parallelizeTestCollections": false
}
And then in your csproj
<ItemGroup>
<None Update="xunit.runner.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
You can also write in code
[assembly: CollectionBehavior(DisableTestParallelization = true)]

Related

TextTemplating target in a .Net Core project

I have recently migrated a test project to .NET Core 2.0. That test project used text templates to generate some repetitive code. The previous project had a build target to generate all T4-templates before build. Therefore, the generated code is also not checked in into the VCS.
I had used this snippet in the project to ensure that templates are built:
<PropertyGroup>
<!-- Default VisualStudioVersion to 15 (VS2017) -->
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
<!-- Determinate VSToolsPath -->
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<!-- Run T4 generation if there are outdated files -->
<TransformOnBuild>True</TransformOnBuild>
<TransformOutOfDateOnly>True</TransformOutOfDateOnly>
</PropertyGroup>
<!-- Import TextTemplating target -->
<Import Project="$(VSToolsPath)\TextTemplating\Microsoft.TextTemplating.targets" />
My first approach was to keep this fragment and copy it to the new .NET Core project file.
Inside Visual Studio, this works because apparently, VSToolsPath is set correctly. However, when I run the .NET Core SDK tools, as for example dotnet test (as I do on the build server), VSToolsPath maps to Program Files\dotnet\sdk\2.0.3 and there, the text templating targets cannot be found.
Because that did not work, I also tried to simply install the Microsoft.VisualStudio.TextTemplating package from Nuget but that has two problems:
it does not officially support .NET Core and installs for .NET 4.6.1 and
Nuget does not seem to install anything, so I cannot adjust the paths in the project file.
To support building T4 templates while building dotnet build you need to use Custom Text Template Host, which already exists for .NET Core (https://github.com/atifaziz/t5). To include it, add to your project in any ItemGroup this element:
<DotNetCliToolReference Include="T5.TextTransform.Tool" Version="1.1.0-*" />.
As Visual Studio already has it's own Text Template Host implementation, your added element should be conditioned only for .NET Core. For example:
<ItemGroup Condition="'$(MSBuildRuntimeType)'=='Core'">
<DotNetCliToolReference Include="T5.TextTransform.Tool" Version="1.1.0-*" />
</ItemGroup>
And at the same time you should condition out of .NET Core your settings for Visual Studio's Text Template Host, like this: Condition="'$(MSBuildRuntimeType)'=='Full'".
You should also add <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" Condition="'$(MSBuildRuntimeType)'=='Full'" /> before importing Microsoft.TextTemplating.targets to make everything work correctly with .NET Core csproj in Visual Studio.
If you need to be able to clean up all generated code, you should rename your templates from *.tt to *.Generated.tt, all the code will be generated under *.Generated.cs and it will be possible to filter these file out at dotnet clean action.
The complete example of what it will look like in your csproj:
<!-- T4 build support for .NET Core (Begin) -->
<ItemGroup Condition="'$(MSBuildRuntimeType)'=='Core'">
<DotNetCliToolReference Include="T5.TextTransform.Tool" Version="1.1.0-*" />
<TextTemplate Include="**\*.Generated.tt" />
<Generated Include="**\*.Generated.cs" />
</ItemGroup>
<Target Name="TextTemplateTransform" BeforeTargets="BeforeBuild" Condition="'$(MSBuildRuntimeType)'=='Core'">
<ItemGroup>
<Compile Remove="**\*.cs" />
</ItemGroup>
<Exec WorkingDirectory="$(ProjectDir)" Command="dotnet tt %(TextTemplate.Identity)" />
<ItemGroup>
<Compile Include="**\*.cs" />
</ItemGroup>
</Target>
<Target Name="TextTemplateClean" AfterTargets="Clean">
<Delete Files="#(Generated)" />
</Target>
<!-- T4 build support for .NET Core (End) -->
<!-- T4 build support for Visual Studio (Begin) -->
<PropertyGroup Condition="'$(MSBuildRuntimeType)'=='Full'">
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<!-- This is what will cause the templates to be transformed when the project is built (default is false) -->
<TransformOnBuild>true</TransformOnBuild>
<!-- Set to true to force overwriting of read-only output files, e.g. if they're not checked out (default is false) -->
<OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
<!-- Set to false to transform files even if the output appears to be up-to-date (default is true) -->
<TransformOutOfDateOnly>false</TransformOutOfDateOnly>
</PropertyGroup>
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" Condition="'$(MSBuildRuntimeType)'=='Full'" />
<Import Project="$(VSToolsPath)\TextTemplating\Microsoft.TextTemplating.targets" Condition="'$(MSBuildRuntimeType)'=='Full'" />
<!-- T4 build support for Visual Studio (End) -->
If you don't want to rename your template files and you don't need to clean up them, then replace:
<TextTemplate Include="**\*.Generated.tt" />
<Generated Include="**\*.Generated.cs" />
with:
<TextTemplate Include="**\*.tt" />
And delete:
<Target Name="TextTemplateClean" AfterTargets="Clean">
<Delete Files="#(Generated)" />
</Target>
For more information see:
How to set up code generation on dotnet build:
https://notquitepure.info/2018/12/12/T4-Templates-at-Build-Time-With-Dotnet-Core/
How to set up code generation on build for Visual Studio and .NET Core csproj:
https://thomaslevesque.com/2017/11/13/transform-t4-templates-as-part-of-the-build-and-pass-variables-from-the-project/
The full example of the generation of multiple files from a single T4 template:
https://github.com/Konard/T4GenericsExample
Update:
GitHub.com/Mono/T4 is even better.
You are at the mercy of someone writing a port for dotnet core.
This is old: http://www.bricelam.net/2015/03/12/t4-on-aspnet5.html
Or use a different templating tool entirely, though of course I understand if that’s not an option.
Or just use T4Executer. You can set which templates to execute before build, after build or ignore specific templates. Works good with VS2017-19
To expand on Konard's comment of "Update: https://github.com/mono/t4 is even better."
Install Mono/T4 (dotnet-t4) as a tool
If you are running an Azure devops pipeline, you can add it as a step - see the first part of https://stackoverflow.com/a/60667867/1901857.
If you are building in a linux dockerfile, add this before you build (we were using .net 6 on alpine, but it should be fine with other distros and versions):
# you will see a warning if this folder is not on PATH
ENV PATH="${PATH}:/root/.dotnet/tools"
RUN dotnet tool install -g dotnet-t4
If you want to use the tool on your dev machine, instead of VS TextTemplating, run a one-off install from powershell (but every dev in your team will need to do this):
dotnet tool install -g dotnet-t4
Run t4 on build - dev machine and pipeline
dotnet-t4 is setup very similarly to t5 in Konard's answer
Option 1 - dotnet-t4 installed on your dev machine
Add this to your csproj file. No conditional settings required.
<!-- T4 build support for .NET Core (Begin) -->
<ItemGroup>
<TextTemplate Include="**\*.tt" />
</ItemGroup>
<Target Name="TextTemplateTransform" BeforeTargets="BeforeBuild">
<ItemGroup>
<Compile Remove="**\*.cs" />
</ItemGroup>
<Exec WorkingDirectory="$(ProjectDir)" Command="t4 %(TextTemplate.Identity)" />
<ItemGroup>
<Compile Include="**\*.cs" />
</ItemGroup>
</Target>
<!-- T4 build support for .NET Core (End) -->
Option 2 - use VS templating on your dev machine
If you don't want everyone to install the tool locally, you can still add conditional build steps to the project, as per Konard's answer. Note that Visual Studio is now 64-bit, so you can use MSBuildExtensionsPath instead of MSBuildExtensionsPath32:
<!-- T4 build support for .NET Core (Begin) -->
<ItemGroup Condition="'$(MSBuildRuntimeType)'=='Core'">
<TextTemplate Include="**\*.tt" />
</ItemGroup>
<Target Name="TextTemplateTransform" BeforeTargets="BeforeBuild" Condition="'$(MSBuildRuntimeType)'=='Core'">
<ItemGroup>
<Compile Remove="**\*.cs" />
</ItemGroup>
<Exec WorkingDirectory="$(ProjectDir)" Command="t4 %(TextTemplate.Identity)" />
<ItemGroup>
<Compile Include="**\*.cs" />
</ItemGroup>
</Target>
<!-- T4 build support for .NET Core (End) -->
<!-- T4 build support for Visual Studio (Begin) -->
<PropertyGroup Condition="'$(MSBuildRuntimeType)'=='Full'">
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<TransformOnBuild>true</TransformOnBuild>
<!--Other properties can be inserted here-->
<!--Set to true to force overwriting of read-only output files, e.g. if they're not checked out (default is false)-->
<OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
<!--Set to false to transform files even if the output appears to be up-to-date (default is true)-->
<TransformOutOfDateOnly>false</TransformOutOfDateOnly>
</PropertyGroup>
<Import Project="$(VSToolsPath)\TextTemplating\Microsoft.TextTemplating.targets" Condition="'$(MSBuildRuntimeType)'=='Full'" />
<!-- T4 build support for Visual Studio (End) -->

Live unit testing exclude tests

I know it is possible to exclude the whole test project(s) from Live Unit Testing by right clicking on the test project and selecting the "Live Unit Testing" context menu.
But in my solution I have some long running/resource intensive tests, which I would like to exclude. Is it possible to exclude individual tests?
Easiest method is right clicking on the method in the editor view and selecting Live Unit Testing and Exclude.
You can also do it programatically with attributes.
For xUnit: [Trait("Category", "SkipWhenLiveUnitTesting")]
For NUnit: [Category("SkipWhenLiveUnitTesting")]
For MSTest: [TestCategory("SkipWhenLiveUnitTesting")]
more info at Microsoft docs
Adding onto adsamcik's answer, here's how you can exclude an entire project (like an integration tests project) programmatically:
via .NET Core's csproj file:
// xunit
<ItemGroup>
<AssemblyAttribute Include="Xunit.AssemblyTrait">
<_Parameter1>Category</_Parameter1>
<_Parameter2>SkipWhenLiveUnitTesting</_Parameter2>
</AssemblyAttribute>
</ItemGroup>
// nunit
<ItemGroup>
<AssemblyAttribute Include="Nunit.Category">
<_Parameter1>SkipWhenLiveUnitTesting</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
// mstest
<ItemGroup>
<AssemblyAttribute Include="MSTest.TestCategory">
<_Parameter1>SkipWhenLiveUnitTesting</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
or via assemblyinfo.cs:
// xunit
[assembly: AssemblyTrait("Category", "SkipWhenLiveUnitTesting")]
// nunit
[assembly: Category("SkipWhenLiveUnitTesting")]
// mstest
[assembly: TestCategory("SkipWhenLiveUnitTesting")]
I figured out how to add the assembly attribute in .net core's csproj file via this SO answer. The attributes came from MS's documentation.

NodeJS addon can just be executed with self compiled nodeJS

I tried some work on compiling some C++/CLI NodeJS addons.
For example, I wanted to read from Windows Event logs.
At first, I compiled nodeJS to get the node.lib file. Basicly, I followed the steps mentioned in this document: http://coderesearchlabs.com/articles/BNWCA.pdf
I set up an VisualStudio Project with include and library paths pointing to the compiled node 0.10.28 directories.
In this project I made use of the System::Diagnostics::EventLog class: http://msdn.microsoft.com/en-us/library/vstudio/system.diagnostics.eventlog
After finishing my C++ project, I compiled it successfully and could use it with the node.exe from the first step.
Now, I tried to use my "EventReader.node" file on an other machine. But I couldn't require the node file:
Error: no error
This is the error I got after requiring the node-file.
Some hints:
Both machines run Windows 7 Professional
NodeJS version I self compiled: 0.10.28 src
NodeJS version I tried to run my addon with: 0.10.28 msi
Edit:
After using node-gyp, I need to set my references in the vxproj-file. In special these ones:
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
But how do I add these with the gyp-file?

Running unit tests for typescript in VS

I've found couple of examples of running unit tests for typescript.
All of them are based on referencing both ts and js file like
/// <reference path="../Calc.ts" />
/// <reference path="../Calc.js" />
Unfortunately when I try to reference js file I am getting the following error:
Incorrect reference: referenced file: "../Calc.js" cannot be resolved.
If there is no reference test runner doesn't load js file under test and test fails to execute.
Any ideas? Ideally I want to run tests in VS test explorer or Resharper test session.
You can use Chutzpah for that
With Chutzpah you can run your tests from command line and integrate your tests with Visual Studio Test Explorer.
Chutzpah allows you decide if you want to run the tests from .ts files, .js files, .html files or from all of them.
It also allows you to load external .js files (e.g. dependent libraries) from your .ts unit test file, with its specific :
/// <chutzpah_reference path="lib/jquery-1.9.1.min.js" />
/// <reference path="src/YourFileToBeTested.ts" />
Your unit tests can be written in TypeScript.
You can install Chutzpah from Visual Studio/Tools/Extensions and updates.
There is absolutely no reason to include a reference to a JS file :
/// <reference path="../Calc.js" />
The use for /// <reference is to provide the compiler with information about type info present in another file. It has no runtime implications, only compile time implications. And all the compile time implications (typeinfo, code generation) are taken into account when you did:
/// <reference path="../Calc.ts" />

Running unit tests from a .proj file with MSBuild

I want to run unit tests using MSBuild. Here is how I invoke msbuild today:
msbuild MySolution.sln
Instead, I want to use an MSBuild project file called "MyBuild.proj" like this:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5" DefaultTargets="Build">
<Target Name="Build">
<ItemGroup>
<SolutionToBuild Include="MySolution.sln" />
<TestContainer Include="..\Output\bin\Debug\*unittests.dll"/>
</ItemGroup>
</Target>
</Project>
And then call this command line:
msbuild MyBuild.proj
For some reason, when I do that the command succeeds immediately and the build doesn't even happen. I fear I must be missing something very obvious as I am new to MSBuild.
I suppose I really have 2 questions:
Why doesn't this even build my solution
Is the "TestContainer" element correct for executing my tests
Thanks!
You havent supplied any task to actually do anything,
inside your build target you need a call to an msbuild task, your example becomes:
<Target Name="Build">
<ItemGroup>
<SolutionToBuild Include="MySolution.sln" />
<TestContainer Include="..\Output\bin\Debug\*unittests.dll"/>
</ItemGroup>
<MSBuild Projects="#(SolutionToBuild)"/>
</Target>
this specifies what projects you actually want msbuild to build.
See:http://msdn.microsoft.com/en-us/library/vstudio/z7f65y0d.aspx for more details and the parameters it takes.
Thats part one.
As for part 2? what testing framework are you using? If using mstest id try wrapping the commandline mstest.exe in an msbuild exec statement to get it to run and execute the tests. See an example here:http://social.msdn.microsoft.com/Forums/en-US/msbuild/thread/cb87a184-6589-454b-bf1c-2e82771fc3aa