10

So as far as I have been understanding from my research. A .net Standard Library can not be used on its own, so it needs to be tested through a different framework, either with .net Framework or .net Core reference. That's just how I interpreted it. Now I am trying to create a Standard Library as I need it to be compatible on most devices as possible, the problem is I don't know how to create the unit tests correctly. Every time I create a MSTest Project I get the following error:

Test run will use DLL(s) built for framework .NETCoreApp,Version=v1.0 and platform X64. Following DLL(s) do not match framework/platform settings. Otchi.Ebml.Tests.dll is built for Framework 2.1 and Platform AnyCPU.

I have experimented a lot with the different architectures and other settings, but nothing seems to work to remove that warning. Am I doing something incorrectly or is there a different, more suitable approach to creating unit tests for a Standard Library

J.Paravicini
  • 882
  • 12
  • 39
  • 2
    As the linked answer says, your tests have to target either Core or Framework at the same .NET Standard level that your targeting your assembly. If you're targeting .NET Standard 2.0, for instance, the tests should target either .NET Core 2.0+ or .NET Framework 4.6.1+ (see https://learn.microsoft.com/en-us/dotnet/standard/net-standard#net-implementation-support). Edit the project file for Otchi.Ebml.Tests.dll and see what's in the `` node. – Heretic Monkey Oct 07 '19 at 16:35
  • Hmm ok I see, I didnt really understand the answer I linked thats why I opened a new question. I went and looked at the Tests.dll file and the value of is: netcoreapp2.1. and the library is netstandard2.0. IMO The Test TargetFramework should be netcoreapp2.0 if I am to follow your link. Is that correct? – J.Paravicini Oct 07 '19 at 16:39
  • 1
    If your wish is to be compatible on most devices, you have to create several test projects against each of them (.NET Framework 4.6.1+, .NET Core 2.0+, Xamarin, Unity, UWP, Tizen and so on). The MSTest error is simply because you created a .NET Core 1.0 project which does not even support .NET Standard 2.0. – Lex Li Oct 07 '19 at 19:56
  • @LexLi I have set up my Test Project to target the .NET Core 2.1 (netcoreapp2.1) that's why I am confused. Nothing I can find is set to .NET Core 1.0. My Library uses the Standard version and the Test is as said before. So Why is it saying I am using .NET Core 1.0?? – J.Paravicini Oct 07 '19 at 20:08
  • 1
    You might get some idea from MSBuild logging https://learn.microsoft.com/en-us/visualstudio/msbuild/obtaining-build-logs-with-msbuild?view=vs-2019 – Lex Li Oct 07 '19 at 20:12
  • Ok I have done as you said and set the logging level to normal. As said both my projects build the versions they should. But I've found that a the MSTestAdapter Nuget uses the netcoreapp1.0 version. So probably this is causing the problem. – J.Paravicini Oct 07 '19 at 20:26

3 Answers3

10

A .NET Standard Library does not contain the necessary components for execution. It only defines the execution patterns. When you deploy to a specific machine / processor architecture, the code must know which instruction set to execute upon.

This is where the .NET framework and .NET core come into play. The .NET framework contains execution details for instruction sets supported by the Microsoft Windows operating system. .NET core, similarly, contains the instruction set for additional architectures not natively supported by Windows.

To write Unit Tests, you need to create a NEW project, either in .NET or in .NET core, to execute your code. If you want to cover all your bases, or if you have some binaries that are compiled differently for different architectures (third party libraries come to mind) then you might want to unit test for multiple distributions.

Your library should be a standalone library. Your unit tests should be executed before you update the library to validate that the code being entered into the library passes. That way anyone who uses the library after that can feel confident that it will work.

