unittest简述
unittest属于标准库,也就是python自带的,不需要安装就可以直接使用!unittest 单元测试框架是对程序的最小模块进行的一种敏捷化测试
测试固件
假设现在要测试使用selenium打开百度首页搜索,呢么在测试之前需要打开浏览器并进入到百度,测试结束,需要关闭浏览器。测试固件提供了两种执行方式:
1.测试固件每次均执行import unittest
class BaiduTest(unittest.TestCase):
# 先执行setUp方法
def setUp(self) -> None:
print('start...')
# 最后执行tearDown方法
def tearDown(self) -> None:
print('end...')
# 再执行测试用例test_baidu方法
def test_baidu(self):
print('测试用例被执行')
if __name__ == '__main__':
unittest.main(verbosity=2)
start...
测试用例被执行
end...
test_baidu (__main__.BaiduTest) ... ok
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
编写两个测试用例:
import unittest
from selenium import webdriver
class BaiduTest(unittest.TestCase):
# 先执行setUp方法
def setUp(self) -> None:
self.driver = webdriver.Firefox()
self.driver.get('https://www.baidu.com')
self.driver.implicitly_wait(10)
# 最后执行tearDown方法
def tearDown(self) -> None:
self.driver.quit()
# 再执行测试用例test_baidu方法
def test_baidu_input(self):
self.driver.find_element_by_id('kw').send_keys('鳄鱼君')
def test_baidu_click(self):
self.driver.find_element_by_id('su').click()
if __name__ == '__main__':
unittest.main(verbosity=2)
你会发现,两个测试用例,浏览器会被打开两次,关闭两次。测试用例很多,这样就非常不合理!
2.测试固件只执行一次
要想让测试用例至执行一次,就需要使用setUpClass和tearDownClass这两个测试固件,这样,不管有多少个测试用例,测试固件只执行一次,看代码:
import unittest
class BaiduTest(unittest.TestCase):
# 先执行setUp方法
@classmethod
def setUpClass(cls) -> None:
print('start...')
# 最后执行tearDown方法
@classmethod
def tearDownClass(cls) -> None:
print('end...')
# 再执行测试用例
def test_1(self):
print('测试用例被执行')
def test_2(self):
print('测试用例被执行')
def test_3(self):
print('测试用例被执行')
if __name__ == '__main__':
unittest.main(verbosity=2)
start...
测试用例被执行
测试用例被执行
测试用例被执行
end...
test_1 (__main__.BaiduTest) ... ok
test_2 (__main__.BaiduTest) ... ok
test_3 (__main__.BaiduTest) ... ok
----------------------------------------------------------------------
Ran 3 tests in 0.000s
OK
然后修改一下代码:
import unittest
from selenium import webdriver
class BaiduTest(unittest.TestCase):
# 先执行setUp方法
driver = None
@classmethod
def setUpClass(cls) -> None:
cls.driver = webdriver.Firefox()
cls.driver.get('https://www.baidu.com')
cls.driver.implicitly_wait(10)
# 最后执行tearDown方法
@classmethod
def tearDownClass(cls) -> None:
cls.driver.quit()
# 再执行测试用例
def test_baidu_input(self):
self.driver.find_element_by_id('kw').send_keys('鳄鱼君')
def test_baidu_click(self):
self.driver.find_element_by_id('su').click()
if __name__ == '__main__':
unittest.main(verbosity=2)
测试执行
代码运行的是unittest的main,我们看一下具体的源码:。你会发现verbosity的默认值是1。我们上面的代码是2,会显示详细的信息!如果在一个测试类中,单独执行某个测试用例,可以按照下图操作:

