如何在GitHub推送时自动运行Odoo单元测试及API执行问题排查
问题1:Odoo.sh推送代码时自动运行特定模块测试的配置方法
要实现Odoo.sh推送代码时自动运行指定模块的测试,可通过以下方式配置:
1. 配置.odoo-ci.yml文件
在仓库根目录创建该文件,明确指定要运行的测试模块,示例配置如下:
test: modules: # 直接指定目标模块 - your_custom_sale_module # 或指定模块+测试标签,仅运行带对应标签的测试用例 - name: your_custom_sale_module tags: ['sale_uat', 'post_install']
Odoo.sh在代码推送时会读取该配置,自动执行指定模块的测试任务。
2. 为测试方法添加标签
在测试类的方法上添加@tagged装饰器,标记测试类型,配合CI配置精准触发:
from odoo.tests import tagged, TransactionCase @tagged('sale_uat', 'post_install') class TestSaleProject(TransactionCase): def test_sale_order_with_project_task(self): # 测试逻辑代码 pass
注:post_install标签表示测试需在模块安装后运行,适合依赖已安装模块数据的场景。
3. 开启分支自动测试
确保目标分支在Odoo.sh后台开启了"自动测试"选项,推送代码后系统会自动执行配置的测试任务。
问题2:API调用测试第二次卡住的修复方案
你直接实例化测试类并手动调用setUpClass的方式,不符合Odoo测试框架的生命周期管理逻辑,会导致测试环境残留(如未回滚的数据库事务、已创建的测试记录),第二次调用时出现卡住问题。修复方案如下:
正确的测试执行方式:使用unittest测试运行器
通过Python标准库的unittest.TestLoader和TestRunner加载并运行测试,Odoo测试框架会自动处理事务回滚、环境清理等流程。修改后的控制器代码示例:
import unittest import json from odoo import fields, _ from odoo.http import Controller, Response, route from odoo.logger import logging from your_module.tests.test_sale_project import TestSaleProject _logger = logging.getLogger(__name__) _webhook_sale = '/webhook/execute_sale_uat' class TestExecutionController(Controller): @route(_webhook_sale, auth='none', type='http', methods=['POST'], csrf=False) def execute_sale_order_uat(self, **post): _logger.info("begin execute_sale_order_uat") try: self.authenticate_token_and_environment(scope='sale_access') _logger.info("Authenticated successfully") # 加载测试类为测试套件 loader = unittest.TestLoader() test_suite = loader.loadTestsFromTestCase(TestSaleProject) # 运行测试(将输出重定向到/dev/null避免日志冗余,可按需调整) runner = unittest.TextTestRunner(stream=open('/dev/null', 'w'), verbosity=2) test_result = runner.run(test_suite) # 根据测试结果返回响应 if test_result.wasSuccessful(): response_data = { 'code' : 200, 'result' : 'success', 'message': _(f"Sale UATs executed successfully on {fields.Datetime.now()}"), } return Response(json.dumps(response_data), status=200, content_type='application/json') else: # 收集失败/错误信息 error_details = [] for test_case, err in test_result.failures + test_result.errors: error_details.append(f"{test_case.id()}: {err}") response_data = { 'code' : 500, 'result' : 'failed', 'message': _("部分测试执行失败"), 'errors' : error_details } return Response(json.dumps(response_data), status=500, content_type='application/json') except Exception as e: _logger.error(f"执行UAT测试出错: {str(e)}", exc_info=True) response_data = { 'code' : 500, 'result' : 'error', 'message': _(f"测试执行异常: {str(e)}") } return Response(json.dumps(response_data), status=500, content_type='application/json')
关键注意事项
- 测试类必须继承自
odoo.tests.common.TransactionCase(或其子类),确保每个测试方法在独立事务中运行,执行后自动回滚,避免数据残留。 - 不要手动调用
setUpClass、tearDownClass等方法,测试运行器会自动按生命周期执行这些方法。 - 若需在测试中使用特定环境(如特定公司、用户),可在测试类的
setUp方法中初始化,而非控制器中处理。
内容的提问来源于stack exchange,提问作者Victor Macario
相关产品推荐
相关产品推荐

