Skip to main content

odoo-testing

Odoo 18 test patterns — TransactionCase, HttpCase, test data, assertions

Informações da origem

Repositório
Insightpulseai/odoo
Última atividade na origem
9 de abril de 2026 às 11:24
Idioma detectado do SKILL.md
inglês
Estrelas
6
Forks
2

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
odoo-testing
description
Odoo 18 test patterns — TransactionCase, HttpCase, test data, assertions
category
qa
priority
high
# Odoo 18 Testing Patterns ## Test Classes | Class | Use case | Isolation | |-------|----------|-----------| | `TransactionCase` | Standard model/logic tests | DB rollback after each test method | | `HttpCase` | Controller routes, full HTTP stack | Separate transaction per request | | `tagged()` | Control when tests run | Decorator on class or method | `SavepointCase` is **deprecated in Odoo 18** — use `TransactionCase` instead. ```python # Correct from odoo.tests import TransactionCase, tagged @tagged('post_install', '-at_install') class TestSaleOrder(TransactionCase): @classmethod def setUpClass(cls): super().setUpClass() # NEVER skip this cls.partner = cls.env['res.partner'].create({'name': 'Test'}) ``` ## Test Discovery - Test files live in `tests/` inside the module - Every test file must be imported in `tests/__init__.py` - Class names must start with `Test` ```python # tests/__init__.py from . import test_sale_logic from . import test_invoice_flow ``` ## Test Data Create data in `setUpClass` via `cls.env`. Reference XML demo data with `cls.env.ref()`. ```python # Correct — setUpClass with cls.env @classmethod def setUpClass(cls): super().setUpClass() cls.product = cls.env['product.product'].create({ 'name': 'Widget', 'list_price': 100.0, }) cls.currency = cls.env.ref('base.USD') # Wrong — hardcoded database IDs def test_bad(self): partner = self.env['res.partner'].browse(42) # NEVER do this ``` ## Common Assertions ```python def test_order_total(self): order = self.env['sale.order'].create({...}) self.assertEqual(order.amount_total, 100.0) # Bulk field assertion across recordset self.assertRecordValues(order.order_line, [ {'product_id': self.product.id, 'price_unit': 100.0}, ]) # Exception testing with self.assertRaises(ValidationError): order.write({'date_order': False}) # Form testing (simulates UI onchanges) from odoo.tests.common import Form def test_form_onchange(self): with Form(self.env['sale.order']) as f: f.partner_id = self.partner self.assertTrue(f.pricelist_id) ``` ## Mocking ```python from unittest.mock import patch from freezegun import freeze_time @tagged('post_install', '-at_install') class TestMailSend(TransactionCase): @classmethod def setUpClass(cls): super().setUpClass() cls.env = cls.env(context={'testing': True}) # Mock outbound mail @patch('odoo.addons.mail.models.mail_mail.MailMail.send') def test_no_real_email(self, mock_send): self.env['mail.mail'].create({...}).send() mock_send.assert_called_once() # Freeze time for date-sensitive logic @freeze_time('2026-01-15') def test_deadline(self): self.assertEqual(fields.Date.today(), date(2026, 1, 15)) ``` ## Running Tests ```bash # Run tests for a single module (disposable DB) odoo -d test_mymodule -i ipai_finance_ppm --test-enable --stop-after-init # Run only specific tagged tests odoo -d test_mymodule -i ipai_finance_ppm --test-tags=post_install --stop-after-init # Run a single test class odoo -d test_mymodule -i ipai_finance_ppm --test-tags=.TestSaleOrder --stop-after-init ``` ## What NOT To Do | Anti-pattern | Why | Do instead | |-------------|-----|------------| | Test on `odoo_dev` or `odoo_prod` | Pollutes real data | Use `test_<module>` DB | | Skip `super().setUpClass()` | Breaks env setup, causes cryptic errors | Always call super first | | Hardcode record IDs (`browse(42)`) | IDs differ across databases | Use `create()` or `env.ref()` | | Test OCA module internals | Not your code to validate | Test your `ipai_*` overrides only | | Import `SavepointCase` | Deprecated in 19 | Use `TransactionCase` | | Run tests on host machine | Missing deps, wrong Python | Run inside devcontainer |
Ver no GitHub