-
Notifications
You must be signed in to change notification settings - Fork 325
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
Tests' build output for netcoreapp3+ mixes the system under test with VsTest implementation details. #2279
Comments
@plioi I feel your pain, but could not find any option to disable the new behavior, I am trying to find someone who knows how to disable this, or to confirm that there is not an option to disable this. |
@nohwnd Thanks. Understandable if there's no near-term workaround. My gut says that there would need to be a larger design change in VSTest itself to avoid the need to touch the build output folder, like with .NET Framework builds. It's a little hard to recommend that folks use Test Explorer and the test SDK package, knowing that it alters the system under test. |
Hi, I've been hit by this issue. My scenario is that I've got a console application originally targetting .net framework but now upgraded to netcoreapp3.1 - the console application is using Newtonsoft.Json at version 12.0.3. I also have a separate test solution running integration tests on the application by launching it from the executable - so no project reference from the test project to the project under test. Both solutions build to the same directory. The application is fine when built and run manually, however if I then build and run the integration tests they fail as during building the test project the Newtonsoft.Json.dll has been replaced with the version used by Microsoft.NET.Test.Sdk. I have worked around this for now by adding a nuget reference to Newtonsoft.Json at the version used by my application in the tests but this has cost me a few hours of digging and I don't think my workflow is too rare. |
Some of the implementation details in VsTest, as it prepares to ultimately invoke the test host, makes it look like the primary intended path is for the bin/ folder to NOT contain all these extra assemblies and support files, and that the mode everyone is experiencing was supposed to just be a fallback case. |
Microsoft, this is a critical bug in your product! Why has it not been addressed in over six months? |
@plioi Would be helpful if you could maybe post a few notes on what you've found so far, to help anyone who might want to dig into this further (because apparently Microsoft doesn't care). |
I'm uncertain what the answer should be, but things that come to mind: Evidence that this was unintended is that // If we are here it means it couldn't resolve testhost.dll from nuget cache.
// Try resolving testhost from output directory of test project. This is required if user has published the test project
// and is running tests in an isolated machine. A second scenario is self test: test platform unit tests take a project
// dependency on testhost (instead of nuget dependency), this drops testhost to output path. It seems that the intended-edge case has become the only case. All the work above this comment to traverse the deps file is probably no longer taking action in practice. I suspect that the fact that .NET core test projects get marked as an EXE with an injected empty Main() method has the unintended side effect of dumping all the references into the build output folder, even these development-only dependencies. That didn't happen in the .NET Framework case, since a library test project wasn't ambiguous. Since a netstandard test project would be ambiguous, the test SDK marks it as a console exe in fact. So we get a build output folder using those semantics? To be clear though, as a test framework author myself, having test projects be in-fact console exe's is incredibly valuable. So that makes me wonder whether the resolution can come from taking further control over the way the test SDK's referenced libraries are treated. A concept I've always struggled with, but which might be a part of the answer, is things like the |
Unfortunately, this does not have an easy solution. Whether or not we copy the dlls into the output folder does not make a huge difference here. User code will end up running in testhost.exe into which we load it, together with all the necessary dependencies, including Newtonsoft.Json. There is no AssemblyLoadContext isolation, so you will end up together in the process with Newtonsof.Json types, even if you load them from a nuget folder. Test platform keeps it's external dependencies to a minimum, there is Newtonsoft.Json, and NuGet.Frameworks. Newtonsoft.Json is copied into user folder, and previously the version used was very old (9.x.x), so the user can upgrade it when needed. This upgrade happens automatically by NuGet package version resolve during, so if user is choosing a newer version (e.g. 13.x.x) it will be used. Since then there were many security updates to Newtonsoft.Json and we pushed the version up to the latest (13.x.x), and so should your project. But you are right, if user depends on older version of Newtonsoft.Json we will upgrade them, and influence their main app. This is unfortunately a limitation of the current solution, and we cannot really fix without rolling our own json infrastructure, which is not something we want to commit to just now. |
This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 10 days. |
NOT STALE. |
This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 10 days. |
1 similar comment
This issue has been automatically marked as stale because it has been marked as requiring author feedback but has not had any activity for 10 days. |
Description
.NET Core 3 changed the default behavior of a project's build output folder (see "Build copies dependencies"). For test projects, this has the unfortunate side effect of polluting the test projects' build output folder with test-running infrastructure. In addition to being visually jarring (which is not important), this changes the system under test. The system under test is no longer the one the user intended:
Context in this image:
For instance, the popular Newtonsoft.Json.dll used by the VsTest infrastructure gets copied out here beside the system under test, which could negatively impact behavior if the system under test has its own reference to some other version of the assembly. This is just one example. Even if the user's desired version of Newtonsoft.Json happens to be the one present, the underlying problem remains: we're not testing what we think we are testing. The build output folder is a mix of the system under test, the test adapter's own dependencies, and VsTest testhost infrastructure.
There's hope that this mixing of multiple systems isn't truly necessary:
So, there are two questions:
It appears that the Test SDK's use of NuGet package dependencies essentially overwrites the system under test, and might be the root cause.
Steps to reproduce
Create a solution with a single test project which targets both netcoreapp2.1 and netcoreapp3.1. Build. Inspect the build output folders for both target frameworks.
Expected behavior
Build output folder contains the system under test.
Actual behavior
Build output folder contains a mix of the system under test, the test adapter's own dependencies, and the VsTest infrastructure.
The text was updated successfully, but these errors were encountered: