asp.net 集成测试_简化ASP.NET Core应用程序的功能和集成测试

作者:神秘网友 发布时间:2020-10-15 08:56:25

asp.net 集成测试_简化ASP.NET Core应用程序的功能和集成测试

asp.net 集成测试_简化ASP.NET Core应用程序的功能和集成测试
asp.net 集成测试_简化ASP.NET Core应用程序的功能和集成测试

asp.net 集成测试

asp.net 集成测试_简化ASP.NET Core应用程序的功能和集成测试

In ASP.NET 2.1 (now in preview) there's apparently a new package called Microsoft.AspNetCore.Mvc.Testing that's meant to help streamline in-memory end-to-end testing of applications that use the MVC pattern. I've been re-writing my podcast site at https://hanselminutes.com in ASP.NET Core 2.1 lately, and recently added some unit testing and automatic unit testing with code coverage. Here's a couple of basic tests. Note that these call the Razor Pages directly and call their OnGet() methods directly. This shows how ASP.NET Core is nicely factored for Unit Testing but it doesn't do a "real" HTTP GET or perform true end-to-end testing.

在ASP.NET 2.1(现已预览)中,显然有一个名为Microsoft.AspNetCore.Mvc.Testing的新程序包,该程序包旨在帮助简化使用MVC模式的应用程序的内存端到端测试。 最近,我一直在用ASP.NET Core 2.1重写https://hanselminutes.com上的播客站点,最近又添加了一些单元测试和具有代码??覆盖率的自动单元测试。 这是几个基本测试。 请注意,这些直接调用Razor页面,并直接调用其OnGet()方法。 这说明了如何将ASP.NET Core很好地用于单元测试,但它没有执行“真实的” HTTP GET或执行真正的端到端测试。

These tests are testing if visiting URLs like /620 will automatically redirect to the correct full canonical path as they should.

这些测试用于测试访问的URL(例如/ 620)是否会自动重定向到正确的完整规范路径。

[Fact]
public async void ShowDetailsPageIncompleteTitleUrlTest()
{
// FAKE HTTP GET "/620"
IActionResult result = await pageModel.OnGetAsync(id:620, path:"");

RedirectResult r = Assert.IsType<RedirectResult>(result);
Assert.NotNull(r);
Assert.True(r.Permanent); //HTTP 301?
Assert.Equal("/620/jessica-rose-and-the-worst-advice-ever",r.Url);
}

[Fact]
public async void SuperOldShowTest()
{
// FAKE HTTP GET "/default.aspx?showId=18602"
IActionResult result = await pageModel.OnGetOldShowId(18602);

RedirectResult r = Assert.IsType<RedirectResult>(result);
Assert.NotNull(r);
Assert.True(r.Permanent); //HTTP 301?
Assert.StartsWith("/615/developing-on-not-for-a-nokia-feature",r.Url);
}

I wanted to see how quickly and easily I could do these same two tests, except "from the outside" with an HTTP GET, thereby testing more of the stack.

我想看看如何快速而轻松地完成这两个测试,除了使用HTTP GET从外部进行测试之外,从而测试了更多堆栈。

I added a reference to Microsoft.AspNetCore.Mvc.Testing in my testing assembly using the command-line equivalanet of "Right Click | Add NuGet Package" in Visual Studio. This CLI command does the same thing as the UI and adds the package to the csproj file.

我在测试程序集中使用Visual Studio中“右键单击|添加NuGet程序包”的命令行等效项添加了对Microsoft.AspNetCore.Mvc.Testing的引用。 此CLI命令执行与UI相同的操作,并将程序包添加到csproj文件中。

dotnet add package Microsoft.AspNetCore.Mvc.Testing -v 2.1.0-preview1-final

It includes a new WebApplicationTestFixture that I point to my app's Startup class. Note that I can take store the HttpClient the TestFixture makes for me.

它包含一个新的WebApplicationTestFixture,我指向我的应用程序的Startup类。 请注意,我可以存储TestFixture为我制作的HttpClient。

public class TestingMvcFunctionalTests : IClassFixture<WebApplicationTestFixture<Startup>>
{
public HttpClient Client { get; }

public TestingMvcFunctionalTests(WebApplicationTestFixture<Startup> fixture)
{
Client = fixture.Client;
}
}

No tests yet, just setup. I'm using SSL redirection so I'll make sure the client knows that, and add a test:

尚无测试,只需设置。 我正在使用SSL重定向,因此我将确保客户端知道这一点,并添加一个测试:

public TestingMvcFunctionalTests(WebApplicationTestFixture<Startup> fixture)
{
Client = fixture.Client;
Client.BaseAddress = new Uri("https://localhost");
}

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

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

This will fail, in fact. Because I have an API Key that is needed to call out to my backend system, and I store it in .NET's User Secrets system. My test will get an InternalServerError instead of OK.

实际上,这将失败。 因为我有一个调用我的后端系统所需的API密钥,所以我将其存储在.NET的User Secrets系统中。 我的测试将收到InternalServerError而不是OK。

Starting test execution, please wait...
[xUnit.net 00:00:01.2110048] Discovering: hanselminutes.core.tests
[xUnit.net 00:00:01.2690390] Discovered: hanselminutes.core.tests
[xUnit.net 00:00:01.2749018] Starting: hanselminutes.core.tests
[xUnit.net 00:00:08.1088832] hanselminutes_core_tests.TestingMvcFunctionalTests.GetHomePage [FAIL]
[xUnit.net 00:00:08.1102884] Assert.Equal() Failure
[xUnit.net 00:00:08.1103719] Expected: OK
[xUnit.net 00:00:08.1104377] Actual: InternalServerError
[xUnit.net 00:00:08.1114432] Stack Trace:
[xUnit.net 00:00:08.1124268] D:\github\hanselminutes-core\hanselminutes.core.tests\FunctionalTests.cs(29,0): at hanselminutes_core_tests.TestingMvcFunctionalTests.<GetHomePage>d__4.MoveNext()
[xUnit.net 00:00:08.1126872] --- End of stack trace from previous location where exception was thrown ---
[xUnit.net 00:00:08.1158250] Finished: hanselminutes.core.tests
Failed hanselminutes_core_tests.TestingMvcFunctionalTests.GetHomePage
Error Message:
Assert.Equal() Failure
Expected: OK
Actual: InternalServerError

Where do these secrets come from? In Development they come from user secrets.

这些秘密从何而来? 在开发中,它们来自用户机密。

public Startup(IHostingEnvironment env)
{
this.env = env;
var builder = new ConfigurationBuilder();

if (env.IsDevelopment())
{
builder.AddUserSecrets<Startup>();
}
Configuration = builder.Build();
}

But in Production they come from the ENVIRONMENT. Are these tests Development or Production...I must ask myself.  They are Production unless told otherwise. I can override the Fixture and tell it to use another Environment, like "Development." Here is a way (given this preview) to make my own TestFixture by deriving and grabbing and override to change the Environment. I think it's too hard and should be easier.

但是在生产中,它们来自环境。 这些测试是开发还是生产...我必须问自己。 除非另有说明,否则它们是生产型。 我可以覆盖灯具,并告诉它使用另一个环境,例如“开发”。 这是通过派生,获取和覆盖以更改环境来制作自己的TestFixture的一种方法(提供此预览)。 我认为这太难了,应该会更容易。

Either way, the real question here is for me - do I want my tests to be integration tests in development or in "production." Likely I need to make a new environment for myself - "testing."

无论哪种方式,这里真正的问题是对我来说-我是否要使我的测试成为开发或“生产”中的集成测试。 我可能需要为自己创造一个新的环境-“测试”。

public class MyOwnTextFixture<TStartup> : WebApplicationTestFixture<Startup> where TStartup : class
{
public MyOwnTextFixture() { }

protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.UseEnvironment("Development");
}
}

However, my User Secrets still aren't loading, and that's where the API Key is that I need.

但是,我的用户密钥仍然没有加载,这就是我需要的API密钥。

BUG?: There is either a bug here, or I don't know what I'm doing. I'm loading User Secrets in builder.AddUserSecrets<Startup> and later injecting the IConfiguration instance from builder.Build() and going "_apiKey = config["SimpleCastAPIKey"];" but it's null. The config that's injected later in the app isn't the same one that's created in Startup.cs. It's empty. Not sure if this is an ASP.NE Core 2.0 thing or 2.1 thing but I'm going to bring it up with the team and update this blog post later. It might be a Razor Pages subtlety I'm missing.For now, I'm going to put in a check and manually fix up my Config. However, when this is fixed (or I discover my error) this whole thing will be a pretty nice little set up for integration testing.

