Testing is a critical component of software development that ensures your Odoo modules function as intended, meet business requirements, and maintain stability across updates. With Odoo 18's enhanced testing framework, developers can create more robust and reliable applications. This guide will walk you through the process of writing effective test cases for your Odoo 18 modules.
Why Testing Matters in Odoo Development
Before diving into implementation, let's understand why thorough testing is essential:
- Quality Assurance: Verifies that your module behaves as expected
- Regression Prevention: Catches bugs before they reach production
- Documentation: Serves as living documentation of your module's functionality
- Confidence in Refactoring: Allows safe modification of existing code
- Compliance: Ensures business rules are consistently enforced
Setting Up Your Testing Environment in Odoo 18
Odoo 18 maintains Python's unit test framework while introducing some optimizations. Here's how to structure your test files:
- Create a tests directory in your module folder
- Name test files with the prefix test_ (e.g., test_invoicing.py)
- Import test files in tests/__init__.py
- Import the tests package in your module's __init__.py
Example structure:
your_module/
+-- __init__.py
+-- models/
+-- tests/
+-- __init__.py
+-- test_core.py
+-- test_advanced.py
Writing Your First Test Case
Odoo 18 provides several test case classes. The most commonly used is TransactionCase:
from odoo.tests.common import TransactionCase
class TestPartnerExtension(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
# Create test data available to all test methods
cls.partner = cls.env['res.partner'].create({
'name': 'Test Partner',
'email': 'partner@test.com',
'is_company': True
})
def test_partner_creation(self):
"""Test that partner records are created correctly"""
self.assertEqual(self.partner.name, 'Test Partner')
self.assertTrue(self.partner.is_company)
def test_email_validation(self):
"""Test email validation logic"""
with self.assertRaises(ValueError):
self.partner.write({'email': 'invalid-email'})
Basic Comparisons:
- assertEqual(a, b): Verify a equals b
- assertNotEqual(a, b): Verify a doesn't equal b
- assertTrue(x): Verify x is True
- assertFalse(x): Verify x is False
Object Comparisons:
- assertIs(a, b): Verify a is the same object as b
- assertIsNot(a, b): Verify a is not the same object as b
- assertIsNone(x): Verify x is None
- assertIsNotNone(x): Verify x is not None
Collection Checks:
- assertIn(a, b): Verify a is in b
- assertNotIn(a, b): Verify a is not in b
- assertCountEqual(a, b): Verify a and b have same elements
Exception Handling:
- assertRaises(Error, func, *args): Verify function raises expected error
Advanced Testing Techniques
Testing UI Components with HttpCase
Odoo 18's HttpCase allows testing web controllers and UI components:
from odoo.tests.common import HttpCase
class TestWebsiteController(HttpCase):
def test_website_form(self):
"""Test website form submission"""
self.start_tour('/contactus', 'website_contact_form_test')
record = self.env['website.contact'].search([], limit=1)
self.assertTrue(record, "Form submission failed to create record")
Testing Security Rules
Verify your access controls work as intended:
def test_access_rights(self):
"""Test user access restrictions"""
demo_user = self.env.ref('base.user_demo')
with self.assertRaises(AccessError):
self.partner.with_user(demo_user).write({
'vat': 'BE0123456789'
})
Testing Scheduled Actions
Odoo 18 makes it easier to test automated processes:
def test_scheduled_action(self):
"""Test automated invoice generation"""
cron = self.env.ref('your_module.generate_invoices_cron')
cron.method_direct_trigger()
invoices = self.env['account.move'].search([
('invoice_origin', '=', 'Scheduled Job')
])
self.assertGreaterEqual(len(invoices), 1)
Performance Testing
Odoo 18 introduces better performance testing tools:
def test_partner_creation_performance(self):
"""Test bulk partner creation performance"""
with self.assertQueryCount(threshold=50):
partners = self.env['res.partner'].create([
{'name': f'Partner {i}'} for i in range(100)
])
self.assertEqual(len(partners), 100)
Running Tests in Odoo 18
Execute your tests with:
./odoo-bin -c /etc/odoo/odoo.conf -d test_db -i your_module --test-enable
For specific test tags:
./odoo-bin -c odoo.conf -d test_db --test-tags=slow,security
Writing comprehensive test cases in Odoo 18 ensures your custom modules remain stable, performant, and maintainable as your business grows. By leveraging Odoo's testing framework and following the practices outlined above, you can significantly reduce bugs and deployment risks while improving code quality.
To read more about How to Write Test Case in the Odoo 17 ERP, refer to our blog How to Write Test Case in the Odoo 17 ERP.