I have a simple .sln with 2 projects:
-- .NET standard Library
-- NUnit Test Project
The issue presents itself when I add the NUnit Test Project to the .sln because VisualStudio adds another reference to the test inside the .NET standard Library project (see picture).
Screenshot from VS Explorer:
This folder is not physically present on my laptop but still is causing several build errors for duplicate references.
To add more information:
Deleting the NUnit Test from the Library project will make the Test unavailable.
enter image description here
I've found the culprit even though I'm not sure why it behaves like that.
My solution structure was
-- sln
-- Folder
-- .Net Library
-- NUnit Test
Eliminating the folder will eliminate this strange behavior and adding the NUnit test will not create a duplicate inside the .Net Library.
Related
I've recently jumped into cross-platform development and wanted to just bite the bullet and go straight into the newest framework that the dotnet team has started working on, MAUI.
The issue I've run into is trying to add another test project in the solution and referencing the MAUI project. As I'm pretty new to Visual Studio as well, this may just be a rookie mistake and I just don't know what I'm doing, but here I am asking away.
What I've done:
Created MAUI project with the default template in Visual Studio 2022 Preview 17.2.0, with target frameworks (net6.0, net6.0-android & net6.0-ios)
Added XUnit test project on the side with target framework (net6.0)
Added UseMaui=true as a property of the test project
I've also tried to add all the target frameworks into the project, but that causes more issues than it solves. I've tried to follow this open source project where they got it to work, but I'm unsure how to achieve it.
Some screenshots
Test Project .csproj
Alt+Enter of class not being imported
Manually added import because suggestions did not add them
Error in Test Project
Test Project
This link may be helpful.
https://www.softwaremeadows.com/posts/net_maui_progressing_from_a_default_project_part_6_-_revisiting_unit_testing/
Summary:
In your .csproj file, add 'net6.0' to TargetFrameworks as below.
<TargetFrameworks>net6.0;net6.0-android;net6.0-ios;net6.0-maccatalyst</TargetFrameworks>
Modify OutputType to use Condition.
<OutputType Condition="'$(TargetFramework)' != 'net6.0'">Exe</OutputType>
Its probably because of mismatch in project target frameworks. Easy fix is to add Target Framework to your maui project that matches the one used in test project. For example if your Test poject is base on net6.0, just add net6.0 as a target framework to your maui app project.
Edit 1:
Also sometimes you need to add empty start point for netX.X build, looking like this
public static void Main(string[] args)
{
}
I created a fresh solution with .Net Core exe project. I added an MSTest v2 project too.
I ran Analyze Code coverage for All tests, but I have ony received coverage data fot the test project, and not for the main .Net Core project.
Then I have added a .Net Core dll, still no sucess.
Then I have added .Net Framework exe and .Net Framework dll. I rebuilt a solution and ran Code coverage, but still only MSTest V2 project appears in the results.
Then I have added an Nunit project. This time the result shows MSTest v2 and Nunit project, but none of the projects to be tested.
I also tried to add [ExcludeFromCodeCoverage]. I tried to enable Autodetect runsettings file. Nothing helped.
I also tried adding this code to main project:
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DebugType>Full</DebugType>
</PropertyGroup>
No effect.
I read that if I add a custom runsettings file, things might start to work. However, I think this is just a workaround, as when I asked to run Code Coverage on my collegue's Visual Studio, all projects appear in the result.
Looking for solutions.
Ok, the solution is simple and stupid, but still may solve a tonne of time to an unexperienced unit tester.
The problem is that it is not enough just to add a test project and to add a reference from it to the main project. And even having a test class which does not test anything in the main project does not work.
The real solution is just to add a class which tests at least one method in the main project.
This way the code coverage will get activated and show results, showing you have one method covered. Thus, it seems not possible to have a main project in the coverage results stating 0% of the project is covered. You will always need to have at least minimal coverage.
I'm converting some existing C# projects to be defined in CMake -- moving from the previous include_external_msproject() directive to the newer full support for C#.
But I'm not seeing how to convert projects of the Visual C# Unit Test Project type. I'm able to build them as libraries, and compile them successfully -- but Visual Studio doesn't show them as unit test projects, just as regular libraries. Most crucially, the tests aren't visible to the Test Explorer.
Things I've already tried include:
Adding TestProjectType=UnitTest as a target property:
<TestProjectType>UnitTest</TestProjectType>
Adding a reference path, as follows, as a target property:
<ReferencePath>$(ProgramFiles)/Common Files/microsoft shared/VSTT/$(VisualStudioVersion)/UITestExtensionPackages</ReferencePath>
Adding Microsoft.VisualStudio.QualityTools.UnitTestFramework as a project reference (using CMake's VS_DOTNET_REFERENCES property).
I'm using Microsoft Visual Studio Professional 2015, CMake 3.13.2, .NET Framework 4.5.2 (but I suspect the issue isn't specific to my particular version combination).
Manually adding <TestProjectType>UnitTest</TestProjectType>, made my unit test project show up as unit test. Trying to figure out how to do that using cmake.
Update: the following shows the project as unittest
set_target_properties(${target_name}
PROPERTIES
VS_GLOBAL_PROJECT_TYPES "{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
)
Documentation for VS_GLOBAL_PROJECT_TYPES is here.
I found this documentation for Project Guid: Visual Studio project type guids
Thanks #bhardwajs, your answer helped me.
You can also add TestProjectType to global properties:
set_target_properties(${target_name} PROPERTIES
VS_GLOBAL_TestProjectType "UnitTest"
VS_GLOBAL_PROJECT_TYPES "{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}")
The setup is like this:
A Xamarin.Android application, which depends on Android class library
(at least that's what the template is called in VS)
Said class
library, the purpose of which (not entirely relevant, but FYI) is
interfacing with a REST service and has a dependance on the famous
Newtonsoft.Json NuGet package.
An NUnit test project for said
library.
IDE is Visual Studio 2017, latest version.
If you build and deploy the app on the phone, everything is fine.
However, if you try to run tests from the tests project, it says that it can't find the Newtonsoft library.
I've even managed to find a sort of reason: when the library gets built, it's dependancies aren't packed inside, and they are not copied to build directory.
When .apk is built for the phone, the dependancies ARE getting packed inside.
However, when NUnit project builds itself, it only takes the library, and the dependancies are nowhere to be found.
However, there's no interface to control the behaviour of NuGet "Package Reference" type dependencies (blue ones), the properties window is empty for them. And I found no way to add NuGet packages to this kind of project as a ".config" type of dependancy (grey one).
There is a workaround - you can add the Newtonsoft package to the NUnit test project, then it gets copied to the build directory and the Android library works with it, however it doesn't feel right to me. Tests don't need that reference and it has no business in that project.
How to control NuGet packages in Android Class Library?
Your workaround is the correct solution, you don't need to worry too much about it.
That is because the Newtonsoft package is not used directly in your NUnit test project, so Visual Studio / MSBuild doesn't know if your test project needs this Newtonsoft library. In order to avoid reference pollution in NUnit test project, Visual Studio / MSBuild tries to only bring references over into NUnit test project that it detects as being required by project Xamarin.Android application.
So, to resolve this issue, we often add Newtonsoft to the test project or give a copy task to copy it to the test project.
See This Thread for some more details.
Looking for an answer to another question I now found info that my described behaviour is a known problem, described by .NET developers here:
https://github.com/dotnet/standard/issues/481
Is it possible to make Visual Studio to copy all dependencies of referenced projects into the output path?
Example
In the Solution, Project A (Library, .NET Standard) defines some functions and is dependent on Library L1 (via NuGet) and Library L2 (local .dll, referenced and copied to project)
Project B (Console Application) references Project A.
When building B, The output folder contains all direct dependencies of B and A.dll. L1 and L2 are not available in the output. Therefore, the program does not work correctly.
How can I force VS to copy also L1 and L2 to the output of B?
The only way I found so far is packing A as NuGet, but this seems to be unnecessary overhead and uncomfortable. I think I am just forgetting something everyone else seems to know...
Edit (clearifying Example)
My solutions consists of two projects.
Project MongoWrapper
.NET Standard 2.0 class Library
depends on NuGet MongoDB.Driver package
Actually uses this dependency (no zombie dependency)
Project ConsoleUser
.Net Framework 4.6.1 Console Application
References MongoWrapper project
Actually uses MongoWrapper
Observation
When debugging the ConsoleUser application, it compiles and starts. During runtime, when it calls a method in the MongoWrapper which uses the MongoDB.Driver, the application crashes, as the MongoDB.Driver dependency was not copied into the output folder of the ConsoleUser.
How to fix this?
The problem was introduced by the usage of .Net Standard library and a .Net Framework application.
TLDR
Open the .csproj file of the .Net Framework project with a text editor. Inside the first PropertyGroup add the line
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
Save the file, reopen Solution in Visual Studio and perform Clean & Build
Dependencies in different project file versions
.Net Framework projects use an old version of the .csproj project files. References/Dependencies are stored in the additional packages.configfile. By default, building a .Net Framework project makes the system to search for a packages.config file in the referenced projects. If no such file is found, the build task treats the referenced project as having no dependencies. Therefore, in the example, the MongoDB.Driver library is not added.
By adding the proposed line in the .csproj project file, the build task searches the project file of the referenced project for dependencies, where they are stored in .Net Standard project files.
.Net Core projects by default search for the newer project file structure.
The default behavior for new projects can be set in the Options -> NuGet -> General -> Package Management
Is it possible to make Visual Studio to copy all dependencies of referenced projects into the output path?
Yes.
This is what publishing the application does - it prepares the application for deployment. When you publish, it will include all of the dependencies that the application requires to run in the output.
Use the Publish tool to deploy to a local folder. The exact options available depend on your app type. In Solution Explorer, right-click your project and choose Publish, and then choose Folder. For more information, see Deploy to a local folder.
Tutorial: Publish your Hello World application with Visual Studio 2017
Also see: .NET Core application deployment.