Odoo : Overriding native tests
Based on information founded here - Adapted to fit in one file, works in Odoo 15
Inheriting the Class
Identify the class with tests to override and declare a class inheriting it, in the tests folder of your module
# file : tests/test_to_override.py
# -*- coding: utf-8 -*-
from odoo.addons.module.tests.test_to_override import TestToOverride
from odoo.tests import tagged
@tagged('whatever')
class TestToOverrideInherited(TestToOverride):
def test_function_overriding(self):
#testing
Disable native tests
Even with this system, native tests will still be ran. To disable them, you need to void the functions :
import unittest
@tagged('whatever')
class TestToOverrideInherited(TestToOverride):
# Define an easy way to void
@unittest.skip('Overriden test')
def void(self: TestToOverride):
pass
# disable tests - do not disable a test without writing another one, testing is important!
TestToOverride.test_function_to_override = void
Javascript tests
Tours
Tours are tests involving Python + JS, supposed to simulate a whole workflow. The JavaScript part is called from the Python tests with the name registered in the JS registry.
To override these JS tests, find the file containing the test, and create a file with a similar name and path in your module static directory.
Include this new file through your module's manifest :
# [...]
'assets': {
'web.assets_tests': [
'{module}static/path/to/test_file.js',
]}
# [...]
Then, in the file, target the test using registry and patch it. Inside the patch, you can access the original test values using super
/** @odoo-module **/
import { registry } from "@web/core/registry";
import { patch } from "@web/core/utils/patch";
// an example of test to overwrite
import '@stock_barcode/../tests/tours/tour_test_barcode_flows_picking';
patch(registry.category("web_tour.tours").get('test_picking_type_mandatory_scan_complete_flux_receipt'), {
steps() {
// We want to update each trigger using a product without barcode by one using auto generated barcode
const originalSteps = super.steps();
originalSteps.forEach(function(step, index) {
originalSteps[index].trigger = step.trigger.replace(':not\(\[data-barcode]\)', '[data-barcode^="PACBC"]')
});
// You can also add/remove steps using splice
originalSteps.splice(5, 1, {
trigger: '.o_scan_message.o_scan_product',
run: function () {
const [ lineProductNoBarcode, lineProduct1 ] = helper.getLines();
helper.assert(
lineProduct1.querySelector('.btn.o_edit').disabled, true,
"Edit button should be disabled");
);
},
});
const barcode = lineProductNoBarcode.getAttribute('data-barcode')
const stepIndex = originalSteps.findIndex((step) => step.trigger === ".o_barcode_line .btn.o_add_remaining_quantity");
originalSteps.splice(stepIndex, 0, {
trigger: '.o_barcode_client_action',
run: 'scan '+barcode,
});
// Don't forget to return the overwritten values
return originalSteps;
}
});