
关于
使用 TransactionCase、HttpCase 和浏览器 Tour 测试编写和运行 Odoo 自动化测试。涵盖测试数据设置、Mock 和 CI 集成。
name: odoo-automated-tests description: "编写和运行 Odoo 自动化测试,包括 TransactionCase、HttpCase 和浏览器 Tour 测试。涵盖测试数据设置、Mock 和 CI 集成。" risk: safe source: "self"
Odoo 自动化测试
概述
Odoo 内置了基于 Python unittest 的测试框架。本技能帮助你编写 TransactionCase 单元测试、HttpCase 集成测试和 JavaScript Tour 测试,还涵盖在 CI 流水线中运行测试的方法。
何时使用本技能
- 为自定义模型的业务逻辑编写单元测试。
- 创建 HTTP 测试以验证控制器端点。
- 调试 CI 流水线中的测试失败。
- 使用
--test-enable设置自动化测试执行。
工作原理
- 激活:提及
@odoo-automated-tests并描述要测试的功能。 - 生成:获取包含 setup、teardown 和断言的完整测试类代码。
- 运行:获取执行测试的精确
odooCLI 命令。
示例
示例 1:TransactionCase 单元测试(Odoo 15+ 模式)
# tests/test_hospital_patient.py
from odoo.tests.common import TransactionCase
from odoo.tests import tagged
from odoo.exceptions import ValidationError
@tagged('post_install', '-at_install')
class TestHospitalPatient(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.Patient = cls.env['hospital.patient']
cls.doctor = cls.env['res.users'].browse(cls.env.uid)
def test_create_patient(self):
patient = self.Patient.create({
'name': 'John Doe',
'doctor_id': self.doctor.id,
})
self.assertEqual(patient.state, 'draft')
self.assertEqual(patient.name, 'John Doe')
def test_confirm_patient(self):
patient = self.Patient.create({'name': 'Jane Smith'})
patient.action_confirm()
self.assertEqual(patient.state, 'confirmed')
def test_empty_name_raises_error(self):
with self.assertRaises(ValidationError):
self.Patient.create({'name': ''})
def test_access_denied_for_other_user(self):
other_user = self.env.ref('base.user_demo')
with self.assertRaises(Exception):
self.Patient.with_user(other_user).create({'name': 'Test'})
setUpClassvssetUp: 使用setUpClass(Odoo 15+)来共享测试数据。它每个类只运行一次,比每个测试方法都重新初始化的setUp快得多。
示例 2:通过 CLI 运行测试
./odoo-bin --test-enable --stop-after-init -d my_database -u hospital_management
./odoo-bin --test-enable --stop-after-init -d my_database \
--test-tags hospital_management
./odoo-bin --test-enable --stop-after-init -d my_database \
--test-tags /hospital_management:TestHospitalPatient
示例 3:HttpCase 控制器测试
from odoo.tests.common import HttpCase
from odoo.tests import tagged
@tagged('post_install', '-at_install')
class TestPatientController(HttpCase):
def test_patient_page_authenticated(self):
self.authenticate(self.env.user.login, self.env.user.login)
resp = self.url_open('/hospital/patients')
self.assertEqual(resp.status_code, 200)
def test_patient_page_redirects_unauthenticated(self):
resp = self.url_open('/hospital/patients', allow_redirects=False)
self.assertIn(resp.status_code, [301, 302, 403])
最佳实践
- 应该:使用
setUpClass()配合cls.env而不是setUp()—— 对于大型测试套件速度提升显著。 - 应该:使用
@tagged('post_install', '-at_install')在所有模块安装后运行测试。 - 应该:测试正常路径和错误条件(
ValidationError、AccessError、UserError)。 - 应该:使用
self.with_user(user)测试访问控制,而不是调用sudo()。 - 避免:使用生产数据库进行测试 —— 始终使用专用测试数据库。
- 避免:依赖测试执行顺序 —— 每个
TransactionCase测试都在隔离环境中回滚。 - 避免:在
HttpCase.authenticate()中硬编码密码 —— 使用self.env.user.login或 fixture 用户。
局限性
- JavaScript Tour 测试需要运行中的浏览器(通过
phantomjs或Chrome headless)和运行中的 Odoo 服务器 —— 此处不深入介绍。 HttpCase测试比TransactionCase慢得多 —— 仅用于控制器/路由验证。- 不涵盖外部服务 Mock(例如在测试中 Mock SMTP 服务器或支付网关)。
- 测试隔离在事务级别,而非数据库级别。
兼容工具
Claude CodeCursor
标签
测试

