一、基本用法
unittest是python自带的单元测试框架,主要用于测试用例的组织和执行。
1、基本概念
TestCase:即一个测试用例,包含测试环境准备、测试过程、测试结束后环境销毁等完整的测试流程
TestSuite:多个TestCase的集合构成测试套件
TestRunner:执行测试用例
Test fixture:对测试环境的创建和销毁,比如,在测试之前需要进行登录,测试完成后需要进行退出登录,测试用例更过的专注于核心测试逻辑
上述相关类的源码可以参考博客:https://blog.csdn.net/fengguangke/category_7941105.html
2、基本用法
import unittest
from calculator import Count
#测试类需要继承unittest的TestCase类
class TestCount(unittest.TestCase):
#重写setUp方法,进行测试前的操作
def setUp(self):
print('测试开始')
# 重写tearDown方法,进行测试前的操作
def tearDown(self):
print('测试结束')
#测试核心逻辑
def test_add(self):
res = Count(1,2).add()
self.assertEqual(res,3,'计算错误!')
def test_add1(self):
res = Count(2,3).add()
self.assertEqual(res,5,'计算错误')
if __name__ == '__main__':
unittest.main()
执行结果如下:
说明:
1、每个测试用例都会单独执行setUp、tearDown方法;
2、测试方法以test开头命名;
二、拓展用法
参考整理大神博客,主要是:https://blog.csdn.net/fengguangke/category_7941105.html
1、构建TestSuite的几种方法:
(1). 通过unittest.TestSuite()类直接构建,或者通过TestSuite实例的addTests、addTest方法构建
import unittest
class UserCase(unittest.TestCase):
def testAddUser(self):
print("add a user")
def testDelUser(self):
print("delete a user")
if __name__ == '__main__':
suite = unittest.TestSuite(map(UserCase,['testAddUser','testDelUser']))
suite2 = unittest.TestSuite()
suite2.addTests(map(UserCase,['testAddUser','testDelUser']))
suite3 = unittest.TestSuite()
suite3.addTest(UserCase('testAddUser'))
suite3.addTest(UserCase('testDelUser'))
(2). 通过unittest.TestLoader类的discover、loadTestsFromTestCase、loadTestsFromModule、loadTestsFromName、loadTestsFromNames这五个方法去构建
import unittest
class UserCase(unittest.TestCase):
def testAddUser(self):
print("add a user")
def testDelUser(self):
print("delete a user")
if __name__ == '__main__':
module = __import__(__name__)
suite = unittest.TestLoader().discover('.','unittest_user.py') #unittest_user.py
suite2 = unittest.TestLoader().loadTestsFromTestCase(UserCase)
suite3 = unittest.TestLoader().loadTestsFromModule(module)
(3). 通过unittest.makeSuite()、unittest.findTestCases()这两个方法去构建
import unittest
class UserCase(unittest.TestCase):
def testAddUser(self):
print("add a user")
def testDelUser(self):
print("delete a user")
if __name__ == '__main__':
module = __import__(__name__)
suite = unittest.makeSuite(UserCase,prefix='test')
suite2 = unittest.findTestCases(module,prefix='test')
2、unittest执行顺序
unittest框架默认根据ASCII码的顺序加载测试用例,数字与字母的顺序为:0~9,A~Z,a~z。所以,TestAdd类会优先于TestBdd类被执 行,test_aaa()方法会优先于test_ccc()被执行,因而它并没有按照用例从 上到下的顺序执行;
对于测试目录与测试文件来说,unittest框架同样是按照这个规则来 加载测试用例。
3、跳过测试和预期失败
在运行测试时,有时需要直接跳过某些测试用例,或者当用例符合 某个条件时跳过测试,又或者直接将测试用例设置为失败。unittest提供了实现这些需求的装饰器:
#无条件的跳过装饰的测试方法或类
unittest.skip(reason)
#当条件为真时,跳过装饰的的测试方法或类
unittest.skipIf(condition, reason)
#跳过装饰的测试方法或类,除非条件为真
unittest.skipUnless(condition, reason)
#不管执行结果是否为失败,同一标记为失败
unittest.expectedFailure()
4、更大范围的fixture
对于测试module、测试类、测试方法都有对应的fixture,完整的示例代码:
from selenium import webdriver from selenium.webdriver.common.by import By import unittest def setUpModule(): print('start module') def tearDownModule(): print('end module') class TestClass(unittest.TestCase): @classmethod def setUpClass(cls): print('start class') @classmethod def tearDownClass(cls): print('end class') def setUp(self): print('start case') def tearDown(self): print('end case') def test_add(self): print('case1') def test_add1(self): print('case2') if __name__ == '__main__': unittest.main()
执行结果如下:
可以看出模块和类的fixture只执行了一次,而对于测试方法的fixture,有多少个测试方法就执行了几次