背景

在 CI/CD 流程当中,测试是 CI 中很重要的部分。跟开发人员关系最大的就是单元测试,单元测试编写完成之后,我们可以使用 IDE 或者 dot cover 等工具获得单元测试对于业务代码的覆盖率。不过我们需要一个独立的 CLI 工具,这样我们才能够在 Jenkins 的 CI 流程集成。

端到端测试(End to End Test) 是在 Preview 版本部署完成之后,需要对 Preview 版本进行自动化测试,测试完成之后输出对应的覆盖率报告。根据代码覆盖率报告,我们可以了解 QA 编写的测试用例,是否完整覆盖了所有分支流程。

实现

工具选型

单元测试框架我选择的是 xUnit,它对于 .NET Core 与 .NET Framework 的支持都不错,并且也提供了独立于 IDE 之外的 Console Runner,可以很方便地同 Jenkins 集成。

覆盖率收集工具我选择的是 AltCover,因为它能够收集到部署在 IIS 的 ASP.NET MVC 程序覆盖率指标,这样我们就能够对一些 .NET Framework 老项目进行测试覆盖率汇总计算。AltCover 可以生成多种格式的覆盖率报告,默认格式是 OpenCover。

AltCover 生成的覆盖率报告并不是直接可读的,我们需要一个工具来生成人类可以阅读理解的报告。这里我选择的是 ReportGenerator ,它支持 OpenCover 格式的覆盖率报告,并生成对应的 HTML 文件方便查看。

.NET Framework 集成

我建立了一个简单的 ASP.NET Web API 项目(.NET Framework 4.8),提供了一个 ApiTestController 控制器,暴露了一个 HTTP POST 方法 CreateOrder,内部逻辑比较简单,就是创建了一个新的 OrderAggregateRoot 实例,然后返回了一个 Success 文本。

/// <summary>
/// ApiTestController.
/// </summary>
[Route("api/test")]
public class ApiTestController : ApiController
{
private readonly IOrderRepository _orderRepository; /// <summary>
/// <see cref="ApiTestController"/>.
/// </summary>
public ApiTestController()
{
_orderRepository = new FakeOrderRepository();
} /// <summary>
/// CreateOrder.
/// </summary>
[HttpPost]
[Route("api/test/create")]
public IHttpActionResult CreateOrder(CreateOrderInputDto input)
{
var newOrder = new OrderAggregateRoot(null, input.Items.Select(x => new OrderItem(x.Price, x.Number)).ToList());
_orderRepository.InsertAsync(newOrder); return Ok("Success");
}
}
单元测试覆盖率报告

单元测试项目建立比较简单,我建立了一个 AltCoverTestUnitTest 项目,并且添加了 ASP.NET Web API 项目的引用,在内部添加了 AltCover 与 xUnit 相关包的引用。

AltCoverxUnit Console Runner 包安装完成之后,对于 .NET Framework 项目来说,会在对应的解决方案目录下面有一个 packages 文件夹,在里面找到 packages\altcover.8.3.838\tools\net472 目录,在这个目录里面有一个 AltCover.exe 的可执行文件,这个就是 AltCover 的 CLI 工具。

xUnit Console Runner 对应的 CLI 工具则在 packages\xunit.runner.console.2.4.2\tools\net472 中,根据自己的平台使用 xunit.console.exe 或者是 xunit.console.x86.exe 均可。

随后我们直接使用 MSBuild 命令/IDE 重新编译一下单元测试项目,转到对应的 bin\Debug 目录。在 .bin\Debug 目录中,执行以下命令,将会生成一个新的文件夹,里面会包含修改后的 DLL 文件。

这里 CLI 工具的路径,取决于你的实际路径,就在你解决方案对应的 pacakges 里面。

D:\CoverageTool\AltCoverTestRESFul\packages\altcover.8.3.838\tools\net472\AltCover.exe /o=./__UnitTestWithAltCover -s=Adapter -s=Shouldly -s=Microsoft -t="Shouldly." -s="AltCover.Monitor" -t="System." -s=xunit -e="EmptyFiles" -e=Tests -r=".\_Reports\UnitTestWithAltCover.xml"

这里我解释以下命令,其中 /o 参数指的是修改后 DLL 的输出目录,这里我指定的当前目录下的 __UnitTestWithAltCover 文件夹。-s 参数指的是需要排除的程序集名称,支持通配符与正则表达式。-e 的作用与 -s 类似,具体可以查看 Usage ,最有一个 -r 参数指定报告的输出路径,也就是 OpenCover 格式的 XML 文件输出路径。

为什么需要排除?因为我们的项目可能会引用很多第三方库,这个时候我们为了减少报告的噪音,你也不想在报告里面看到一堆 Microsoft 的代码吧,所以需要手动排除掉这些程序集。

为什么叫做修改后,因为执行命令后,AltCover 会重新生成一个新的 DLL,这个新的 DLL 反编译后可以看到会在每行代码插入 Instance.Visit() 来记录代码的访问路径。

命令执行完成之后,可以看到对应的覆盖率文件生成了,但是这里面覆盖率是 0,因为我们的单元测试还没开始跑。