Zakk Diaz
  • 1,063
  • 10
  • 15
  • So basically the .net Standard contains only the essential libraries that every .net Code Base that can be executed has to implement. That way it is certain that code written in Standard will be able to be implemented in all other .net Projects? – J.Paravicini Oct 07 '19 at 16:56
  • I have added my test Project as a seperate Project. But I don't understand why I'm getting that warning. I followed the Msdn Documentation on how to create a unit test for a c# project, so it shouldn't throw that error. – J.Paravicini Oct 07 '19 at 16:57
  • 1
    Correct! .NET standard is the most basic pattern that all the other frameworks depend upon. Your specific error seems to be for the package 'Otchi.Ebml.Tests.dll'. This DLL seems to already be compiled using .NET framework 2.1. This is an old framework & is is probably not supported in the newest .NET 4.8 - If you REALLY must use this DLL, then your project must be built using .NET 2.1. This is different than .NET Core 2.1, which was released very recently. You will need to install the relevant SDK, this might be it... https://www.microsoft.com/en-us/download/details.aspx?id=15354 – Zakk Diaz Oct 07 '19 at 17:22
  • Weird, I only created my library which is the standard 2.0, and the test library that apparantly contains the framework but it should he the core 2.0 or 2.1 version. I never specified any .net framework projects. Do you know how i could change that? – J.Paravicini Oct 07 '19 at 18:38
  • 1
    In the solution explorer, right click on your .SLN and "Add" a new project. You should get a prompt of dialogs to help you choose which project type to use. If you can't find the project types you are looking for then you must install the SDK's for those project types. If you want to manually change the targeted framework, you can do so in the project properties (Right click the .csproj, properties) or EDIT the .csproj to set "TargetFramework" manually. This method WILL NOT WORK if you do not have the relevant SDK installed or if Visual Studio cannot find it. – Zakk Diaz Oct 07 '19 at 18:41
  • What about issues related to Assembly fails when running from .Net Framework unit test project? – gayan1991 Apr 09 '20 at 13:48
0

Writing unit tests for libraries targeting .NETStandard is tricky since you have to test your code against various implementations of your chosen version of .NETStandard. As already outlined by Zakk Diaz this is due to the fact that .NETStandard merely defines types that are then implemented in actual platforms.

The most common problems are differences in implementation across various platforms like .NETFramework, .NETCore, Mono, etc. However there are also differences in implementations across various versions of platforms that can mess with the way your library works on said platforms (see this example).

This is why running your tests on the lowest version of a platform that implements your chosen version of .NETStandard doesn't quite cut it. You have to take all runtimes into account that your library could be used with.

In general you have two options to solve this issue.

Option 1

Use multi targeting to build your unit test project for all valid runtimes. This also means that you have to have a very big set of target frameworks for your unit test project which will have to be extended whenever new versions of a platform are released.

If you want to cover all relevant scenarios then you'll have dozens of target frameworks and just as many versions of your unit test project being built. Let's just assume that this can get out of hand quickly.

Option 2

Use a unit testing platform that can actually handle .NETStandard by design. Building your unit tests for .NETStandard and having those tests execute on matching runtimes will reduce complexity of your test project.

As of today, most unit testing platforms can't do any of this and you're stuck with Option 1. The one that fits this approach and actually solves your problem is Nuclear.Test.

Please note that Nuclear.Test requires .NETStandard 2.0 and only handles .NETFramework and .NETCore in its current release. This is subject to change however and i'm working on reducing the required version of .NETStandard to 1.0 and include test workers for Mono and UWP as well.

MikeLimaSierra
  • 799
  • 2
  • 11
  • 29
-2

There is an easy bypass,

Create solution with 3 projects:

  1. "Demo.NetStandard"

your .Net Standard library project

  1. "Demo.NetFramework.LinkedToStandard"

new .Net Framework library project, and copy & paste as link all .Net Standard files

  1. "Demo.Tests"

new .Net Framework test project, and Add Reference > "Demo.NetFramework.LinkedToStandard"

This way you write the code straight into your .NetStandard files, and you test it as .NetFramework code.

jacob spitzer
  • 109
  • 1
  • 8