如何将Python+Unittest+Appium的iOS测试结果同步至TestRail?
实现Unittest测试结果自动同步到TestRail
核心思路
利用Unittest的钩子方法(如tearDown)或自定义TestResult类,统一处理测试结果的上报逻辑,避免在每个测试用例中重复编写上报代码。同时通过装饰器或元数据关联测试用例与TestRail的case_id。
方案一:基于测试基类的tearDown方法实现
1. 定义装饰器标记TestRail Case ID
用装饰器给每个测试用例绑定对应的TestRail用例ID,方便后续上报时获取:
def testrail_case(case_id): def decorator(test_func): test_func.case_id = case_id return test_func return decorator
2. 编写测试基类
继承unittest.TestCase,在setUpClass中初始化TestRail API,在tearDown中自动判断当前用例的执行结果并上报:
import unittest from testrail_api import TestRailAPI class TestRailBaseTestCase(unittest.TestCase): @classmethod def setUpClass(cls): # 初始化TestRail API连接 cls.testrail_api = TestRailAPI( url="https://你的TestRail地址/", email="你的账号邮箱", password="你的API密钥或密码" ) cls.test_run_id = 123 # 目标测试运行的ID,需提前在TestRail中创建 def tearDown(self): # 判断当前用例的执行状态 status_id = 1 # 默认成功(TestRail中成功状态的ID,需根据你的配置调整) # 检查用例是否失败或报错 for error in self._outcome.errors: if error[0] is not None: # 失败状态ID,对应TestRail中的"Failed" status_id = 5 break # 获取当前用例绑定的TestRail Case ID case_id = getattr(self._testMethod, "case_id", None) if case_id: # 上报结果到TestRail self.testrail_api.results.add_result_for_case( run_id=self.test_run_id, case_id=case_id, status_id=status_id )
3. 编写业务测试用例
只需继承基类,用装饰器标记Case ID,正常编写断言逻辑即可:
class IOSAutomationTests(TestRailBaseTestCase): @testrail_case(123) def test_a(self): """测试A:验证数值不等""" self.assertNotEqual(1, 2) @testrail_case(124) def test_b(self): """测试B:验证数值相等""" self.assertEqual(1, 1)
方案二:自定义TestResult类实现
通过重写Unittest的TestResult类,在成功、失败、错误的回调方法中统一处理上报:
import unittest from testrail_api import TestRailAPI class TestRailTestResult(unittest.TextTestResult): def __init__(self, stream, descriptions, verbosity): super().__init__(stream, descriptions, verbosity) # 初始化TestRail API self.testrail_api = TestRailAPI( url="https://你的TestRail地址/", email="你的账号邮箱", password="你的API密钥或密码" ) self.test_run_id = 123 def addSuccess(self, test): super().addSuccess(test) case_id = getattr(test._testMethod, "case_id", None) if case_id: self.testrail_api.results.add_result_for_case( run_id=self.test_run_id, case_id=case_id, status_id=1 # 成功状态ID ) def addFailure(self, test, err): super().addFailure(test, err) case_id = getattr(test._testMethod, "case_id", None) if case_id: self.testrail_api.results.add_result_for_case( run_id=self.test_run_id, case_id=case_id, status_id=5 # 失败状态ID ) def addError(self, test, err): super().addError(test, err) case_id = getattr(test._testMethod, "case_id", None) if case_id: self.testrail_api.results.add_result_for_case( run_id=self.test_run_id, case_id=case_id, status_id=3 # 错误状态ID,根据你的TestRail配置调整 )
运行测试时指定自定义TestResult
if __name__ == "__main__": test_suite = unittest.TestLoader().loadTestsFromTestCase(IOSAutomationTests) runner = unittest.TextTestRunner(resultclass=TestRailTestResult) runner.run(test_suite)
注意事项
- 先安装TestRail Python客户端:
pip install testrail-api - TestRail的
status_id需根据你的项目配置调整(可在TestRail的Administration > Statuses中查看对应ID) - 若不想用装饰器,也可从用例的docstring中提取Case ID(比如用正则匹配
case_id:xxx格式)
内容的提问来源于stack exchange,提问作者agaspb1
相关产品推荐
相关产品推荐

