前面的章节我们完成了任务管理主要功能的开发及单元测试编写,可如何知道单元测试效果怎么样呢?测试充分吗?还有没有没有测到的地方呢?

  本章节我们介绍一个统计测试代码覆盖率的利器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——单元测试覆盖率的更多相关文章

  1. python工业互联网应用实战2—从需求开始

    前言:随着国家工业2025战略的推进,工业互联网发展将会提速,将迎来一个新的发展时期,越来越多的企业开始逐步的把产线自动化,去年年底投产的小米亦庄的智能工厂就是一个热议的新闻.小米/华为智能工厂只能说 ...

  2. python工业互联网应用实战3—模型层构建

    本章开始我们正式进入到实战项目开发过程,如何从需求分析获得的实体数据转到模型设计中来,变成Django项目中得模型层.当然,第一步还是在VS2019 IDE环境重创建一个工程项目,本文我们把工程名称命 ...

  3. python工业互联网应用实战1—SQL与ORM

    从sql到ORM应该说也是编程体系逐步演化的结果,通过类和对象更好的组织开个过程中遇到的各种业务问题,面向对象的解耦和内聚作为一套有效的方法论,对于复杂的企业应用而言确实能够解决实践过程中很多问题. ...

  4. python工业互联网应用实战7—业务层

    本章我们演示代码是如何"进化"的,实战的企业日常开发过程中,系统功能总伴随着业务的不断增加,早期简单的代码慢慢的越来越复杂,敏捷编程中的"禅"--简单设计.快速 ...

  5. python工业互联网应用实战13—基于selenium的功能测试

    本章节我们再来说说测试,单元测试和功能测试.单元测试我们在数据验证章节简单提过了,本章我们进一步如何用单元测试来测试view的功能代码:同时,也涉及一下基于selenium的功能测试做法.笔者过去的项 ...

  6. python工业互联网应用实战3—Django Admin列表

    Django Admin笔者使用下来可以说是Django框架的开发利器,业务model构建完成后,我们就能快速的构建一个增删查改的后台管理框架.对于大量的企业管理业务开发来说,可以快速的构建一个可发布 ...

  7. python工业互联网应用实战11—客户端UI

    这个章节我们将演示用户端界面的开发,当前演示界面还是采用先实现基本功能再逐步完善的"敏捷"模式.首先聚焦在功能逻辑方面实现普通用户与系统的交互,普通用户通过url能查看到当前任务的 ...

  8. python工业互联网应用实战15-前后端分离模式1

    我们在13章节里通过监控界面讲了如何使用jquery的动态加载数据写法,通过简单案例来说明了如何实现动态的刷新监控界面的数据,本章我们将演示如何从Django模板加载数据逐步演化到前后端分离的异步数据 ...

  9. python工业互联网应用实战18—前后端分离模式之jquery vs vue

    前面我们分三章来说明了使用django template与jquery的差别,通过jquery如何来实现前后端的分离,同时再9章节使用vue.js 我们浅尝辄止的介绍了JQuery到vue的切换,由于 ...

随机推荐

  1. python基础学习之函数进阶【匿名函数、作用域关系、闭包、递归】

    匿名函数 lambda的用法: lambda x:x+1 解释,同等于以下函数 def test(x): return x+1 因为没有函数名,所以称为匿名函数 只适用于简易的逻辑,复杂逻辑无法实现 ...

  2. 在Windows10搭建WebAssembly开发环境

    最近研究WebAssembly技术,准备用WebAssembly编译C/C++代码供前端调用.网上看了很多文章,收获很大,现在就遇到的问题做一个记录. 官网关于windows开发环境搭建基本上几句话, ...

  3. 叫练手把手教你读JVM之GC信息

    案例 众所周知,GC主要回收的是堆内存,堆内存中包含年轻代和老年代,年轻代分为Eden和Surivor,如下图所示.我们用案例分析下堆的GC信息[版本:HotSpot JDK1.8]. /** * @ ...

  4. elf.h

    1 /* This file defines standard ELF types, structures, and macros. 2 Copyright (C) 1995-2019 Free So ...

  5. 用 Go + WebSocket 快速实现一个 chat 服务

    前言 在 go-zero 开源之后,非常多的用户询问是否可以支持以及什么时候支持 websocket,终于在 v1.1.6 里面我们从框架层面让 websocket 的支持落地了,下面我们就以 cha ...

  6. ES 终于可以搜到”悟空哥“了!

    Elasticsearch 搜索引擎内置了很多种分词器,但是对中文分词不友好,所以我们需要借助第三方中文分词工具包. 悟空哥专门研究了下 ik 中文分词工具包该怎么玩,希望对大家有所帮助. 本文主要内 ...

  7. > 与 < 差在哪?-- Shell十三问<第十一问>

    > 与 < 差在哪?-- Shell十三问<第十一问> 谈到 I/O redirection ,不妨先让我们认识一下 File Descriptor (FD) .程序的运算,在 ...

  8. BLE链路层状态机初探

    状态机 BLE链路层把所有的功能放到五种不同的状态中,在不同的状态分别执行不同的功能. 一般来说,BLE设备大致有这么几种状态:空闲,广播,扫描,发起连接和连接成功. 广播和扫描是相对应的,一个设备广 ...

  9. OpenPAL3:仙三开源版的第二个小目标 Accomplish!

    去年的时候,OpenPAL3 的第一个版本发布 之后,我给 0.2 版本设定了一个小目标:让景天能跑出永安当.当时的第一个版本还只能算是概念验证的版本,没有音乐支持.输入支持,不能直接读取仙剑三的打包 ...

  10. 如何解压从UK biobank下载下来的tsv.bgz文件?

    今天碰到一个问题,就是从UK biobank下载下来的gwas result file是filename.tsv.bgz格式.这东西需要解压才能阅历,可是用zip或者rar都是搞不定,网上搜了一圈,说 ...