[C#]使用 AltCover 获得代码覆盖率 - E2E Test 和 Unit Test
背景
在 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 相关包的引用。


AltCover 与 xUnit 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 ,那么可以直接选择微软主推的 coverlet ,AltCover 对于 .NET Framework、Mono、.NET Core 项目都有不错的支持,并且作者维护得也很勤快。
[C#]使用 AltCover 获得代码覆盖率 - E2E Test 和 Unit Test的更多相关文章
- angular(转)
学习之前可以看看 知乎上讨论angularjs优缺点 帮你选择框架的网站 同类主流框架对比 教程 angularjs在慕课网 angularjs在51cto angularjs在图灵社区 社区 Ang ...
- 基于vue2.0的在线电影APP,
基于vue2.0构建的在线电影网[film],webpack + vue + vuex + vue-loader + keepAlive + muse-ui + cordova 全家桶,cordova ...
- Webpack单元测试,e2e测试
此篇文章是续 webpack多入口文件.热更新等体验,主要说明单元测试与e2e测试的基本配置以及相关应用. 一.单元测试 实现单元测试框架的搭建.es6语法的应用.以及测试覆盖率的引入. 1. 需要安 ...
- 使用Angular CLI进行单元测试和E2E测试
第一篇文章是: "使用angular cli生成angular5项目" : http://www.cnblogs.com/cgzl/p/8594571.html 第二篇文章是: & ...
- UT, FT ,E2E 测试的意思
前端实现自动化就要借助到unit和e2e端到端测试了 一.unit测试(FT 就是Fucntion Test 功能测试, 注意不是: funciton函数 ...fucntion功能 不一样哦 ...
- 聊聊Go代码覆盖率技术与最佳实践
"聊点干货" 覆盖率技术基础 截止到Go1.15.2以前,关于覆盖率技术底层实现,以下知识点您应该知道: go语言采用的是插桩源码的形式,而不是待二进制执行时再去设置breakpo ...
- Python 代码覆盖率统计工具 coverage.py
coverage.py是一个用来统计python程序代码覆盖率的工具.它使用起来非常简单,并且支持最终生成界面友好的html报告.在最新版本中,还提供了分支覆盖的功能. 官方网站: http://ne ...
- 基于Grunt&Mocha 搭建Nodejs自动化单元测试框架(含代码覆盖率统计)
Introduction Grunt 是一个基于任务的JavaScript 世界的构建工具 Mocha 是具有丰富特性的 JavaScript 测试框架,可以运行在 Node.js 和浏览器中,使得异 ...
- angular 调试 js (分 karms protractor / test e2e unit )
首页订阅 Protractor端到端的AngularJS测试框架教程 2014年01月18日 分类:教程, JavaScript, AngularJS Protractor是一个建立在WebDrive ...
随机推荐
- java接口多实现注入方法总结
1. 单实现接口注入方法 1.1 构造注入(推荐) @RequiredArgsConstructor public class TestController { // 其只有一个具体的实现类 priv ...
- DS18B20数字温度计 (三) 1-WIRE总线 ROM搜索算法和实际测试
目录 DS18B20数字温度计 (一) 电气特性, 寄生供电模式和远距离接线 DS18B20数字温度计 (二) 测温, ROM和CRC算法 DS18B20数字温度计 (三) 1-WIRE总线 ROM搜 ...
- 入坑KeePass(四)KeePass通过坚果云WebDav同步方法
参考博客:什么值得买平台-Keepass+坚果云:多平台密码无缝同步 .1.在坚果云上创建一个同步专用的文件夹(建议勾上"默认不同步到电脑"选项) 创建之后可以把刚才创建的数据库文 ...
- Windows启动谷歌浏览器Chrome失败(应用程序无法启动,因为应用程序的并行配置不正确)解决方法
目录 一.系统环境 二.问题描述 三.解决方法 一.系统环境 Windows版本 系统类型 浏览器Chrome版本 Windows 10 专业版 64 位操作系统, 基于 x64 的处理器 版本 10 ...
- python做小游戏——做个马里奥分分钟解决
一.前言 嗨喽,大家好呀!这里是小熊猫 在你的童年记忆里,是否有一个蹦跳.顶蘑菇的小人已经被遗忘? 马里奥是靠吃蘑菇成长,闻名世界的超级巨星.特征是大鼻子.头戴帽子.身穿背带工作服.还留着胡子.帽子加 ...
- 浪姐打分看不够?用几行Python代码模拟评委打分
大家好鸭~我是小熊猫比赛大家都看过吧,每次是不是都对比赛成绩充满期待.特别是浪姐的打分看的简直欲罢不能- 今天就用Python来模拟评委打分,这个案例很短也很简单,很适合新手跟小白练习. 在某次十佳歌 ...
- Maven配置【详细】
参考网址:https://www.jianshu.com/p/f2f52a062d5b
- windows系统下.NET CORE c# 通过bat脚本发布iis应用程序,半智能点击式ci/cd
这里以git为例子讲解: 第一个 pullCode.bat 文件是 拉取代码 git pull 第二个 publish.bat 脚本,编译代码,并发布指定文件夹 dotnet publish &quo ...
- 52 条 SQL 语句性能优化策略,建议收藏
本文会提到 52 条 SQL 语句性能优化策略. 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在where及order by涉及的列上建立索引. 2.应尽量避免在where子句中对字段进行nul ...
- Java 内存模型,或许应该这么理解
大家好,我是树哥. 在前面一段时间,我连续写了几篇关于并发编程的文章: 从 CPU 讲起,深入理解 Java 内存模型! - 陈树义的博客 深入理解 happens-before 原则 - 陈树义的博 ...
