python工业互联网应用实战14——单元测试覆盖率
前面的章节我们完成了任务管理主要功能的开发及单元测试编写,可如何知道单元测试效果怎么样呢?测试充分吗?还有没有没有测到的地方呢?
本章节我们介绍一个统计测试代码覆盖率的利器Coverage,Coverage.py (以下简称 Coverage)是 Python 测试界最为流行的一个库之一,用来统计测试覆盖率。测试覆盖率可以从一个角度衡量代码的质量,覆盖率越高,说明测试越充分,代码出现 bug 的几率相对也就越小。当然需要明确的是,测试覆盖率仅仅只是衡量代码质量的一个角度,即是否有代码未经过单元测试验证,不能说100% 的覆盖率的代码就没有 bug 了。
1.1. 安装coverage
IDE Python环境管理里或进入命令行安装coverage,如下图:



1.2. 运行coverage
1.2.1. 工程目录下运行coverage run manage.py test
D:\my tfs\IndDemo>coverage run manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.............
----------------------------------------------------------------------
Ran 13 tests in 0.146s
OK
Destroying test database for alias 'default'...
D:\my tfs\IndDemo>
1.2.2. 查看统计结果coverage report
D:\my tfs\IndDemo>coverage report
Name Stmts Miss Cover
--------------------------------------------------------------------------------------
C:\Users\FQ\AppData\Roaming\Python\Python36\site-packages\six.py 490 242 51%
Collector\__init__.py 0 0 100%
Collector\admin.py 1 0 100%
Collector\migrations\__init__.py 0 0 100%
Collector\models.py 1 0 100%
Collector\tests.py 8 0 100%
Collector\views.py 93 72 23%
IndDemo\__init__.py 0 0 100%
IndDemo\settings.py 21 0 100%
IndDemo\urls.py 9 0 100%
Task\TaskBiz.py 27 5 81%
Task\__init__.py 1 0 100%
Task\admin.py 82 36 56%
Task\apps.py 4 0 100%
Task\migrations\0001_initial.py 7 0 100%
Task\migrations\0002_auto_20210314_0840.py 6 0 100%
Task\migrations\__init__.py 0 0 100%
Task\models.py 81 12 85%
Task\tests.py 78 0 100%
Task\urls.py 3 0 100%
Task\views.py 33 2 94%
TestStringMethods.py 9 1 89%
app\__init__.py 0 0 100%
app\forms.py 6 0 100%
app\migrations\__init__.py 0 0 100%
app\models.py 1 0 100%
app\tests.py 16 0 100%
app\views.py 12 0 100%
manage.py 10 2 80%
--------------------------------------------------------------------------------------
TOTAL 999 372 63%
D:\my tfs\IndDemo>
1.2.3. coverage html命令获得更加详细的信息
此命令在同级目录下生成包含html文件的文件夹,默认名称为htmlcov,点击打开index.html即可。

通过覆盖率统计,我们可以看到Task\views.py文件的代码覆盖率94%,有两行代码未被测试覆盖到,就可以通过点击相关链接查看详情,如下图:


有两行代码未被单元测试覆盖到,红色标注出来了非常方便查看未被覆盖额代码。
1.3. 修改单元测试代码
接下来我们增加单元测试代码,增加 self.client.get('/task/1/change/')测试get请求才能进入到上图标红的代码分支。
...
def test_task_change(self):
data={'source':'111','target':'05-01-11'}
#更新第一个task的源和目标值
response=self.client.post('/task/1/change/',data)
model = Task.objects.get(pk=1)
self.assertEqual(model.Source,'111')
self.assertEqual(model.Target,'05-01-11')
response=self.client.get('/task/')
self.assertIn('111',response.content.decode())
self.assertTemplateUsed(response,'Task/tasks.html')
response=self.client.get('/task/1/change/')
self.assertIn('111',response.content.decode())
self.assertTemplateUsed(response,'Task/taskChange.html')
重新运行代码覆盖命令:
D:\my tfs\IndDemo>coverage run manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.............
----------------------------------------------------------------------
Ran 13 tests in 0.212s
OK
Destroying test database for alias 'default'...
D:\my tfs\IndDemo>coverage html
刷新网页/htmlcov/index.html,我们得到如下图:

