python中的单元测试框架
python中的单元测试框架有很多,什么unittest, testtools, subunit, coverage, testrepository, nose, mox, mock, fixtures, discover等等,看着就眼花撩乱。单元测试的重要性就不多说了,作为一名合格的程序员,会写单元测试是必要条件,这里我们就从最简单的单元测试开始看起。
Unittest
Unittest是python的一个标准模块,是其他框架的基础。unittest有几个重要的概念,test fixture, test case, test suite, test runner,只有理解了这几个概念,才能真正的理解单元测试的基本原理。
TestCase: 一个TestCase的实例就是一个测试用例。什么是测试用例呢?就是一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown)。Unittest的本质也就在这里,一个测试用例是一个完整的测试单元,通过运行这个测试单元,可以对某一个问题进行验证。
TestSuit: 而多个测试用例集合在一起,就是TestSuite,而且TestSuite也可以嵌套TestSuite
TestLoader: 是用来加载TestCase到TestSuite中的,其中有几个loadTestsFrom__()方法,就是从各个地方寻找TestCase,创建它们的实例,然后add到TestSuite中,再返回一个TestSuite实例。
TextTestRunner是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法。
测试的结果会保存到TextTestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息
下面我们就写一个简单的测试用例。
|
|
然后写一个测试用例:
|
|
运行这个测试用例:
|
|
关于python -m
相信你一定见过python -m的用法,但是你知道python test.py 和 python -m test.py的区别吗?
python test.py: 直接运行, 就是把test.py所在的目录放到了sys.path中。
python -m test.py: 把模块当作脚本启动,也就是把你当前输入命令的目录放到sys.path中。
比如,我们有一个工程文件夹,结构如下:
|
|
如果我们直接运行,python3 tests/test_num.py会报如下的错误:
|
|
但是我们如果以模块的方式启动,则可以正常运行:
|
|
这就是python -m的作用。
运行unittest
可以使用命令
|
|
也可以使用discover自动查找测试用例并执行
|
|
集成Unittest到SonarQube
在CI/CD的过程中,用到了代码测试工具SonarQube,并集成到了jenkins中,这样使得在构建之前就可以使用SonarQube对代码进行单元测试。
SonarQube集成python框架可以使用nose,但是这里我们先使用最原始的unittest,看一下如何在SonarQbue中部署。
在Jenkins的构建步骤中首先配置好SonarQube:
|
|
然后再shell中执行命令:
|
|
因为nosetests命令默认是会忽略掉可执行文件的,所以要加上–exe来确保可以正常启动测试。
关于单元测试的其他框架和内容,等有时间再继续。