构建测试套件
一个测试类中会有很多个测试用例,现在我想要让这些测试用例按照顺序执行。这里先打开百度搜索栏,然后输入内容,搜索:import unittest
from selenium import webdriver
class BaiduTest(unittest.TestCase):
# 先执行setUp方法
def setUp(self) -> None:
self.driver = webdriver.Firefox()
self.driver.get('https://www.baidu.com')
self.driver.implicitly_wait(10)
# 最后执行tearDown方法
def tearDown(self) -> None:
self.driver.quit()
# 再执行测试用例test_baidu方法
def test_baidu_input(self):
self.driver.find_element_by_id('kw').send_keys('鳄鱼君')
def test_baidu_click(self):
self.driver.find_element_by_id('su').click()
if __name__ == '__main__':
suite = unittest.TestSuite()
# 先添加的先执行,后添加的后执行
suite.addTest(BaiduTest('test_baidu_input')) //先输入
suite.addTest(BaiduTest('test_baidu_click')) //再搜索
unittest.TextTestRunner(verbosity=2).run(suite)
按照测试类执行:
import unittest
from selenium import webdriver
class BaiduTest(unittest.TestCase):
# 先执行setUp方法
def setUp(self) -> None:
self.driver = webdriver.Firefox()
self.driver.get('https://www.baidu.com')
self.driver.implicitly_wait(10)
# 最后执行tearDown方法
def tearDown(self) -> None:
self.driver.quit()
# 再执行测试用例test_baidu方法
def test_baidu_input(self):
self.driver.find_element_by_id('kw').send_keys('鳄鱼君')
def test_baidu_click(self):
self.driver.find_element_by_id('su').click()
if __name__ == '__main__':
# 把测试用例类中所有的测试用例组成测试套件,比卖你注意向测试套件中添加测试用例
suite = unittest.TestSuite(unittest.makeSuite(BaiduTest))
unittest.TextTestRunner(verbosity=2).run(suite)
加载测试类,,最后会显示测试执行的时间:
import unittest
from selenium import webdriver
class BaiduTest(unittest.TestCase):
# 先执行setUp方法
def setUp(self) -> None:
self.driver = webdriver.Firefox()
self.driver.get('https://www.baidu.com')
self.driver.implicitly_wait(10)
# 最后执行tearDown方法
def tearDown(self) -> None:
self.driver.quit()
# 再执行测试用例test_baidu方法
def test_baidu_input(self):
self.driver.find_element_by_link_text('新闻').click()
def test_baidu_click(self):
self.driver.find_element_by_link_text('地图').click()
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(BaiduTest)
unittest.TextTestRunner(verbosity=2).run(suite)
按测试模块,执行该模块下的所有测试类。一个py文件就是一个模块,再一个py文件中,可以有N个测试类,N个测试用例,我们可以设置按照模块执行:
import unittest
from selenium import webdriver
class BaiduTest(unittest.TestCase):
# 先执行setUp方法
def setUp(self) -> None:
self.driver = webdriver.Firefox()
self.driver.get('https://www.baidu.com')
self.driver.implicitly_wait(10)
# 最后执行tearDown方法
def tearDown(self) -> None:
self.driver.quit()
# 再执行测试用例test_baidu方法
def test_baidu_input(self):
self.driver.find_element_by_link_text('新闻').click()
def test_baidu_click(self):
self.driver.find_element_by_link_text('地图').click()
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromModule('test.py')
unittest.TextTestRunner(verbosity=2).run(suite)
优化测试套件,单独把测试套件写成一个方法调用:
import unittest
from selenium import webdriver
class BaiduTest(unittest.TestCase):
# 先执行setUp方法
def setUp(self) -> None:
self.driver = webdriver.Firefox()
self.driver.get('https://www.baidu.com')
self.driver.implicitly_wait(10)
# 最后执行tearDown方法
def tearDown(self) -> None:
self.driver.quit()
# 再执行测试用例test_baidu方法
def test_baidu_input(self):
self.driver.find_element_by_link_text('新闻').click()
def test_baidu_click(self):
self.driver.find_element_by_link_text('地图').click()
@staticmethod
def suite(test_class):
suite = unittest.TestLoader().loadTestsFromTestCase(test_class)
return suite
if __name__ == '__main__':
unittest.TextTestRunner(verbosity=2).run(BaiduTest.suite(BaiduTest))
分离测试固件
如果有多个测试类,呢么打开浏览器和关闭浏览器的代码都是重复的,我们可以将这些代码分离出去,然后每个测试类继承即可!import unittest
from selenium import webdriver
class InitTest(unittest.TestCase):
def setUp(self) -> None:
self.driver = webdriver.Firefox()
self.driver.get('https://www.baidu.com')
self.driver.implicitly_wait(10)
def tearDown(self) -> None:
self.driver.quit()
编写测试类的时候需要继承该类:
import unittest
from slave import InitTest
class BaiduTest(InitTest):
def test_baidu_input(self):
self.driver.find_element_by_link_text('新闻').click()
def test_baidu_click(self):
self.driver.find_element_by_link_text('地图').click()
@staticmethod
def suite(test_class):
suite = unittest.TestLoader().loadTestsFromTestCase(test_class)
return suite
if __name__ == '__main__':
unittest.TextTestRunner(verbosity=2).run(BaiduTest.suite(BaiduTest))
测试断言
判断实际测试结果与预期结果是否一致,一直通过,不一直报错。方法 | 介绍 |
---|---|
assertEqual(a,b) | a == b |
assertNotEqual(a,b) | a != b |
assertTrue(x) | bool(x) is True |
assertFalse(x) | bool(x) is False |
assertIs(a,b) | a is b |
assertIsNot(x) | a is not b |
assertIsNone(x) | x is None |
assertIsNotNone(x) | x is not None |
assertIn(a,b) | a in b |
assertNotIn(a,b) | a not in b |
assertIsInstance(a,b) | isinstance(a,b) |
assertNotIsInstance(a,b) | not isinstance(a,b) |
import unittest
from selenium import webdriver
class BaiduTest(unittest.TestCase):
def setUp(self) -> None:
self.driver = webdriver.Firefox()
self.driver.get('https://www.baidu.com')
self.driver.implicitly_wait(10)
def tearDown(self) -> None:
self.driver.quit()
def test_baidu_input(self):
title = self.driver.title
if title == '百度':
print('success')
else:
print('fail')
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(BaiduTest)
unittest.TextTestRunner(verbosity=2).run(suite)
结果是fail,但是测试时ok的,所以尽量要使用断言,来代替这样的判断!也不要再断言的位置捕获异常,异常捕获之后,测试还是ok的,测试毛线,就用断言!
批量执行测试用例
现在再test文件下有test_baidu.py和test_eyujun.py两个文件,现在创建一个all_test.py文件用来批量执行这两个测试用例:import os
import unittest
def all_case():
# discover批量获取测试模块,start_dir测试路径,pattern正则匹配包名
suite = unittest.TestLoader().discover(
start_dir=os.path.dirname(__name__),
pattern='test_*.py',
top_level_dir=None
)
return suite
if __name__ == '__main__':
unittest.TextTestRunner(verbosity=2).run(all_case())
你自己编写几个测试模块试一下,这里只给出批量执行的例子!
生成测试报告
这里可以借助第三方库生成HTML格式的测试报告,下载地址:https://github.com/tungwaiyip/HTMLTestRunner,下载 HTMLTestRunner.py文件后,把该文件放到 Python安装路径的Lib子文件夹中,例如,C:\Python36-32\Lib目录下。当然也可以使用pip命令:pip install html-testrunner
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。