Possible bug
Create a new app and add an integration test project
dotnet new mvc -n WebApp --target-framework-override net461
dotnet new xunit -n WebApp.IntegrationTests --target-framework-override net461
dotnet new sln -n Sample
dotnet sln add WebApp\WebApp.csproj
dotnet sln add WebApp.IntegrationTests\WebApp.IntegrationTests.csproj
dotnet add WebApp.IntegrationTests\WebApp.IntegrationTests.csproj reference WebApp\WebApp.csproj
dotnet add WebApp.IntegrationTests\WebApp.IntegrationTests.csproj package Microsoft.AspNetCore.Mvc.Testing
dotnet build
Make UnitTest1.cs implement IClassFixture<WebApplicationFactory<Startup>>
Compile it with:
dotnet msbuild /p:OutputPath=C:\temp\SampleOutput /p:GenerateProjectSpecificOutputFolder=true /p:OutDirWasSpecified=true /p:platform="any cpu" /p:configuration="debug"
The file WebApp.deps.json is copied in the wrong folder when compiling the application with these additional msbuild parameter /p:OutputPath=C:\temp\SampleOutput /p:GenerateProjectSpecificOutputFolder=true /p:OutDirWasSpecified=true, in this case it's C:\temp\SampleOutput instead of C:\temp\SampleOutput\WebApp.IntegrationTests, this leads to the following excfeption when trying to run the integration tests:
System.InvalidOperationException : Can't find'WebApp.deps.json'. This file is required for functional tests to run properly. There should be a copy of the file on your source project bin folder. If that is not the case, make sure that the property PreserveCompilationContext is set to true on your project file. E.g '<PreserveCompilationContext>true</PreserveCompilationContext>'. For functional tests to work they need to either run from the build output folder or the WebApp.deps.json file from your application's output directory must be copied to the folder where the tests are running on. A common cause for this error is having shadow copying enabled when the tests run.
Inspecting the build log with MSBuild Log Viewer I found that this copy is added by the Microsoft.AspNetCore.Mvc.Testing.targets
I was able to workaround this problem duplicating the CopyAdditionalFilesTarget in my integration project and changing line 56 from
<Copy SourceFiles="%(DepsFilePaths.FullPath)" DestinationFolder="$(OutputPath)" Condition="Exists('%(DepsFilePaths.FullPath)')" />
to
<Copy SourceFiles="%(DepsFilePaths.FullPath)" DestinationFolder="$(OutDir)" Condition="Exists('%(DepsFilePaths.FullPath)')" />
Microsoft.AspNetCore.Mvc or Microsoft.AspNetCore.App or Microsoft.AspNetCore.All:Latest 2.1.x
:Edit Fixed line number
Thanks for contacting us, @ilmax.
@javiercn, can you please look into this? Thanks!
@pranavkm Any idea on this? Should we use OutDir or OutputPath?
@pranavkm Should we just try one of them first and fallback to the other one?
@ilmax could you give me some background as to why you're specifying the OutDirWasSpecified flag? The only documentation I could find for that switch says that it's meant for packaging projects which really doesn't make sense in the context of an integration test project.
@pranavkm sure, essentially we are using it in our CI build on VSTS. We are building all our solutions to the $(Build.BinariesDirectory), these are the msbuild arguments we are using:
/p:OutputPath=$(Build.BinariesDirectory) /p:GenerateProjectSpecificOutputFolder=true /p:OutDirWasSpecified=true
This allows to re-create the project structure in the $(Build.BinariesDirectory) directory, so every project create it's own directory into $(Build.BinariesDirectory) and all the assets (dlls, configs and so on) are copied into this directory, but the WebApp.deps.json is not copied to the correct directory, making integration test fail with the aforementioned exception.
Essentially $(OutputPath) points to $(Build.BinariesDirectory) instead $(OutDir) points to the correct location, i.e $(Build.BinariesDirectory)\$(ProjectName).
Please note that everything but the deps.json is correctly copied to the expected location.
You can reproduce this behavior following the steps above, just make sure to build the project into a different folder, i.e. OutputPath should point to a different directory.
I've verified that changing the target to use $(OutDir) works in the normal scenario as well
Ahh. Sorry, I hadn't correctly read through the issue and for thought you were recommending using OutputPath over OutDir. The documentation does recommend using OutDir so should be safe to just use it consistently.
@ilmax We鈥檒l be happy to take a PR for this if you want to contribute it.
@javiercn sure, I can do it tomorrow CET time
@ilmax Sounds good. Thanks for contributing!
Thanks for the PR @ilmax