-
Notifications
You must be signed in to change notification settings - Fork 152
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
Error running tests from assembly built using VS2017 csproj file format #291
Comments
Excellent report, thanks. As a temporary workaround, although not a great one, you should be able to use the Visual Studio adapter and the |
@rprouse Thank you for the suggestion, I'll give that a try. |
@ManfredLange @rprouse Maybe I'm behind the curve. Can one of you explain why this is a bug? NUnit is supposed to work from assemblies and only assemblies. It does nothing to load any assembly but the first one and all resolution is done by the runtime or - in the case of dynamically loaded assemblies - by the appication itself. If this were to be implemented, how would you run tests deployed for QC for example? |
Yes, I agree, it should be able to work off an assembly only. However, with the change in the tooling it seems that it is not sufficient to simply point nunit3-console to the assembly. Execution will fail with the FileLoadException reported in this issue. I just reproduced this issue once more, this time building the project using "dotnet build". It builds fine, just like building from VS2017. Those two build options appear to do the same. I also tried "dotnet publish" (with no further options), which just copies everything into a target folder but unfortunately does't solve the issue. Both scenarios, with and without publish, have the dependent packages files right in the folder of the test assembly (eg bin/Debug/net461). Still the runtime doesn't load them automatically for some reason. Perhaps it treats them as "private paths"? I then tried the following: I wrote a little console app targeting net461 (yup that works) and added some code that loads the test assembly. It retrieves the tests from the assembly (using reflection based on full type names) and then executes them. No need for a NUnit reference in the console app. However, I had to add an AssemblyResolve event handler that loaded the assembly (ie the dependency) sitting right next to the test assembly. Without the event handler my little prototype ran into the same problem. With the event handler present it worked just fine. In my opinion this small experiment seems to suggest that either the console or the engine may need an AssemblyResolve event handler that can handle this scenario. Or - another option - it may require a different type of AppDomain setup although we need to be aware that the AppDomain concept is not the same under .NET Core. For now I'll be using "dotnet test" which seems to do the work. Unfortunately this comand doesn't like the solution file because that runs into a different bug unrelated to NUnit (and already reported and worked on someplace over at the msbuild guys). I already have a workaround in place for that other, unrelated bug. |
@CharliePoole, the issue is that Visual Studio doesn't copy dependent assemblies into the bin directory when it builds using the new project format. |
Understood. That was my points to why it shouldn't be seen as an NUnit issue. |
I'll revisit this issue as it appears as if there is yet another factor at play. I need to investigate this further. Update: Nope, false positive. This issue remains to be reproducible using the steps to reproduce despite the file in question actually actually being present in the output directory. Here is are the assemblies in play in this scenario:
So it's testAssembly -> assemblyUnderTest -> Autofac (all targeting .NET Framework 4.6.1) The full text of the exception for steps 3 and 4 is identical and is as follows: System.IO.FileLoadException : Could not load file or assembly 'Autofac, Version=4.0.0.0, Culture=neutral, PublicKeyToken=17863af14b0044da' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) Next, I added the packages "NUnitTest3Adapter" and "Microsoft.NET.Test.Sdk". As suggested "dotnet test" now works which is great. But here is the surprise: nunit-console works now as well even though none of the two of them references "Autofac". Next, I removed package "Microsoft.NET.Test.Sdk" and nunit-console fails again with FileNotFoundException To make a cross-check I added "Microsoft.NET.Test.Sdk" back in and removed "NUnit3TestAdapter". nunit-console works again. So the work around for the reported issue this: add package "Microsoft.NET.Test.Sdk" and nunit-console will find assemblies that are already in the output dir - "Autofac" in my scenario. |
Assuming in my quick check I found the correct line of code there appears to be at least one instance where package Microsoft.NET.Test.Sdk adds an AssemblyResolve event handler. This could potentially explain why nunit-console works with this package referenced and fails while the package is absent. It may also point towards a possible solution in either nunit-console or the nunit engine. Perhaps an appropriate AssemblyResolve event handler would fix the issue. I used this approach as well in my little console app prototype and that executed the tests without the FileLoadException. |
I would agree in principle, but we aren't going to change the way that .NET builds. We also support it with the I wonder however if adding the This could be a documentation issue. |
My two cents: I think adding Microsoft.NET.Test.Sdk is a workaround for the new csproj format. Based on the experiments it appears that all that is needed is an appropriate AssemblyResolve event handler. Everything else coming with Microsoft.NET.Test.Sdk may not be needed. But then again, that package may not be too much of a burden in the first place. If that is the case, perhaps making it a dependency for NUnit for projects in the new csproj format might be the best option. |
@ManfredLange I would have no problem with using an AssemblyResolve handler if we could do it well. What I'm not clear on is how NUnit can know where to look for the assembly in order to resolve it. The engine has no knowledge that it is running in an output directory created by VS and certainly doesn't know what project format was used. Some application that's calling the engine has to tell it. That makes sense to me if the runner is the VS adapter but not so much sense in the general case. However, I may be missing something so feel free to fill me in. 😄 BTW, we already use an AssemblyResolve event handler for certain things, so if this is done it should probably be added to that one. |
@ManfredLange BTW - in case you were not aware - I'm on vacation and many of my limited responses are via my cell. Hence, the infrequency and lack of detail in my posts. 😄 |
Needs to be re-confirmed using the 4.0 codebase. |
@ManfredLange I'm attempting to clean up very old issues like this one. Although it hasn't been worked on explicitly, SDK-format projects are now supported and various other issues are resolved in the latest 3.16 development builds on MyGet. I think this is probably still valid, but it will help if you can try your case using one of the dev builds. You should use the latest 3.16 build rather than any of the 4.0 builds - I'll be porting changes to main (and 4.0.--devxxxxx) after the 3.16 release. |
This issue has been resolved in version 3.16.0 The release is available on: |
Steps to reproduce:
This fails with FileLoadException because the files of the other nuget package, e.g. Autofac, cannot be loaded. They are not copied to TargetDirectory during build. [Update 16 Sep 2017: I stand corrected: the files are copied but nunit-console still falls over with the FileLoadException. I'll re-run the scenario to confirm again and rule out other causes.]
Step 1 can be replaced with using "dotnet new classlib" at a command prompt or in a powershell.
Environment
Visual Studio 2017 version 15.4 with packages NUnit 3.8.1, NUnit.ConsoleRunner 3.7.0 and Microsoft.Net.Compilers 2.3.2 and using dotnet version 2.0.0.
Expected Behavior
NUnit engine should resolve and load assemblies that the test assembly may depend on, e.g. using the information from obj/project.assets.json of the test project created in step 1 above.
Notes
This may already be filed as an issue. I searched existing issues but couldn't find anything obvious. I apologize if this is a duplicate.
The text was updated successfully, but these errors were encountered: