原生测试框架Unittest 解决重复性前置条件的问题
核心机制解析
1. 测试类基础结构
class TestA(unittest.TestCase, Oder):
@classmethod
def setUpClass(cls):
...
def setUp(self):
self.get()
self.login()
- 关键组件:
unittest.TestCase
:测试用例基类Oder
:页面对象类(提供业务操作)setUpClass
:类级别初始化(整个测试类执行前运行一次)setUp
:方法级别初始化(每个测试方法执行前运行)
生命周期钩子详解
2. 执行流程图示
3. 方法作用对比
方法 | 执行时机 | 典型用途 |
---|---|---|
setUpClass | 整个测试类开始前执行一次 | 初始化全局资源(如启动浏览器) |
setUp | 每个测试方法执行前 | 准备测试环境(如登录操作) |
tearDown | 每个测试方法执行后 | 清理测试数据 |
tearDownClass | 整个测试类结束后执行一次 | 释放全局资源(如关闭浏览器) |
代码实现解析
4. 前置条件复用实现
def setUp(self):
self.get() # 来自Oder类的页面访问方法
self.login() # 来自Oder类的登录操作方法
- 作用机制:
- 每个测试方法执行前自动调用
- 统一执行页面访问和登录操作
- 避免在每个测试方法中重复编写相同代码
5. 测试方法示例
def test_Oder(self):
self.search_bug()
assert self.element(self.order_label).text == 'Web Orders'
def test_logout(self):
self.logout()
assert self.driver.current_url == '...'
- 优势体现:
- 测试方法只需关注业务验证
- 前置条件自动保障一致性
- 降低代码维护成本
最佳实践建议
6. 优化方案对比
方案 | 优点 | 缺点 |
---|---|---|
方法内直接调用 | 直观可见 | 重复代码多,维护成本高 |
使用setUp | 统一管理前置条件 | 需要合理设计继承体系 |
装饰器封装 | 灵活组合不同前置条件 | 增加代码复杂度 |
7. 扩展建议
def tearDown(self):
if hasattr(self, 'driver'):
self.driver.quit()
@classmethod
def setUpClass(cls):
cls.driver = Chrome().start_chrome_browser # 全局浏览器实例
常见问题解决方案
8. 异常处理模式
def setUp(self):
try:
self.get()
self.login()
except Exception as e:
self.fail(f"前置条件初始化失败: {str(e)}")
9. 条件跳过机制
@unittest.skipIf(env == 'prod', '跳过生产环境执行')
def test_danger_operation(self):
...
10.完整代码
import unittest
from chap3.po import *
class TestA(unittest.TestCase, Oder):
@classmethod
def setUpClass(cls):
...
def setUp(self):
self.get()
self.login()
def test_Oder(self):
self.search_bug()
assert self.element(self.order_label).text == 'Web Orders'
def test_logout(self):
self.logout()
assert self.driver.current_url == ('http://secure.smartbearsoftware.com/samples/'
'TestComplete12/WebOrders/Login.aspx?ReturnUrl='
'%2fsamples%2fTestComplete12%2fWebOrders%2fDefault.aspx')
通过合理使用测试生命周期钩子,可使测试代码维护成本降低约50% .
「小贴士」:点击头像→【关注】按钮,获取更多软件测试的晋升认知不迷路! 🚀