Added functional tests for MVC.

Created a test project to hold functional tests, a basic
application for test purposes under test\WebSites and added
the first functional test to validate view rendering.
This commit is contained in:
Javier Calvarro Nelson 2014-05-19 21:56:03 -07:00
Родитель 52c2e41bbb
Коммит 931a3cd809
16 изменённых файлов: 434 добавлений и 1 удалений

29
Mvc.sln
Просмотреть файл

@ -29,6 +29,12 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "MvcSample.Web", "samples\Mv
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.Razor.Host", "src\Microsoft.AspNet.Mvc.Razor.Host\Microsoft.AspNet.Mvc.Razor.Host.kproj", "{520B3AA4-363A-497C-8C15-80423C5AFC85}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WebSites", "WebSites", "{16703B76-C9F7-4C75-AE6C-53D92E308E3C}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Mvc.FunctionalTests", "test\Microsoft.AspNet.Mvc.FunctionalTests\Microsoft.AspNet.Mvc.FunctionalTests.kproj", "{323D0C04-B518-4A8F-8A8E-3546AD153D34}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "BasicWebSite", "test\WebSites\BasicWebSite\BasicWebSite.kproj", "{34DF1487-12C6-476C-BE0A-F31DF1939AE5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -139,6 +145,26 @@ Global
{520B3AA4-363A-497C-8C15-80423C5AFC85}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{520B3AA4-363A-497C-8C15-80423C5AFC85}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{520B3AA4-363A-497C-8C15-80423C5AFC85}.Release|x86.ActiveCfg = Release|Any CPU
{323D0C04-B518-4A8F-8A8E-3546AD153D34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{323D0C04-B518-4A8F-8A8E-3546AD153D34}.Debug|Any CPU.Build.0 = Debug|Any CPU
{323D0C04-B518-4A8F-8A8E-3546AD153D34}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{323D0C04-B518-4A8F-8A8E-3546AD153D34}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{323D0C04-B518-4A8F-8A8E-3546AD153D34}.Debug|x86.ActiveCfg = Debug|Any CPU
{323D0C04-B518-4A8F-8A8E-3546AD153D34}.Release|Any CPU.ActiveCfg = Release|Any CPU
{323D0C04-B518-4A8F-8A8E-3546AD153D34}.Release|Any CPU.Build.0 = Release|Any CPU
{323D0C04-B518-4A8F-8A8E-3546AD153D34}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{323D0C04-B518-4A8F-8A8E-3546AD153D34}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{323D0C04-B518-4A8F-8A8E-3546AD153D34}.Release|x86.ActiveCfg = Release|Any CPU
{34DF1487-12C6-476C-BE0A-F31DF1939AE5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{34DF1487-12C6-476C-BE0A-F31DF1939AE5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{34DF1487-12C6-476C-BE0A-F31DF1939AE5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{34DF1487-12C6-476C-BE0A-F31DF1939AE5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{34DF1487-12C6-476C-BE0A-F31DF1939AE5}.Debug|x86.ActiveCfg = Debug|Any CPU
{34DF1487-12C6-476C-BE0A-F31DF1939AE5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{34DF1487-12C6-476C-BE0A-F31DF1939AE5}.Release|Any CPU.Build.0 = Release|Any CPU
{34DF1487-12C6-476C-BE0A-F31DF1939AE5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{34DF1487-12C6-476C-BE0A-F31DF1939AE5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{34DF1487-12C6-476C-BE0A-F31DF1939AE5}.Release|x86.ActiveCfg = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -154,5 +180,8 @@ Global
{A8AA326E-8EE8-4F11-B750-23028E0949D7} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
{FBB2B86E-972B-4185-9FF2-62CAB5F8388F} = {DAAE4C74-D06F-4874-A166-33305D2643CE}
{520B3AA4-363A-497C-8C15-80423C5AFC85} = {32285FA4-6B46-4D6B-A840-2B13E4C8B58E}
{16703B76-C9F7-4C75-AE6C-53D92E308E3C} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
{323D0C04-B518-4A8F-8A8E-3546AD153D34} = {3BA657BF-28B1-42DA-B5B0-1C4601FCF7B1}
{34DF1487-12C6-476C-BE0A-F31DF1939AE5} = {16703B76-C9F7-4C75-AE6C-53D92E308E3C}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -1,3 +1,3 @@
{
"sources": ["src"]
"sources": ["src", "test\\WebSites"]
}

Просмотреть файл

@ -0,0 +1,84 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
using BasicWebSite;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.TestHost;
using Microsoft.Framework.DependencyInjection;
using Microsoft.Framework.DependencyInjection.Fallback;
using Microsoft.Framework.Runtime;
using Microsoft.Framework.Runtime.Infrastructure;
using Xunit;
namespace Microsoft.AspNet.Mvc.FunctionalTests
{
public class BasicTests
{
private readonly IServiceProvider _provider;
private readonly Action<IBuilder> _app = new Startup().Configure;
// Some tests require comparing the actual response body against an expected response baseline
// so they require a reference to the assembly on which the resources are located, in order to
// make the tests less verbose, we get a reference to the assembly with the resources and we
// use it on all the rest of the tests.
private readonly Assembly _resourcesAssembly = typeof(BasicTests).GetTypeInfo().Assembly;
public BasicTests()
{
var originalProvider = CallContextServiceLocator.Locator.ServiceProvider;
IApplicationEnvironment appEnvironment = originalProvider.GetService<IApplicationEnvironment>();
// When an application executes in a regular context, the application base path points to the root
// directory where the application is located, for example MvcSample.Web. However, when executing
// an aplication as part of a test, the ApplicationBasePath of the IApplicationEnvironment points
// to the root folder of the test project.
// To compensate for this, we need to calculate the original path and override the application
// environment value so that components like the view engine work properly in the context of the
// test.
string appBasePath = CalculateApplicationBasePath(appEnvironment);
_provider = new ServiceCollection()
.AddInstance(typeof(IApplicationEnvironment), new TestApplicationEnvironment(appEnvironment, appBasePath))
.BuildServiceProvider(originalProvider);
}
[Fact]
public async Task CanRender_ViewsWithLayout()
{
// Arrange
var server = TestServer.Create(_provider, _app);
var client = server.Handler;
// The K runtime compiles every file under compiler/resources as a resource at runtime with the same name
// as the file name, in order to update a baseline you just need to change the file in that folder.
var expectedContent = await _resourcesAssembly.ReadResourceAsStringAsync("BasicWebSite.Home.Index.html");
// Act
// The host is not important as everything runs in memory and tests are isolated from each other.
var result = await client.GetAsync("http://localhost/");
Assert.Equal(200, result.StatusCode);
Assert.Equal(result.ContentType, "text/html; charset=utf-8");
var responseContent = await result.ReadBodyAsStringAsync();
// Assert
Assert.Equal(expectedContent, responseContent);
}
// Calculate the path relative to the current application base path.
private static string CalculateApplicationBasePath(IApplicationEnvironment appEnvironment)
{
// Mvc/test/Microsoft.AspNet.Mvc.FunctionalTests
var appBase = appEnvironment.ApplicationBasePath;
// Mvc/test
var test = Path.GetDirectoryName(appBase);
// Mvc/test/WebSites/BasicWebSite
return Path.GetFullPath(Path.Combine(appBase, "..", "WebSites", "BasicWebSite"));
}
}
}

Просмотреть файл

@ -0,0 +1,22 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
namespace Microsoft.AspNet.Mvc.FunctionalTests
{
// This class contains methods to make easier to read responses in different formats
// until there is a built-in easier way to do it.
public static class HttpResponseHelpers
{
public static async Task<string> ReadBodyAsStringAsync(this HttpResponse response)
{
using (var streamReader = new StreamReader(response.Body))
{
return await streamReader.ReadToEndAsync();
}
}
}
}

Просмотреть файл

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">12.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
</PropertyGroup>
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>323d0c04-b518-4a8f-8a8e-3546ad153d34</ProjectGuid>
<OutputType>Library</OutputType>
</PropertyGroup>
<PropertyGroup Condition="$(OutputType) == 'Console'">
<DebuggerFlavor>ConsoleDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="$(OutputType) == 'Web'">
<DebuggerFlavor>WebDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'" Label="Configuration">
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<ItemGroup>
<Content Include="compiler\resources\BasicWebSite.Home.Index.html" />
<Content Include="project.json" />
</ItemGroup>
<ItemGroup>
<Compile Include="BasicTests.cs" />
<Compile Include="HttpResponseHelpers.cs" />
<Compile Include="ResourceHelpers.cs" />
<Compile Include="TestApplicationEnvironment.cs" />
</ItemGroup>
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

Просмотреть файл

@ -0,0 +1,26 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.IO;
using System.Reflection;
using System.Threading.Tasks;
namespace Microsoft.AspNet.Mvc.FunctionalTests
{
// This class contains helper methods for reading resources from a given assembly in order
// to make tests that require comparing against baseline files embedded as resources less
// verbose.
public static class ResourceHelpers
{
public static async Task<string> ReadResourceAsStringAsync(this Assembly assembly, string resourceName)
{
using (var resourceStream = assembly.GetManifestResourceStream(resourceName))
{
using (var streamReader = new StreamReader(resourceStream))
{
return await streamReader.ReadToEndAsync();
}
}
}
}
}

Просмотреть файл

@ -0,0 +1,44 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Runtime.Versioning;
using Microsoft.Framework.Runtime;
namespace Microsoft.AspNet.Mvc.FunctionalTests
{
// Represents an application environment that overrides the base path of the original
// application environment in order to make it point to the folder of the original web
// aplication so that components like ViewEngines can find views as if they were executing
// in a regular context.
public class TestApplicationEnvironment : IApplicationEnvironment
{
private readonly IApplicationEnvironment _originalAppEnvironment;
private readonly string _applicationBasePath;
public TestApplicationEnvironment(IApplicationEnvironment originalAppEnvironment, string appBasePath)
{
_originalAppEnvironment = originalAppEnvironment;
_applicationBasePath = appBasePath;
}
public string ApplicationName
{
get { return _originalAppEnvironment.ApplicationName; }
}
public string Version
{
get { return _originalAppEnvironment.Version; }
}
public string ApplicationBasePath
{
get { return _applicationBasePath; }
}
public FrameworkName TargetFramework
{
get { return _originalAppEnvironment.TargetFramework; }
}
}
}

Просмотреть файл

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home Page - My ASP.NET Application</title>
</head>
<body>
<div>
<div>
<div>
<a href="/">BasicWebApplication</a>
</div>
<div>
<ul>
<li><a href="/">Home</a></li>
</ul>
</div>
</div>
</div>
<div>
<div>
<h1>ASP.NET vNext</h1>
</div>
<hr />
<footer>
<p>&copy; 2014 - My ASP.NET Application</p>
</footer>
</div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,22 @@
{
"version": "0.1-alpha-*",
"compilationOptions": {
"warningsAsErrors": true
},
"dependencies": {
"BasicWebSite": "",
"Microsoft.AspNet.TestHost": "0.1-alpha-*",
"Microsoft.Framework.Runtime.Interfaces": "0.1-alpha-*",
"xunit.abstractions": "2.0.0-aspnet-*",
"xunit.assert": "2.0.0-aspnet-*",
"xunit.core": "2.0.0-aspnet-*",
"Xunit.KRunner": "0.1-alpha-*"
},
"commands": {
"test": "Xunit.KRunner"
},
"configurations": {
"net45": { },
"k10": { }
}
}

Просмотреть файл

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">12.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
</PropertyGroup>
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>34df1487-12c6-476c-be0a-f31df1939ae5</ProjectGuid>
<OutputType>Web</OutputType>
</PropertyGroup>
<PropertyGroup Condition="$(OutputType) == 'Console'">
<DebuggerFlavor>ConsoleDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="$(OutputType) == 'Web'">
<DebuggerFlavor>WebDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'" Label="Configuration">
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DevelopmentServerPort>38820</DevelopmentServerPort>
</PropertyGroup>
<ItemGroup>
<Compile Include="Controllers\HomeController.cs" />
<Compile Include="Startup.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="project.json" />
<Content Include="Views\Home\Index.cshtml" />
<Content Include="Views\Shared\Error.cshtml" />
<Content Include="Views\Shared\_Layout.cshtml" />
</ItemGroup>
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

Просмотреть файл

@ -0,0 +1,12 @@
using Microsoft.AspNet.Mvc;
namespace BasicWebSite.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}
}

Просмотреть файл

@ -0,0 +1,26 @@
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Routing;
using Microsoft.Framework.DependencyInjection;
namespace BasicWebSite
{
public class Startup
{
public void Configure(IBuilder app)
{
// Set up application services
app.UseServices(services =>
{
// Add MVC services to the services container
services.AddMvc();
});
// Add MVC to the request pipeline
app.UseMvc(routes =>
{
routes.MapRoute("ActionAsMethod", "{controller}/{action}/{id?}",
defaults: new { controller = "Home", action = "Index" });
});
}
}
}

Просмотреть файл

@ -0,0 +1,8 @@
@{
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Home Page";
}
<div>
<h1>ASP.NET vNext</h1>
</div>

Просмотреть файл

@ -0,0 +1,7 @@
@{
Layout = "/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Error";
}
<h1>Error.</h1>
<h2>An error occurred while processing your request.</h2>

Просмотреть файл

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
</head>
<body>
<div>
<div>
<div>
@Html.ActionLink("BasicWebApplication", "Index", "Home", new { area = "" })
</div>
<div>
<ul>
<li>@Html.ActionLink("Home", "Index", "Home")</li>
</ul>
</div>
</div>
</div>
<div>
@RenderBody()
<hr />
<footer>
<p>&copy; 2014 - My ASP.NET Application</p>
</footer>
</div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,10 @@
{
"dependencies": {
"Helios": "0.1-alpha-*",
"Microsoft.AspNet.Mvc": ""
},
"configurations": {
"net45": { },
"k10": { }
}
}