如何使用 Xamarin MvvmCross 获取代码覆盖率?

How to obtain code coverage with Xamarin MvvmCross?

tl;博士

嗨!我正在尝试找出使用 MvvmCross 和 Visual Studio Community 2017 in Windows 10[=37= 开发的 Xamarin 应用程序 (Xamarin.Android) 的代码覆盖率是多少].

描述

我们已经试过两次了:

  • 我们第一次创建了一个 MSTest 项目,我们可以在 Visual Studio 的测试资源管理器中 运行 并使用 SonnarQube 导出输出。虽然我们可以检查我们的代码重复、错误、漏洞和代码味道,但 SonarQube 根本不报告代码覆盖率。

我们意识到这是因为 Xamarin 项目使用 .NET Standard 而不是 .NET Framework,而 SonarQube 只支持 .NET Framework。然后我们找到 this link 和 Mac 的解决方案,我引用:

It looks like the best solution we have come across is to compile the tests into an executable with NUnitLite runner and then use the log profiler, mprof-report and ReportGenerator to generate the final html files :

e.g.

mono --debug --profile=log:coverage,covfilter=+MyNamespace,covfilter=-NotMyNamespace,output=coverage.mlpd MyTests.exe --noresult

mprof-report --reports=coverage --coverage-out=coverage.xml coverage.mlpd

mono ./packages/ReportGenerator.2.5.6/tools/ReportGenerator.exe -reports:coverage.xml -targetdir:report

firefox ./report/index.htm

  • 因此我们将测试项目转换为使用 NUnit。我们能够使用 NUnit.Adapter 将 NUnit 附加到 Visual Studio,我们能够从中生成可执行文件并从二进制安装程序 (*.微星)。正如我们运行第一个命令,它returns测试的结果也给出了一个错误:

The 'log' profiler wasn't found in the main executable nor could it be loaded from 'mono-profiler-log'.

因此,没有覆盖输出。事实上,似乎也没有安装 mprof-report,即使在 Mono 命令提示符中也是如此。

那么,考虑到我们根本不倾向于购买软件的企业版,是否有任何方法可以找出我们的 Xamarin MvvmCross 项目的代码覆盖率?如果可以,怎么办?

终于明白了!它绝对不是 CI/CD 友好(目前),但它至少可以用来了解 MvvmCross Xamarin 应用程序中单元测试的当前状态。

此外,它不包括Droid 项目。但由于我们使用 MVVM,Droid 项目应该只包含视图、资源和绑定(理想情况下)。因此,在我看来,覆盖它不如其他项目(AppCore、服务等)那么重要...

无论如何,这是我所做的:

  • 安装 NUnit、NUnitLite、NUnit3TestAdapter、OpenCover 和 ReportGenerator(全部通过 NuGet,直接来自 Visual Studio)
  • Convert MSTest to NUnit
  • Build tests into an executable console application with NUnitLite
  • *将应用程序解决方案中每个项目(Droid 项目和任何测试项目除外)的 buildOptions 中的 debugType 从 "Portable" 更改为 "Full":转到项目属性 -> 构建。然后,在输出部分点击高级和select调试信息 - >更改为。 (Thanks, m4ss1m0g!)
  • 现在,运行 OpenCover 和 ReportGenerator 命令(或下面修改后的 .bat 脚本)将覆盖率报告生成为人类可读的 .htm 文件。使用浏览器打开 .htm 文件,然后 - 瞧 - 您已经报告了您的覆盖率!

这是我使用的简单脚本,我将其放在解决方案的根文件夹中(注意 OpenCover 和 ReportGenerator 包的 版本,以及所有 路径已使用!You can also place filters with OpenCover to exclude or include any Namespaces, Classes and Methods you want).

packages\OpenCover.4.6.519\tools\OpenCover.Console.exe -skipautoprops -output:<path-where-you-want-your-xml-results-to-be>\coverage.xml -target:<path-to-your-test-executable-generated-by-NUnitLite> -register:user -filter:"+[*]<your-solution-name>.* -[nunit*]* -[*<your-test-project-name>]*"

packages\ReportGenerator.4.0.4\tools\net47\ReportGenerator.exe -reports:<path-where-your-xml-results-output-are--same-as-output-path-above>\coverage.xml -targetdir:coverage

观察:

  1. 执行上述步骤并确认其有效后,您可以安装 AxoCover VisualStudio 扩展,它提供了一种查看当前代码覆盖率的实用方法,而不必 运行上面的 .bat 脚本并导航到生成输出 coverage.htm 的文件夹。
  2. 上述过程中的第三步(标有 *)是确保您的测试可执行文件考虑您的其他项目的关键。