Testing in Odoo: Knowledge and Best Practices

In previous blog posts, we’ve talked about the importance of implementing tests in our Odoo developments to avoid unwanted situations. In this article, we’ll focus on explaining how tests should be implemented in Odoo and best practices to make them robust and sustainable over time.

Different types of tests in Odoo

To begin with, it’s important to highlight that there are three different types of tests that can be implemented in Odoo, each with a distinct purpose. When we talk about testing in Odoo, most commonly we refer to Python Unit Tests, but there are also JavaScript Unit Tests and Tour Tests. Let’s take a look at each one.

Python Unit Test

Unit tests in Odoo are implemented using Python’s unittest library. This type of test is used to verify backend or server-side functionality. To properly structure tests in your module, consider the following:

  • Inside your module folder, create a subfolder named tests.
  • This folder must include an __init__.py file where you import the test files. This file should also be imported from the module’s main __init__.py.
  • It's recommended that each test file starts with test_ followed by the name of the model being tested.
  • Tests are created using test classes, which can be of different types (TransactionCase, SingleTransactionCase, HttpCase) depending on the nature of the test.
  • Initially, within your class, a setUpClass method should be defined to set up shared data across tests. Keep in mind that if you modify these values in one method, the changes will persist for subsequent tests.
  • Then, define methods that execute parts of your code and use assertions to check that the actual results match expected values. Test methods must start with test_.

What to consider when implementing Python Unit Tests

The recommended approach is to ensure each test validates a specific and atomic functionality, starting with the base case and increasing complexity gradually.​

To make it easier to understand the test’s purpose in the future, it’s a good idea to include a description at the beginning of the test explaining the use case, expected inputs, and/or outputs. 

Additionally, to make tests more sustainable, you can implement auxiliary methods within the test class to execute supporting code. This is especially useful when this code is shared among tests or not intrinsic to the specific functionality being tested.

A best practice is to create one class per test file, and one test file per model you want to test in your module.

Using tags is an interesting option to organize and selectively execute tests (e.g. post-install, at-install, standard).​

There are advanced tools documented in Odoo that are worth mentioning, such as Form (to simulate form creation and saving, like in the UI), M2MProxy, or O2MProxy.

JS Unit Test

JavaScript tests in Odoo run in the browser and are recommended when dealing with complex frontend logic. These are implemented using QUnit or Hoot (depending on the Odoo version), which provide a web interface for running the tests. Keep in mind the following when writing JS tests:

  • Test files should be placed in some_addon/static/tests/.
  • Write the minimum amount of code necessary for the test to run correctly.
  • It’s better to break large tests into smaller ones for easier understanding and maintenance.
  • Always clean up after each test, e.g. by destroying created widgets.
  • It can be difficult to cover all code, but having some tests already helps catch bugs before production.
  • Include both positive and negative assertions in the same test to avoid them becoming useless if UI elements (like CSS classes) change.
  • For debugging, you can use QUnit.only(…) to run a single test temporarily and enable debug mode in helper functions.

Tour Test or Integration Test

Tour tests are the least known and used, but they are very useful to check complete flows and ensure the correct implementation of a defined use case in the system. These tests combine backend and frontend checks, validating the interaction between both. To implement them:

  • Place them in my_addon/static/tests/tours and add them to the assets in __manifest__.py.
  • They are essential when handling complex JavaScript logic that interacts with the backend.
  • They can be run and debugged in the browser, whether locally or in test/production environments, making them a powerful tool to debug errors in the live system.
  • They support taking PNG screenshots to visually analyze the state of the application.
Extra tip: Query Counts Assertion

To ensure test efficiency, it’s recommended to use Query Counts Assertion. It helps identify whether the code is executing more SQL queries than necessary, helping to optimize performance.

Best practices for implementing tests

To finish, we’d like to highlight a few best practices mentioned throughout the article. These will make implementing and maintaining tests less of a burden and help achieve the main goal: ensuring the reliability and maintainability of our software.

  • Explain the purpose of the test at the beginning. For example:
	​"""When we create a vacation request and set more days than we have 
​ left, a rejection message should be shown to the user."""
  • Keep tests as atomic as possible, gradually adding complexity through different cases.
  • Centralize setup logic in setUpClass() and reuse helper methods, so test methods can focus solely on the system flow and assertions, making them cleaner and easier to follow.
  • When inheriting classes in your module, it’s advisable to also inherit their test classes (if available) to reuse the existing setup and shared test data.

With these practices, you’ll be able to handle test implementation without any issues and ensure robust and sustainable development in Odoo. If you want to dive deeper into Odoo testing, check out the official documentation, the YouTube channel of the Spanish Odoo Association (AEOdoo), or other articles on the Dixmit blog.

OWL: Why Should We Learn It as Odoo Developers?