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

Improved end to end testing support for MVC applications #275

Open
javiercn opened this Issue Oct 27, 2017 · 0 comments

Comments

Projects
None yet
1 participant
@javiercn
Member

javiercn commented Oct 27, 2017

Improved end to end testing support for MVC applications

In this release we have created a new package Microsoft.AspNetCore.Mvc.Testing to help streamline
end to end testing of MVC applications using TestServer.

This package takes care of some of the typical pitfalls users run into when trying to test MVC applications
using TestServer.

  • It copies the .deps file from your project into the test assembly bin folder.
  • It sets the content root the application's project root so that static files and views can be found.
  • It provides a class WebApplicationTestFixture<TStartup> that streamlines the bootstrapping of your app on
    TestServer.

Sample end to end in memory test using xUnit

using Xunit;

namespace MyApplication.FunctionalTests
{
    public class MyApplicationFunctionalTests : IClassFixture<WebApplicationTestFixture<Startup>>
    {
        public MyApplicationFunctionalTests(WebApplicationTestFixture<Startup> fixture)
        {
            Client = fixture.Client;
        }

        public HttpClient Client { get; }

        [Fact]
        public async Task GetHomePage()
        {
            // Arrange & Act
            var response = await Client.GetAsync("/");

            // Assert
            Assert.Equal(HttpStatusCodes.OK, response.StatusCode);
        }
    }
}

Important notes

Shadow copying needs to be disabled

For end to end in-memory tests to work properly, shadow copying needs to be disabled on your test framework of choice, as it causes the tests to execute in a different folder than the output folder.
For instructions on how to do this on xUnit see https://xunit.github.io/docs/configuring-with-json.html.

Your app needs to have a CreateWebHostBuilderMethod on the Program class

By convention our WebApplicationTestFixture<TStartup> tries to find a method with the signature public static IWebHostBuilder CreateWebHostBuilder(string [] args) on the entry point class of the assembly where Startup is located. (Typically your Program class) If you don't have this method WebApplicationTestFixture<TStartup> won't be able to initialize your app in the same way it is done on a normal run. You can configure the WebHostBuilder yourself by overriding CreateWebHostBuilder on WebApplicationTestFixture<TStartup>.

The test infrastructure needs to know the content root of the application under test

To set the content root for your app, WebApplicationTestFixture<TStartup> first locate your solution file (.sln) and then make a guess about where project might be. The Content Root of the application is defined by convention as <<SolutionFolder>>/<<ProjectAssemblyName>>. For example, based on the folder structure defined below, the content root of the application is defined as c:\work\MyApp. This is important because if not set correctly to the root folder of your application under test all views and static files will not be found.

c:/work/
    MyApp.sln
    MyApp/MyApp.csproj
    MyApp.FunctionalTests/MyApp.FunctionalTests.csproj

The process for determining the folder to use as the content root when running the tests is the following:

  • WebApplicationTestFixture<TStartup> starts on the bin folder of the test project, in the example above c:/work/MyApp.FunctionalTests/MyApp.FunctionalTests/bin/<<Configuration>>/<<Framework>>
  • It navigates to the parent folder until it finds a .sln file.
  • It appends <<AssemblyName>> to the folder in which it found the .sln file and set that as the content root.

If you happen to be using a different convention for the layout of your projects, you can inherit from WebApplicationTestFixture and pass in the relative path from your solution to the application under test when calling the constructor. For example "/src/MyApp"

public class MyAppTestFixture<TStartup> : WebApplicationTestFixture<TStartup> where TStartup : class
{
    public MyAppTestFixture(string solutionRelativePath)
        : base("/src/MyApp") { }
}

@javiercn javiercn added this to the 2.1.0 milestone Oct 27, 2017

@javiercn javiercn self-assigned this Oct 27, 2017

@aspnet aspnet locked and limited conversation to collaborators Oct 27, 2017

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.