单元测试介绍
单元测试没啥可介绍的,就是测试某一个确定的模块(粒度可以是class级别,也可以是func级别)的功能是否符合预期。本文介绍python的unittest模块时,主要是和Java
的junit
进行对比。
python
的单测和Java
的Junit
用法很像,只不过还是有一些细微的区别的。
在Junit
里面,通常有下面几个特点:
- 单元测试类一般命名都是
XxxxTest
,当然也可以不遵守; - 单元测试使用
@Test
来标记一个单元测试方法,如果没有用该注解的话,就是一个普通的方法;
而在python
里面,则有以下特点
- 单元测试类命名一般都是
xxx_test
,当然也可以不遵守; - 单元测试类需要继承
unittest.TestCase
类,这样才会将该类标识为一个单测类
单元测试的方法,并不是使@Test
装饰器来标识,而是使用以test
开头的方法来标识(区分大小写),比如test1()
、test_1()
、testIt()
这些都是单元测试方法,但是TestIt()
、tEstIt()
这样的就是不是,因为前缀要完全匹配test
。
使用示例
# coding:utf-8
import unittest
# 单元测试类要继承unittest模块的TestCase类
class UnitTestDemo(unittest.TestCase):
# 单元测试方法要以小写test前缀开头
def test_echo(self):
print("hello unit test")
def not_a_test_func(self):
print("run not_a_test_func")
# 使用unittest.main()触发所有单测方法的执行
if __name__ == '__main__':
unittest.main()
如果使用IDEA,那么每个单测方法都会出现可执行的按钮,直接点击执行即可。
单元测试的前置操作与后置操作
Junit里面有@before
、@beforeClass
、@after
、@afterClass
注解,这几个注解可以在单元测试方法前后执行一些操作,比如单测执行前的初始化和单测执行后的清理操作;
其中@before
和@after
这两个注解标注的方法,会在每个单测执行前后执行;而@beforeClass
和@afterClass
标注的方法,只会执行一次,@beforeClass
是在所有单测执行前执行,@afterClass
会在所有单测执行后才执行。
Python也有这样的功能,只不过不是通过装饰器方式实现的,而是通过固定的方法名来实现的。
-
setUp()
会在每个单元测试方法的执行前执行,若有多个单测方法,则会执行多次; -
tearDown()
会在每个单元测试方法的执行后才执行,如果有多个单测方法,则会执行多次; -
setUpClass()
会在所有测试方法执行前执行一次,然后就不再执行了,需要使用@classmethod
装饰器将其标识为静态方法; -
tearDownClass
会在所有测试方法都执行完后才执行,且只执行一次,需要使用@classmethod
装饰器将其标识为静态方法;
# coding:utf-8
import unittest # 导入单元测试模块
class MyFuncTest(unittest.TestCase):
# setUpClass方法,所有单测方法执行前,只执行一次
@classmethod
def setUpClass(cls):
print("setUpClass static method")
# setUp方法,每个单测方法执行前都会执行一次
def setUp(self):
print("setUp method")
def tearDown(self):
print("tearDown method")
@classmethod
def tearDownClass(cls):
print("tearDownClass method")
# test开头的方法是单元测试方法
def test_echo_1(self):
print("this is test_echo_1")
def test_echo_2(self):
print("this is test_echo_2")
# 入口,调用unittest.main()方法即可,单元测试模块会自动运行上面的单测
if __name__ == '__main__':
unittest.main()
上面的单测运行后输出如下:
setUpClass static method
setUp method
this is test_echo_1
tearDown method
setUp method
this is test_echo_2
tearDown method
tearDownClass method
assert断言
python里面也支持断言的功能,由于单元测试类继承了TestCase类,那么就可以直接使用断言方法,使用方式如下:
# coding:utf-8
import unittest # 导入单元测试模块
class MyFuncTest(unittest.TestCase):
def test_check(self):
i = 10
# 可以直接使用python的关键字
assert i > 9
# 使用unittest的断言
self.assert_(i > 9, "i不大于9")
# 等级于
# self.assertTrue(i > 11)
self.assertLess(i, 11, "i小于11")
# 入口,调用unittest.main()方法即可,单元测试模块会自动运行上面的单测
if __name__ == '__main__':
unittest.main()
忽略执行
某些情况下,我们不希望某个单元测试方法执行,那么我们可以将其注释掉或者将其名称改成不以test
关键字开头,而另外一种方式是使用@unittest.skip
装饰器来表示不需要执行该单测方法
# 使用@unittest.skip装饰器,可将单测忽略(不会执行)
@unittest.skip("这是忽略测试的原因")
def test_skip_method(self):
print("这个单测会被忽略,不会执行")