先简单介绍一下unittest的核心组成部分:
- 测试夹具:Test Fixture
- 一般用于执行测试用例的准备或者清理工作,比如测试开始前的数据准备或者测试结束的数据清理等。通过setUp()、tearDown()、setUpClass()、tearDownClass()这四个钩子函数实现了测试用例的准备和清理工作。
- setUp():在每一个测试用例执行前都会执行一次
- tearDown():在每一个测试用例执行后都会执行一次
- setUpClass():仅在整个测试类开始执行前执行,且必须使用@classmethod装饰
- tearDownClass():仅在整个测试类结束执行后执行,且必须使用@classmethod装饰
- 测试用例:Test Case
- 是unittest的最小单元,测试用例会继承TestCase这个基类
- 测试用例集:Test Suite
- 又称为测试套件,可以包含一个或者多个测试用例
- 测试用例集包括一个或多个TestSuite类,每一个TestSuite类包括一个或多个TestCase类,也可以包括其他TestSuite类。TestSuite通过addTest()方法或者addTests()方法把一个个测试用例、测试用例集组装成一个新的测试用例集。
- 测试加载器:Test Loader
- 用于从提供的类(class)和模块(module)中生成测试用例集,unittest默认提供一个测试加载器(Default Test Loader)
- 测试加载器加载本地或从外部文件定义好的TestCase类或者TestSuite类
- 默认加载以test开头的.py文件
- 测试运行器:Test Runner
- 用于执行测试用例和输出测试结果
unittest还支持忽略执行某些测试用例,在要忽略的测试用例上添加如下装饰器即可:
- @unittest.skip():执行时直接忽略被装饰的测试用例
- @unittest.skipIf():如果skipIf里的条件成立,执行时直接忽略被装饰的测试用例
- @unittest.skipUnless():永久在执行时忽略被装饰的测试用例,除非skipUnless里的条件成立
- @unittest.expectedFailure:期望被装饰的测试用例是失败的,如果失败的,则此条测试用例被标记为测试通过
接下来我们对上一篇文章中的pageobject三层架构中,业务层(测试用例层)的代码使用unittest框架进行改造。
test_login.py文件的代码如下:
import time
from Module.login import Login
from selenium import webdriver
import unittest
import ddt
test_data = [
{"username":"test123", "password":"123456"},
{"username":"test124", "password":"123456"}
]
# 使用unittest框架
@ddt.ddt
class Login_test(unittest.TestCase):
def setUp(self) -> None:
self.driver = webdriver.Chrome()
self.driver.get('https://mail.163.com')
self.driver.maximize_window()
def tearDown(self) -> None:
time.sleep(5)
self.driver.quit()
@ddt.data(*test_data)
def test_login(self, test_data):
print(test_data)
username = test_data['username']
password = test_data['password']
login = Login()
# login.login(self.driver, 'test123', '123456')
login.login(self.driver, username, password)
if __name__ == '__main__':
unittest.main()
在项目目录下创建一个Reports文件夹,用来存放测试报告的结果。
执行入口run.py文件的修改如下:
import time
import unittest
from Setting.Config import Test_Data_Path, Report_Path, Test_Case_Path
from TestRunner import HTMLTestRunner
import TestRunner
if __name__ == '__main__':
now = time.strftime('%Y-%m-%d %H:%M:%S')
# pytest.main(['-s', '-v', Test_Data_Path])
suit = unittest.TestSuite()
loader = unittest.TestLoader()
suit.addTests(loader.discover(start_dir=Test_Case_Path))
# 生成测试报告,测试报告存放地址及测试报告的名称
with open(Report_Path + '/' + now + 'report.html', 'wb') as fp:
runner = HTMLTestRunner(
stream=fp,
title='test_unittest'
)
runner.run(suit)