BUG ?:这里有一个错误,或者我不知道自己在做什么。 我在builder.AddUserSecrets <Startup>中加载用户密钥,然后从builder.Build()注入IConfiguration实例,然后输入“ _apiKey = config [” SimpleCastAPIKey“]; ”,但它为空。 稍后在应用程序中注入的配置与Startup.cs中创建的配置不同。 它是空的。 不确定这是ASP.NE Core 2.0还是2.1,但我将与团队讨论并稍后更新此博客文章。 我可能缺少Razor Pages的细微之处。现在,我要进行检查并手动修复Config。 但是,当这个问题解决之后(或者我发现了我的错误),这整个过程将成为集成测试的一个不错的设置。

I will add another test, similar to the redirect Unit Test but a fuller integration test that actually uses HTTP and tests the result.

我将添加另一个测试,类似于重定向单元测试,但实际上是使用HTTP并测试结果的更完整的集成测试。

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

// Assert
Assert.Equal(HttpStatusCode.MovedPermanently, response.StatusCode);
Assert.Equal("/620/jessica-rose-and-the-worst-advice-ever",response.Headers.Location.ToString());
}

There's another issue here that I don't understand. Because have to set Client.BaseAddress to https://localhost (because https) and the Client is passed into fixture.Client, I can't set the Base address twice or I'll get an exception, as the Test's Constructor runs twice, but the HttpClient that's passed in as a lifecycler that's longer. It's being reused, and it fails when setting its BaseAddress twice.

这里还有另一个我不明白的问题。 因为必须将Client.BaseAddress设置为https:// localhost (因为https),并且Client会传递到Fixture.Client中,所以我不能两次设置Base地址,否则会得到异常,因为Test的构造函数运行了两次,但作为生命周期传递程序传递的HttpClient更长。 它被重用,并且在设置BaseAddress两次时失败。

Error Message:
System.InvalidOperationException : This instance has already started one or more requests. Properties can only be modified before sending the first request.

BUG? So to work around it I check to see if I've done it before. Which is gross. I want to set the BaseAddress once, but I am not in charge of the creation of this HttpClient as it's passed in by the Fixture.

BUG? 因此,要解决此问题,请检查是否之前已完成。 哪个好我想一次设置BaseAddress,但是由于该Fixture传递了该HttpClient,因此我不负责该HttpClient的创建。

public TestingMvcFunctionalTests(MyOwnTextFixture<Startup> fixture)
{
Client = fixture.Client;
if (Client.BaseAddress.ToString().StartsWith("https://") == false)
Client.BaseAddress = new Uri("https://localhost");
}

Another option is that I create a new client every time, which is less efficient and perhaps a better idea as it avoids any side effects from other tests, but also feels weird that I should have to do this, as the new standard for ASP.NET Core sites is to be SSL/HTTPS by default..

另一个选择是,我每次都创建一个新客户端,这效率较低,可能是一个更好的主意,因为它避免了其他测试带来的任何副作用,但是我感到很奇怪,我必须这样做,这是ASP的新标准。 NET Core站点默认为SSL / HTTPS。

