Integration testing

集成测试用来确保app的不同模块之间可以正确的一起工作。ASP.NET Core提供单元测试框架和内建的测试网络服务来支持集成测试,并且测试网络服务不需要网络开销就可以处理请求。

View or download sample code

Introduction to integration testing

不像单元测试,集成测试通常包含app的基础设施问题,比如,数据库,文件系统,网络资源,网络请求和响应。单元测试使用假的或模拟的对象来代替这些问题,但是集成测试的目的是确认系统在这些基础设施之上是否能正常的运行。

集成测试,运行更大量的代码段,并且因为他们依赖于基础设施元素,往往比单元测试慢几个数量级。因此,限制编写的集成测试数量是个好主意,尤其是当你可以使用单元测试来测试相同的行为。

Note

如果一些行为可以使用单元测试或集成测试来测试,请使用单元测试,因为它几乎总是更快。 您可能有许多或几百个单元测试与许多不同的输入,但只是一些覆盖最重要的场景的集成测试。

不需要写太多的集成测试来确认你能够写入和读取数据到数据库。不需要列举每一个可能的组合,只需要确认app可以一起正常工作就可以。

Integration testing ASP.NET Core

要设置好集成测试并运行,需要创建一个测试项目,添加需要测试的项目的ASP.NET Core网站应用,并安装一个测试运行器。这个过程在Unit testing有描述。

Note

将单元测试和集成测试分成不同的项目,将帮助你避免意外的将基础架构问题引入单元测试,并且可以很容易的选择启动哪一组测试。

The Test Host

ASP.NET Core包含一个测试主机,可以添加到集成测试项目,并用于托管ASP.NET Core应用程序,提供测试请求,而不需要真正的Web主机。

所提供的示例包括已配置为使用xUnit和测试主机的集成测试项目。 它使用Microsoft.AspNetCore.TestHost NuGet包。

一旦Microsoft.AspNetCore.TestHost包包含在项目中,您就可以在测试中创建和配置TestServer。 以下测试显示如何验证对网站根目录发出的请求返回“Hello World!”。 并应成功运行由Visual Studio创建的ASP.NET Core的默认空Web模板。

public class PrimeWebDefaultRequestShould
{private readonly TestServer _server;private readonly HttpClient _client;public PrimeWebDefaultRequestShould(){// Arrange_server = new TestServer(new WebHostBuilder().UseStartup<Startup>());_client = _server.CreateClient();}[Fact]public async Task ReturnHelloWorld(){// Actvar response = await _client.GetAsync("/");response.EnsureSuccessStatusCode();var responseString = await response.Content.ReadAsStringAsync();// AssertAssert.Equal("Hello World!",responseString);}
}

此测试使用Arrange-Act-Assert模式。 Arrange步骤在构造函数中完成,它创建一个TestServer的实例。 一个配置好的WebHostBuilder将用于创建TestHost; 在此示例中,来自被测系统(SUT)的Startup类的Configure方法被传递给WebHostBuilder。 此方法将用于配置TestServer的请求管道,与SUT服务器的配置方式相同。

在测试的Act部分,向TestServer实例发出“/”路径的请求,并将响应读回到字符串中。 此字符串与预期的“Hello World!”字符串进行比较。 如果它们匹配,则测试通过; 否则失败。

现在,您可以添加一些额外的集成测试,以确认素数检查功能能在app中正常运行。

public class PrimeWebCheckPrimeShould
{private readonly TestServer _server;private readonly HttpClient _client;public PrimeWebCheckPrimeShould(){// Arrange_server = new TestServer(new WebHostBuilder().UseStartup<Startup>());_client = _server.CreateClient();}private async Task<string> GetCheckPrimeResponseString(string querystring = ""){var request = "/checkprime";if(!string.IsNullOrEmpty(querystring)){request += "?" + querystring;}var response = await _client.GetAsync(request);response.EnsureSuccessStatusCode();return await response.Content.ReadAsStringAsync();}[Fact]public async Task ReturnInstructionsGivenEmptyQueryString(){// Actvar responseString = await GetCheckPrimeResponseString();// AssertAssert.Equal("Pass in a number to check in the form /checkprime?5",responseString);}[Fact]public async Task ReturnPrimeGiven5(){// Actvar responseString = await GetCheckPrimeResponseString("5");// AssertAssert.Equal("5 is prime!",responseString);}[Fact]public async Task ReturnNotPrimeGiven6(){// Actvar responseString = await GetCheckPrimeResponseString("6");// AssertAssert.Equal("6 is NOT prime!",responseString);}
}

注意!!!上面的集成测试不是用来检查素数检查器的正确性的,而是检查app是否像你期望的那样运行,因为素数检查器的正确性是单元测试覆盖的范围。

Refactoring to use middleware

重构是改变应用程序代码以改进其设计而不改变其行为的过程。 理想情况下,有一套已经通过的测试,可以帮助确保系统的行为在更改之前和之后保持不变。 查看在Web应用程序的Configure方法中实现主要检查逻辑的方式,您将看到:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.Run(async (context) =>{if (context.Request.Path.Value.Contains("checkprime")){int numberToCheck;try{numberToCheck = int.Parse(context.Request.QueryString.Value.Replace("?", ""));var primeService = new PrimeService();if (primeService.IsPrime(numberToCheck)){await context.Response.WriteAsync($"{numberToCheck} is prime!");}else{await context.Response.WriteAsync($"{numberToCheck} is NOT prime!");}}catch{await context.Response.WriteAsync("Pass in a number to check in the form /checkprime?5");}}else{await context.Response.WriteAsync("Hello World!");}});
}

这个代码可以正常运行,但它远不是你想要实现的那样,即使这么简单。 想象一下,如果你需要在每次添加另一个URL路径时都添加这么多的代码,Configure方法会是什么样子?

一个选项是考虑在app中添加MVC,创建一个控制器来处理素数的检查。然而,假设你现在不需要MVC的其他功能,因为它太大了。

可以利用ASP.NET Core middleware,它可以让我们再自己的类中封装素数检查逻辑,并让Configure方法更好的分离关注点。

您希望允许中间件使用路径作为参数,因此中间件类在其构造函数中需要一个RequestDelegate和一个PrimeCheckerOptions实例。 如果请求的路径与此中间件配置的不匹配,您只需调用链中的下一个中间件,不做任何进一步操作。 配置中的其余实现代码现在位于Invoke方法中。

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using PrimeWeb.Services;
using System;
using System.Threading.Tasks;namespace PrimeWeb.Middleware
{public class PrimeCheckerMiddleware{private readonly RequestDelegate _next;private readonly PrimeCheckerOptions _options;private readonly PrimeService _primeService;public PrimeCheckerMiddleware(RequestDelegate next,PrimeCheckerOptions options,PrimeService primeService){if (next == null){throw new ArgumentNullException(nameof(next));}if (options == null){throw new ArgumentNullException(nameof(options));}if (primeService == null){throw new ArgumentNullException(nameof(primeService));}_next = next;_options = options;_primeService = primeService;}public async Task Invoke(HttpContext context){var request = context.Request;if (!request.Path.HasValue ||request.Path != _options.Path){await _next.Invoke(context);}else{int numberToCheck;if (int.TryParse(request.QueryString.Value.Replace("?", ""), out numberToCheck)){if (_primeService.IsPrime(numberToCheck)){await context.Response.WriteAsync($"{numberToCheck} is prime!");}else{await context.Response.WriteAsync($"{numberToCheck} is NOT prime!");}}else{await context.Response.WriteAsync($"Pass in a number to check in the form {_options.Path}?5");}}}}
}

由于此中间件在其路径匹配时充当请求委派链中的端点,因此当此中间件处理请求时,不会调用_next.Invoke。

创建好了这个中间件和一些有用的扩展方法,配置他们更容易,重构的配置方法如下所示:

public void Configure(IApplicationBuilder app,IHostingEnvironment env)
{if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}app.UsePrimeChecker();app.Run(async (context) =>{await context.Response.WriteAsync("Hello World!");});
}

在重构之后,可以确信Web应用程序仍然像以前一样工作,因为您的集成测试全部通过。

Note

在完成重构和测试通过后,最好将更改提交给源代码控制服务。 如果你正在练习测试驱动开发,考虑添加Commit到你的Red-Green-Refactor循环,详见这里

Resources

Unit Testing

Middleware

Testing Controllers

转载于:https://www.cnblogs.com/windchen/p/6590723.html

