测试基础 开源项目核心代码单元测试 100% 覆盖率实战

花菜 · 2024年04月22日 · 最后由 King 回复于 2024年04月25日 · 7265 次阅读

1、背景

最近发现之前开源个人自用的django-ninja脚手架项目,居然有了 30 个 star。

在这个项目上增加一些新的功能时,每次修改代码后,手动测试是挺麻烦的。

并且也不知道是否会影响到以前的功能,代码覆盖率是多少。

image.png

因此决定加强该项目的单元测试,目标是 100% 覆盖核心代码。
image.png

2、单元测试

单元测试框架就直接用 django 自带的 TestClient,没有额外使用 pytest。

之前有看过 pytest-django,但暂时用不到,就先放着。
覆盖率统计直接参考 httprunner,使用了 coverage

下面开始实操

2.1 Codecov 配置

使用 github 登录
https://app.codecov.io/

登录后,就能看到 github 账号下所有的仓库了
image.png

点击需要配置的项目后面的 Configure
image.png

然后复制 CODECOV_TOKEN 对应的值,也就是打马赛克的部分

image.png

然后取到 github 对应的仓库,创建一个秘钥,这个秘钥是给接下来的 github action 用的
image.png

具体的代码在这里
https://github.com/lihuacai168/django-ninja-demo/blob/main/.github/workflows/django-test.yml

简单说一下这个 actions 的左右,跟 Jenkins 的流水线一样,steps 就是定义步骤

大概步骤就是:

  • 拉取代码
  • 安装 python 依赖
  • 执行单元测试
  • 生成 coverage xml 报告
  • 上传 coverage xml 报告到 Codecov(这一步需要用到 CODECOV_TOKEN 这个秘钥) image.png

2.2 单元测试

在 django 中编写单元测试非常简单,只需导入 Django.test 下面的 TestCase,继承即可,详细参考

https://github.com/lihuacai168/django-ninja-demo/blob/main/employee/tests.py
image.png

2.3 本地执行单元测试

执行单测

# 首次执行需要安装coverage,pip install coverage
$ coverage run --source='.' manage.py test                                                             
Found 11 test(s).
Creating test database for alias 'default'...
System check identified some issues:

.................
----------------------------------------------------------------------
Ran 11 tests in 2.574s

OK
Destroying test database for alias 'default'...

执行单测,生成 html 报告,并且在浏览器打开

coverage run --source='.' manage.py test && coverage html && open htmlcov/index.html

image.png

可以看到整体的覆盖率是 96%,其他的文件都 100% 覆盖

utils/model_opertion.py 这个文件覆盖率只有 60%,点击进去之后,可以查看到具体哪里没有被覆盖

image.png

2.4 coverage 覆盖配置

在实践中,有些文件不需要被覆盖的,可以通过这样配置

image.png

有些语句不需要覆盖率的,使用# pragma: no cover就能标记为不需要覆盖
image.png

2.5 CICD 自动执行单测并统计覆盖率

因为我们在前面配置好了 github action,代码推送到远程之后

单元测试会自动执行 (可在 action 中自行定义触发条件),并且报告统计出来,发送到 Codecov,非常的方便。

在尤其开源项目中,别人提交了 PR,我们就能根据单元测试的结果和覆盖率,决定是否接受他的 PR
https://github.com/lihuacai168/django-ninja-demo/pull/12
image.png

也可以通过配置,直接在 README 引用覆盖率结果,让别人一眼就能出来当前项目的代码覆盖率

image.png

2.6 Codecov 覆盖率结果

在 codecov 中,覆盖率的结果都会被统计出来,并且历史记录,非常方便溯源
image.png

3、总结

项目的单元测试经过整合 Github Ations + Coverage + TestClient + Codecov,测试流程也从手动走向自动化,大幅度提高了项目质量和可维护性。

目前整体 96%,只需要把 utils/model_opertion.py 的覆盖率提升上来,就能完美实现 100% 覆盖率,加油!

公众号原文

共收到 9 条回复 时间 点赞

欢迎留言一起交流哦~

其实这个论坛对技术不太感兴趣的,怎么实践也是。这些离一般的测试的实际工作稍微有点远了。

simonpatrick 回复

不至于吧,这个帖没人讨论,我个人感觉是因为文章里的这个单位测试不是测试业务项目的,是自测自己的测试平台的,额。。。怎么说呢,感觉有点诡异,但是又说不出哪里不对

测试新人 回复

翻译一下,就是没啥用;

确实没啥用

(如果有 Java 版就好了)看 Python 有种看英文文档的阻塞感

测试新人 回复

为啥要把目光局限于业务测试呢,除非一直相当点工?,如果真是这样确实无所谓。

测试工具类,基础库这些,没有和业务强相关单元测试是重要的。

后续迭代维护,没单测,每次改动心智负担很重。
另外,可能大部分测试人员也没有参与过开源项目的贡献,提一个 PR 上来,没有测试代码,直接就合并,就过于草率啦。

林冲冲 回复

第一次听说堵塞感这个词😀
Java 生态我不熟悉呢

花神可以的,上个自动化就是用花神的,这次继续学习,不局限于当下,认真准备。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册