public TestingMvcFunctionalTests(MyOwnTextFixture<Startup> fixture)
{
Client = fixture.CreateClient(new Uri(https://localhost));
}

I'm still learning about how it all fits together, but later I plan to add in Selenium tests to have a full, complete, test suite that includes the browser, CSS, JavaScript, end-to-end integration tests, and unit tests.

我仍在学习如何将它们组合在一起,但后来我计划添加Selenium测试,以拥有一个完整,完整的测试套件,其中包括浏览器,CSS,JavaScript,端到端集成测试和单元测试。 。

Let me know if you think I'm doing something wrong. This is preview stuff, so it's early days!

如果您认为我做错了事,请告诉我。 这是预览资料,所以还很早!



Sponsor: Get the latest JetBrains Rider for debugging third-party .NET code, Smart Step Into, more debugger improvements, C# Interactive, new project wizard, and formatting code in columns.

赞助商:获取最新的JetBrains Rider,用于调试第三方.NET代码,Smart Step Into,更多调试器改进,C#Interactive,新项目向导以及列中的格式代码。

关于斯科特 (About Scott)

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

斯科特·汉塞尔曼(Scott Hanselman)是前教授,前金融首席架构师,现在是演讲者,顾问,父亲,糖尿病患者和Microsoft员工。 他是一位失败的单口相声漫画家,一个玉米种植者和一本书的作者。

asp.net 集成测试_简化ASP.NET Core应用程序的功能和集成测试 asp.net 集成测试_简化ASP.NET Core应用程序的功能和集成测试 asp.net 集成测试_简化ASP.NET Core应用程序的功能和集成测试 About   关于 Newsletter 时事通讯 Hosting By 主持人 asp.net 集成测试_简化ASP.NET Core应用程序的功能和集成测试

翻译自: https://www.hanselman.com/blog/easier-functional-and-integration-testing-of-aspnet-core-applications

asp.net 集成测试

asp.net 集成测试_简化ASP.NET Core应用程序的功能和集成测试相关教程

  1. lighthouse使用_使用Chrome的Lighthouse Auditor优化ASP.NET Cor

    lighthouse使用_使用Chrome的Lighthouse Auditor优化ASP.NET Core网站 lighthouse使用 I'm continuing to update my podcast site. I've upgraded it from ASP.NET Web Pages (10 year old code written in WebMatrix) to ASP.NET Core 2.1 developed with V

  2. .net core单元测试_.NET Core中的自动单元测试以及Visual Studio

    .net core单元测试_.NET Core中的自动单元测试以及Visual Studio Code中的代码覆盖率 .net core单元测试 I was talking to Toni Edward Solarin on Skype yesterday about his open source spike (early days) of Code Coverage for .NET Core called coverle

  3. 如何在mysql插入50万条测试数据:利用存储过程SQL编程实现

    如何在mysql插入50万条测试数据:利用存储过程SQL编程实现 目录 1. 首先创建两张测试表 2.为function指定一个参数 3. 创建函数:随机产生字符串 4. 创建函数:用于随机产生多少到多少的编号 5. 创建存储过程:往emp表中插入数据 6. 创建存储过程,往dept表添

  4. ASP.NET单页应用程序Angular版本候选

    ASP.NET单页应用程序Angular版本候选 I was doing some Angular then remembered that the ASP.NET Angular Project Template has a release candidate and is scheduled to release sometime soon in 2018. 我当时在做一些Angular,然后想起ASP.NET“ Angula

  5. Linux安装yum(已经测试)

    Linux安装yum(已经测试) 解决: -bash: yum: command not found错误 最近在学习Linux,今天不小心在 CentOS7 系统下把yum命令给删除了,于是百度了好几篇文章,实话照他们的操作去做,实在不敢说啥,只得自己手动了....... 步骤如下 第一步: http://mirrors.

  6. 3-6 银行业务队列简单模拟 (20分)附详细测试点

    3-6 银行业务队列简单模拟 (20分)附详细测试点 题目描述 设某银行有A、B两个业务窗口,且处理业务的速度不一样,其中A窗口处理速度是B窗口的2倍 —— 即当A窗口每处理完2个顾客时,B窗口处理完1个顾客。给定到达银行的顾客序列,请按业务完成的顺序输出顾客序

  7. 一步步实现持续集成(二)安装GIT

    一步步实现持续集成(二)安装GIT 在自动化部署服务器中,版本控制软件是必须的。服务器可以作为一个远程版本代码仓库使用,这也体现了远程服务器代码共享的优势。 版本控制软件常用有SVN、VSS和GIT,我们还是选择较为流行的GIT。 在远程服务器中,仅安装GIT

  8. ContiPerf接口性能测试

    ContiPerf接口性能测试 为什么80%的码农都做不了架构师? ContiPerf是一个轻量级的测试工具,基于JUnit 4 开发,可用于接口级的性能测试 可以指定在线程数量和执行次数,通过限制最大时间和平均执行时间来进行效率测试 具体使用方法 添加依赖 !--性能测试-- d