A good part of a developer's work is to test and debug code. Automated tests are an inevitable tool to build and maintain robust software. Testing in odoo allows test automation aggregation of tests into collections just like normal unit tests. This blog explains how to add tests for python code in our addon modules in Odoo to make them more robust.
Python tests are added in addon modules as follows:
1. Creating the Python files
In order to add unit tests to our module, first of all, we have to create a subdirectory ”tests”.so all the “.py” files from this subdirectory will be automatically running while the test runs. The “.py” files names inside this directory should be started with ‘test_’ otherwise it will not execute the tests.
For example, in the custom module, I have created the test folder, in which test_module.py file is created.
After that we have to import this test_custom.py file in the __init__.py as follows:
from. import test_module
Odoo provides a number of utilities and helpers to test the odoo modules.
2. Creating the Classes
For testing addon modules odoo provides a few classes. We can use the TransactionCase (separate transaction for each test) and also SingleTransactionCase(runs all the tests in a single transaction). This can be useful when you want the final state of each test to be the initial state for the following test.
The setUp() method is where we prepare data and variables to be used. We will usually store them as class attributes so that they are available to be used in the test methods.
Odoo uses a unittest extension library, unittest2.
3. Writing Test Cases
Now let’s expand the test for the method test_data() as shown above. The simplest tests we can write, run some code from the tested object, query for a result to verify, and then use an assert to compare with an expected result.
Here we are going to create two locations in stock. location and testing whether the usage of both the locations is the same.
Assert functions are used to check whether the operation’s output is True or False. We can also specify the error message in case our test fails in the message argument msg in the assert functions. In the above example assertEqual() test that arg1 and arg2 are equal.If the values of arg1 and agr2 are not equal the test will fail.
Sometimes we need our tests to check if an exception was generated. A common case is when testing if some validations are being done properly. To check whether an exception is raised, we place the corresponding code inside with self.assertRaises() block.
For that, we need to import the Warning exception at the top of the file.
from odoo.exceptions import Warning
And add to the test class a method with another test case.
5. Running Tests
You can use the following command to run your test from your local odoo instances.
./odoo-bin -i automated_test_demo --test-enable -c /etc/odoo-server.conf
In order to run a test, you have to use the ‘-test-enable’ parameter and the ‘-i’ parameter to show which modules you want to test.
Commonly Used Assert Functions for Testing:
Assert functions are used to check whether the operation’s output is True or False. We can also specify the error message in case our test fails in the message argument msg in the assert functions. Now let’s see some of the most commonly used assert methods and what's all their purpose.
1. assertEqual(arg1, arg2, msg=None)
This one is the most widely used among assert methods. It checks whether the first and second arguments are equal and if they are not equal the test will fail. It is used to test whether the argument arg1 and argument agr2 are equal. If they are not equal the test will fail.
2. assertNotEqual(arg1, arg2, msg = None)
This one is just opposite that of assertEqual as explained above. In this, the test fails if arg1 and arg2 are of equal.
3. assertTrue(expr, msg = None)
It tests whether the given expression is true. If the given expression is false then the test will fail.
4. assertFalse(expr, msg = None)
It tests whether the given expression is false, otherwise the test will fail.
5. assertIsNone(expr, msg = None) and assertIsNotNone(expr, msg = None)
The assertIsNone() tests that expr is None. If the expression is not None then the test will fail. Similarly, the assertIsNotNone() tests that that expr is Not None. If the expression is None then the test will fail in this case.
6. assertIsInstance(obj, cls, msg = None)
It will test whether the given object obj is an instance of the class cls we have given.
7. assertNotIsInstance(obj, cls, msg = None)
It will help us to test whether the object (obj) is not an instance of the class cls.
8. assertIn(arg1, arg2, msg = None)
It will test whether the given argument arg1 is in arg2.
9. assertNotIn(arg1, arg2, msg = None)
It will test whether the given argument arg1 is not in arg2.
10. assertIs(arg1, arg2, msg = None) and assertIsNot(arg1, arg2, msg = None)
assertIs() tests that arg1 and arg2 evaluate to the same object.The assertIsNot() tests that arg1 and arg2 don’t evaluate to the same object.