Integration testing相关推荐

  1. Testing and Test-First Programming

    Testing levels Unit testing 单元测试 测试某一小部分代码的正确性,尤其是测试某个函数. Integration testing 集成测试 The combined exec ...

  2. Testing Process - 读书笔记

    看到 Wikipedia 上面有一篇对于软件测试的综述,挺有总结性,做下读书笔记. Wikipedia 的这篇文章,可以通过下面的 URL 访问: http://en.wikipedia.org/wi ...

  3. 软件测试testing

    目录 1 解释 2 测试水平 3 静态测试与动态测试 4 测试与调试 5 白盒测试与黑盒测试 6 测试优先的编程(TTD) 7 回归测试 1 解释 软件测试是提供有关被测产品或服务质量的信息而进行的一 ...

  4. [ZZ]测试阶段及类型(Testing Phases Types)

    测试阶段及类型: Testing Phases http://www.research.umbc.edu/~cseaman/ifsm698/lect0910.ppt http://www.ics.uc ...

  5. 《代码大全2》阅读笔记13-- Chapter 22 Developer Testing

    Chapter 22 Developer Testing  开发者测试 测试是最常见的改善质量的活动--这种实践得到许多业界和学界研究,以及商业经验的支持. ·单元测试(Unit testing)是将 ...

  6. 5 Things That Will Impact the Future of Software Testing(将要影响软件测试未来的5件事)

    目录 原链接 翻译内容 Summary(摘要): 正文 1. Artificial Intelligence(人工智能) 2. DevOps 3. QA as a Service(QA即服务) 4. ...

  7. 自定义国内maven镜像包设置settings.xml

    直接复制以下代码创建一个名为settings.xml的文件,放到C:\Users\Administrator\.m2下即可 <!-- Licensed to the Apache Softwar ...

  8. Saiku二次开发获取源代码在本地编译(五)

    关于Saiku的二次开发,在本地编译然后启动自己编译好的Saiku服务 Saiku是开源的,从github上能下载源代码,本例中的saiku源码也是从github上找的,然后自己改了一些pom.xml ...

  9. 国内阿里Maven仓库镜像Maven配置文件Maven仓库速度快

    国内连接maven官方的仓库更新依赖库,网速一般很慢,收集一些国内快速的maven仓库镜像以备用. 最新更新:2016年11月11日 18:05:40 阿里云提供Maven私服,我把配置文件贴一下,自 ...

最新文章

  1. 在64位的环境中使用VS建立Web项目进行Oracle连接需要注意WebDev是32位的
  2. xampp无法启动apache,提示terminating worker thread 0
  3. 任意的android程序,Android任意位置获取应用Context
  4. Android中的意图匹配--IntentFilter的作用
  5. python怎么安装requests库-Python3.6安装及引入Requests库的实现方法
  6. Cannot place PIO comp S on the proposed PIO site PB6C / F5 because the types of their IOLOGICs a...
  7. docker容器指定ip
  8. 上顿号符号_上顿号符号_标点符号(1):谈谈顿号的用法
  9. C++学习之路 | PTA乙级—— 1027 打印沙漏 (20 分)(精简)
  10. Selenium API-WebElement 属性
  11. QT5.10+MinGW+OpenCV3.4.2编译
  12. Lucene的索引链结构_IndexChain
  13. 2N点实数序列为 N=64。用一个复数FFT程序,一次算出,并绘出。
  14. 计算机网络第七版谢希仁习题,计算机网络 释疑与习题解答 谢希仁 第7七版 计算机网络(第7版)谢...
  15. Win7忘记开机密码解决办法
  16. 放弃75W年薪,回老家当公务员,提离职被领导教育,网友:leader嫉妒了
  17. 通过位与方法获取三色值,十六进制色值转换RGB
  18. 呼吸系统药物--平喘药
  19. 淘宝怎么选品技巧秘籍,做淘宝7分靠选货品
  20. 基于MQTT协议的WZ指令开发V3.0版本支持onenet

热门文章

  1. mongodb--find高级用法
  2. git push -u origin master 上传出错问题
  3. 存储知识课堂(二):磁盘读写磁头揭秘
  4. 将EditText的光标定位到字符的最后面
  5. 用C#实现win7下vs2008的激活(附学习交流代码)
  6. 18 | 案例篇:内存泄漏了,我该如何定位和处理?
  7. 17 | 案例篇:如何利用系统缓存优化程序的运行效率?
  8. 10.11 arping:发送arp请求
  9. linux中断处理函数参数,第9章 设置ISR(中断处理函数)
  10. cdh sqoop 配置_相比于手动搭建集群,使用Ambari或者CDH的必要性