随后我们执行下面的命令,使用 xUnit Console Runner 运行我们的单元测试项目。

D:\CoverageTool\AltCoverTestRESFul\packages\xunit.runner.console.2.4.2\tools\net47\xunit.console.exe ./__UnitTestWithAltCover/AltCoverTestUnitTest.dll -xml "./_Reports/UnitTestWithAltCoverReport.xml"

第一个参数是需要执行的单元测试 DLL,第二个参数 -xml 说明我们具体的执行结果输出路径,这里我们也输出到了 _Reports 文件夹,这个时候我们就有两个 XML 文件了。

切换到 _Reports 文件夹,打开终端,我们这个时候需要使用 reportgeneator 工具,根据这两个 XML 文件生成人类可读的 HTML 报告。

reportgenerator "-reports:UnitTestWithAltCover.xml;UnitTestWithAltCoverReport.xml" "-targetdir:coveragereport" -reporttypes:Html

上述命令的意思就是根据这两个 xml ,在当前目录的 coveragereport 文件夹,生成一个新的 HTML 报告。

关于 reportgenerator 的安装,可以参考官方的 线上工具,它会根据你选择的情况返回适合的安装命令。我自己直接使用的 dotnet tool install --global dotnet-reportgenerator-globaltool 命令进行的安装。

最后的效果:

IIS Web API 覆盖率报告

我们建立一个新的 IIS 站点,并将对应的 DLL 文件放到对应的目录下面。首先暂停对应 IIS 站点,并且停止对应的应用程序池。

随后执行以下命令,将会修改对应的 DLL 文件,以便后续进行覆盖率跟踪,原理跟上面的一样。

D:\CoverageTool\AltCoverTestRESFul\packages\altcover.8.3.838\tools\net472\AltCover.exe --save --inplace -i "D:\TempFiles\IIS\AltCoverTestWebSite\bin" -s=Adapter -s=Shouldly -s="Antlr3.Runtime" -s=Microsoft -t="Shouldly." -s="AltCover.Monitor" -t="System." -s=xunit -e="EmptyFiles" -e=Tests

执行完上述命令以后,将会在终端执行目录下生成两个文件,一个是 coverage.xml ,一个是 coverage.xml.acv 文件,后者是 AltCover 的控制文件,用于记录程序在运行过程中的执行代码路径。

随后启动对应的 IIS 站点与应用程序池,执行自动化测试,或者调用对应的接口。

如果需要停止测试了,需要将对应的 IIS 站点与应用程序池停止,只有停止了,AltCover 才会将已执行代码路径信息写入到对应的控制文件当中。

可以看到 coverage.xml.0.acv 文件已经有内容了,但是我们还需要将控制文件的信息合并到 coverage.xml 当中,这个时候需要执行第二个命令进行合并。

D:\CoverageTool\AltCoverTestRESFul\packages\altcover.8.3.838\tools\net472\AltCover.exe runner --collect -r "D:\TempFiles\IIS\AltCoverTestWebSite\bin"

output:

... D:\TempFiles\IIS\AltCoverTestWebSite\coverage.xml.0.acv (380b)
308 visits recorded in 00:00:00.0171096 (18,002 visits/sec)
A total of 308 visits recorded
Coverage statistics flushing took 0.04 seconds
Visited Classes 10 of 12 (83.33)
Visited Methods 14 of 22 (63.64)
Visited Points 65 of 93 (69.89)
Visited Branches 4 of 30 (13.33)
Maximum CRAP score 30
==== Alternative Results (includes all methods including those without corresponding source) ====
Alternative Visited Classes 13 of 15 (86.67)
Alternative Visited Methods 20 of 30 (66.67)
Alternative maximum CRAP score 30

可以看到控制台的输出已经有 308 visits recorded,随后我们使用 reportgenerator 工具生成 HTML 报告。

.NET Core 集成

单元测试覆盖率报告

集成方法同 .NET Framework 一样。

ASP .NET Core 覆盖率报告

这里我使用的是 dotnet tool 安装的 altcover 命令,安装命令如下,前提是你得有 .NET Core 运行时。

dotnet tool install --global altcover.global --version

随后编译对应的 ASP.NET Core 项目,并且在对应的 bin\Debug 目录打开终端,执行以下命令进行准备工作。

altcover /o=./__UnitTestWithAltCover -i .

随后使用 altcover runner 命令启动对应的程序。

altcover runner -x .\__UnitTestWithAltCover\AltCoverTestRESTFulCore.exe -r .\__UnitTestWithAltCover\

如果已经完成了测试,请终止掉对应的进程,否则 AltCover 不会将数据写入到 XML 文件,最后也使用 reportgenerator 工具生成 HTML 报告。

总结

如果你的项目是基于 .NET Core ,那么可以直接选择微软主推的 coverletAltCover 对于 .NET Framework、Mono、.NET Core 项目都有不错的支持,并且作者维护得也很勤快。