文件Task\views.py单元测试代码覆盖率达到了100%
1.4. 配置coverage
windows平台生成.coveragerc配置文件:
D:\my tfs\IndDemo>echo >.coveragerc
1.4.1. 基本配置
[run]
branch = True
source = .
[report]
show_missing = True
- branch = True。是否统计条件语句的分支覆盖情况。if 条件语句中的判断通常有 True 和 False 两种情况,设置 branch = True 后,Coverage 会测量这两种情况是否都被测试到。
- source = .。指定需统计的源代码目录,这里设置为当前目录(即项目根目录)。
- show_missing = True。在生成的统计报告中显示未被测试覆盖到的代码行号。
有一些文件其实并不需要测试,或者并非项目的核心文件(例如部署脚本 fabfile.py,django 的 migrations 文件等),这些文件应该从统计中排除。
Coverage 默认显示全部文件的覆盖率统计结果,如果文件比较多的话就不好查找非 100% 覆盖率的文件。毕竟我们的目标是提高代码覆盖率,因此已达 100% 覆盖的代码文件我们不再关心。我们要做的是找到非 100% 覆盖率的文件,为其添加缺失的测试。
1.4.2. 完善配置
在 [run] 配置块中增加 omit 配置项可以指定排除统计的文件。
在 [report] 配置块中增加 skip_covered 配置项可以指定统计报告中不显示 100% 覆盖的文件。
[run]
branch = True
source = .
omit =
*/__init__.py
manage.py
IndDemo/*
*/migrations/*
IndDemo/wsgi.py
[report]
show_missing = True
skip_covered = True
重新运行覆盖率
D:\my tfs\IndDemo>coverage run manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.............
----------------------------------------------------------------------
Ran 13 tests in 0.157s
OK
Destroying test database for alias 'default'...
D:\my tfs\IndDemo>coverage html

1.5. 小结
通过单元测试的代码覆盖率coverage工具,我们能够快速的定位到那些代码未经过单元测试覆盖到,从而实现单元测试精准的定位,确保覆盖到所有代码。虽然说经过单元测试的代码就没有bug,没有经过单元测试的代码隐藏的可能的bug概率会高得多。所以企业开发过程中引入单元测试和覆盖率肯定会给项目开发质量带来一个飞跃的提升!
这些都是深陷多个项目泥潭后,发现单元测试带来的好处。如果你和你团队也在做一个企业定制开发项目,组织编写单元测试吧,项目的中后期变更、扩展,你会发现编写单元测试的代价是多么的值得!
python工业互联网应用实战14——单元测试覆盖率的更多相关文章
- python工业互联网应用实战2—从需求开始
前言:随着国家工业2025战略的推进,工业互联网发展将会提速,将迎来一个新的发展时期,越来越多的企业开始逐步的把产线自动化,去年年底投产的小米亦庄的智能工厂就是一个热议的新闻.小米/华为智能工厂只能说 ...
- python工业互联网应用实战3—模型层构建
本章开始我们正式进入到实战项目开发过程,如何从需求分析获得的实体数据转到模型设计中来,变成Django项目中得模型层.当然,第一步还是在VS2019 IDE环境重创建一个工程项目,本文我们把工程名称命 ...
- python工业互联网应用实战1—SQL与ORM
从sql到ORM应该说也是编程体系逐步演化的结果,通过类和对象更好的组织开个过程中遇到的各种业务问题,面向对象的解耦和内聚作为一套有效的方法论,对于复杂的企业应用而言确实能够解决实践过程中很多问题. ...
- python工业互联网应用实战7—业务层
本章我们演示代码是如何"进化"的,实战的企业日常开发过程中,系统功能总伴随着业务的不断增加,早期简单的代码慢慢的越来越复杂,敏捷编程中的"禅"--简单设计.快速 ...
- python工业互联网应用实战13—基于selenium的功能测试
本章节我们再来说说测试,单元测试和功能测试.单元测试我们在数据验证章节简单提过了,本章我们进一步如何用单元测试来测试view的功能代码:同时,也涉及一下基于selenium的功能测试做法.笔者过去的项 ...
- python工业互联网应用实战3—Django Admin列表
Django Admin笔者使用下来可以说是Django框架的开发利器,业务model构建完成后,我们就能快速的构建一个增删查改的后台管理框架.对于大量的企业管理业务开发来说,可以快速的构建一个可发布 ...
- python工业互联网应用实战11—客户端UI
这个章节我们将演示用户端界面的开发,当前演示界面还是采用先实现基本功能再逐步完善的"敏捷"模式.首先聚焦在功能逻辑方面实现普通用户与系统的交互,普通用户通过url能查看到当前任务的 ...
- python工业互联网应用实战15-前后端分离模式1
我们在13章节里通过监控界面讲了如何使用jquery的动态加载数据写法,通过简单案例来说明了如何实现动态的刷新监控界面的数据,本章我们将演示如何从Django模板加载数据逐步演化到前后端分离的异步数据 ...
- python工业互联网应用实战18—前后端分离模式之jquery vs vue
前面我们分三章来说明了使用django template与jquery的差别,通过jquery如何来实现前后端的分离,同时再9章节使用vue.js 我们浅尝辄止的介绍了JQuery到vue的切换,由于 ...
随机推荐
- 2021年的UWP(6)——长生命周期Desktop Extension向UWP的反向通知
上一篇我们讨论了UWP和Desktop Extension间的双向通讯,适用于Desktop Extension中存在用户交互的场景.本篇我们讨论最后一种情况,与前者不同的是,Desktop Exte ...
- DAOS 分布式异步对象存储|存储模型
概述 DAOS Pool 是分布在 Target 集合上的存储资源预留.分配给每个 Target 上的 Pool 的实际空间称为 Pool Shard. 分配给 Pool 的总空间在创建时确定,后期可 ...
- C++并发与多线程学习笔记--多线程数据共享问题
创建和等待多个线程 数据和共享问题分析 只读的数据 有读有写 其他案例 共享数据的保护案例代码 创建和等待多个线程 服务端后台开发就需要多个线程执行不同的任务.不同的线程执行不同任务,并返回执行结果. ...
- .NET 6 Preview 3 中 ASP.NET Core 的更新和改进
原文:bit.ly/2Qb56NP 作者:Daniel Roth 译者:精致码农-王亮 .NET 6 预览版 3 现已推出,其中包括许多对新的 ASP.NET Core 改进.以下是本次预览版的新内容 ...
- 使用 EPPlus 封装的 excel 表格导入功能 (.net core c#)
使用 EPPlus 封装的 excel 表格导入功能 前言 最近做系统的时候有很多 excel导入 的功能,以前我前后端都做的时候是在前端解析,然后再做个批量插入的接口 我觉着这样挺好的,后端部分可以 ...
- [Fundamental of Power Electronics]-PART II-9. 控制器设计-9.6 环路增益的测量/9.7 本章小结
9.6 环路增益的测量 测量原型反馈系统的环路增益是一个非常好的工程实践.这种实践的目的是验证系统是否被正确地建模.如果是的,那么已经应用了良好控制器设计的系统,其特性将满足相关瞬态过冲(相角裕度), ...
- 【C/C++】malloc和new的区别
malloc和new的区别 malloc是C语言的内存申请函数.new是C++语言的运算符.所以在.c文件中无法使用new. malloc申请空间时,传递的是size.new申请空间时,传递的是typ ...
- 为Github的README.md生成目录的小工具
1 概述 因为Github的README.md文件[TOC]不生效,因此封装了一个别人已封装好的JAR包供大家使用. 2 使用方法 用Java做的,只需要JDK11以上的环境: java -jar t ...
- 【Azure Developer】使用Java代码启动Azure VM(虚拟机)
问题描述 在使用Java的启动Azure VM的过程中,遇见了com.azure.core.management.exception.ManagementException: Status code ...
- editorconfig、eslint、prettier三者的区别、介绍及使用
每次搭建新项目都少不了这些工具,但时间一久就忘记了,下次搭新项目时又要四处查官方文档,因此特此记录,主要内容是对这三个工具的理解,以及具体使用方式 editorconfig 理解 先看官网的定义: E ...