[C#]使用 AltCover 获得代码覆盖率 - E2E Test 和 Unit Test的更多相关文章

  1. angular(转)

    学习之前可以看看 知乎上讨论angularjs优缺点 帮你选择框架的网站 同类主流框架对比 教程 angularjs在慕课网 angularjs在51cto angularjs在图灵社区 社区 Ang ...

  2. 基于vue2.0的在线电影APP,

    基于vue2.0构建的在线电影网[film],webpack + vue + vuex + vue-loader + keepAlive + muse-ui + cordova 全家桶,cordova ...

  3. Webpack单元测试,e2e测试

    此篇文章是续 webpack多入口文件.热更新等体验,主要说明单元测试与e2e测试的基本配置以及相关应用. 一.单元测试 实现单元测试框架的搭建.es6语法的应用.以及测试覆盖率的引入. 1. 需要安 ...

  4. 使用Angular CLI进行单元测试和E2E测试

    第一篇文章是: "使用angular cli生成angular5项目" : http://www.cnblogs.com/cgzl/p/8594571.html 第二篇文章是: & ...

  5. UT, FT ,E2E 测试的意思

    前端实现自动化就要借助到unit和e2e端到端测试了 一.unit测试(FT 就是Fucntion Test 功能测试,  注意不是: funciton函数 ...fucntion功能   不一样哦  ...

  6. 聊聊Go代码覆盖率技术与最佳实践

    "聊点干货" 覆盖率技术基础 截止到Go1.15.2以前,关于覆盖率技术底层实现,以下知识点您应该知道: go语言采用的是插桩源码的形式,而不是待二进制执行时再去设置breakpo ...

  7. Python 代码覆盖率统计工具 coverage.py

    coverage.py是一个用来统计python程序代码覆盖率的工具.它使用起来非常简单,并且支持最终生成界面友好的html报告.在最新版本中,还提供了分支覆盖的功能. 官方网站: http://ne ...

  8. 基于Grunt&Mocha 搭建Nodejs自动化单元测试框架(含代码覆盖率统计)

    Introduction Grunt 是一个基于任务的JavaScript 世界的构建工具 Mocha 是具有丰富特性的 JavaScript 测试框架,可以运行在 Node.js 和浏览器中,使得异 ...

  9. angular 调试 js (分 karms protractor / test e2e unit )

    首页订阅 Protractor端到端的AngularJS测试框架教程 2014年01月18日 分类:教程, JavaScript, AngularJS Protractor是一个建立在WebDrive ...

随机推荐

  1. Prometheus普罗米修斯快速入门

    欢迎来到普罗米修斯! Prometheus是一个监控平台,通过从监控目标的抓取HTTP端点上获取指标. 本指南将展示如何使用和安装Promethues,配置和监视第一个资源.还将下载并安装导出器Exp ...

  2. Three.js 打造缤纷夏日3D梦中情岛 🌊

    声明:本文涉及图文和模型素材仅用于个人学习.研究和欣赏,请勿二次修改.非法传播.转载.出版.商用.及进行其他获利行为. 背景 深居内陆的人们,大概每个人都有过大海之梦吧.夏日傍晚在沙滩漫步奔跑:或是在 ...

  3. 深度学习与CV教程(12) | 目标检测 (两阶段,R-CNN系列)

    作者:韩信子@ShowMeAI 教程地址:http://www.showmeai.tech/tutorials/37 本文地址:http://www.showmeai.tech/article-det ...

  4. 快速 IO

    IO 的进化史 cin和cout 刚开始学的时候,老师叫我们用 cin 和 cout 大概是因为这最简单吧 cin>>x; cout<<x scanf和printf 学到函数了 ...

  5. .net core 抛异常对性能影响的求证之路

    一.前言 在.net 社区中曾经听到过很多关于大量抛异常会影响性能这样的结论,心中一直就存在各种疑问.项目中使用自定义异常来处理业务很爽,但是又担心大量抛业务异常存在性能问题. 查阅了各种文档,微软官 ...

  6. JavaScript 语言入门

    目录 JavaScript 介绍 JavaScript 和 和 html 代码的结合方式 第一种方式 第二种方式 4.变量 关系(比较)运算 逻辑运算 数组(重点) 函数(重点) 函数的二种定义方式 ...

  7. SAP 文本框多行输入

    REPORT zjw_test01. CONSTANTS: gc_text_line_length TYPE i VALUE 72. TYPES: text_table_type(gc_text_li ...

  8. 叮,GitHub 到账 550 美元「GitHub 热点速览 v.22.26」

    作者:HelloGitHub-小鱼干 如果你关注 GitHub 官方动态,你会发现它们最近频频点赞世界各地开发者晒出的 GitHub $550 sponsor 截图,有什么比"白嫖" ...

  9. sql-DDL-操作数据库与表

    1. 操作数据库:CRUD oracle应该是没有操作数据库的SQL oracl创建数据库通过数据库提供的工具来新建数据库 windows版oracle新建数据库 C(Create):创建 creat ...

  10. # Vue3 toRef 和 toRefs 函数

    Vue3 toRef 和 toRefs 函数 上一篇博文介绍了 vue3 里面的 ref 函数和 reactive 函数,实现响应式数据,今天主要来说一下 toRef 函数和 toRefs 函数的基本 ...