diff --git a/content/developer/reference/backend/testing.rst b/content/developer/reference/backend/testing.rst
index d3458dc3d..10bf74372 100644
--- a/content/developer/reference/backend/testing.rst
+++ b/content/developer/reference/backend/testing.rst
@@ -281,252 +281,17 @@ Testing JS code
Testing a complex system is an important safeguard to prevent regressions and to
guarantee that some basic functionality still works. Since Odoo has a non trivial
-codebase in Javascript, it is necessary to test it. In this section, we will
-discuss the practice of testing JS code in isolation: these tests stay in the
-browser, and are not supposed to reach the server.
+codebase in Javascript, it is necessary to test it.
-.. _reference/testing/qunit:
+See the :doc:`Unit testing <../frontend/unit_testing>` to learn about the
+various aspect of the front-end testing framework, or jump directly to one of the
+sub-sections:
-Qunit test suite
-----------------
+- :doc:`Hoot <../frontend/unit_testing/hoot>`
-The Odoo framework uses the QUnit_ library testing framework as a test runner.
-QUnit defines the concepts of *tests* and *modules* (a set of related tests),
-and gives us a web based interface to execute the tests.
+- :doc:`Web test helpers <../frontend/unit_testing/web_helpers>`
-For example, here is what a pyUtils test could look like:
-
-.. code-block:: javascript
-
- QUnit.module('py_utils');
-
- QUnit.test('simple arithmetic', function (assert) {
- assert.expect(2);
-
- var result = pyUtils.py_eval("1 + 2");
- assert.strictEqual(result, 3, "should properly evaluate sum");
- result = pyUtils.py_eval("42 % 5");
- assert.strictEqual(result, 2, "should properly evaluate modulo operator");
- });
-
-The main way to run the test suite is to have a running Odoo server, then
-navigate a web browser to ``/web/tests``. The test suite will then be executed
-by the web browser Javascript engine.
-
-.. image:: testing/tests.png
- :align: center
-
-The web UI has many useful features: it can run only some submodules, or
-filter tests that match a string. It can show every assertions, failed or passed,
-rerun specific tests, ...
-
-.. warning::
-
- While the test suite is running, make sure that:
-
- - your browser window is focused,
- - it is not zoomed in/out. It needs to have exactly 100% zoom level.
-
- If this is not the case, some tests will fail, without a proper explanation.
-
-Testing Infrastructure
-----------------------
-
-Here is a high level overview of the most important parts of the testing
-infrastructure:
-
-- there is an asset bundle named `web.qunit_suite`_. This bundle contains
- the main code (assets common + assets backend), some libraries, the QUnit test
- runner and the test bundles listed below.
-
-- a bundle named `web.tests_assets`_ includes most of the assets and utils required
- by the test suite: custom QUnit asserts, test helpers, lazy loaded assets, etc.
-
-- another asset bundle, `web.qunit_suite_tests`_, contains all the test scripts.
- This is typically where the test files are added to the suite.
-
-- there is a `controller`_ in web, mapped to the route */web/tests*. This controller
- simply renders the *web.qunit_suite* template.
-
-- to execute the tests, one can simply point its browser to the route */web/tests*.
- In that case, the browser will download all assets, and QUnit will take over.
-
-- there is some code in `qunit_config.js`_ which logs in the console some
- information when a test passes or fails.
-
-- we want the runbot to also run these tests, so there is a test (in `test_js.py`_)
- which simply spawns a browser and points it to the *web/tests* url. Note that
- the browser_js method spawns a Chrome headless instance.
-
-
-Modularity and testing
-----------------------
-
-With the way Odoo is designed, any addon can modify the behaviour of other parts
-of the system. For example, the *voip* addon can modify the *FieldPhone* widget
-to use extra features. This is not really good from the perspective of the
-testing system, since this means that a test in the addon web will fail whenever
-the voip addon is installed (note that the runbot runs the tests with all addons
-installed).
-
-At the same time, our testing system is good, because it can detect whenever
-another module breaks some core functionality. There is no complete solution to
-this issue. For now, we solve this on a case by case basis.
-
-Usually, it is not a good idea to modify some other behaviour. For our voip
-example, it is certainly cleaner to add a new *FieldVOIPPhone* widget and
-modify the few views that needs it. This way, the *FieldPhone* widget is not
-impacted, and both can be tested.
-
-Adding a new test case
-----------------------
-
-Let us assume that we are maintaining an addon *my_addon*, and that we
-want to add a test for some javascript code (for example, some utility function
-myFunction, located in *my_addon.utils*). The process to add a new test case is
-the following:
-
-1. create a new file *my_addon/static/tests/utils_tests.js*. This file contains the basic code to
- add a QUnit module *my_addon > utils*.
-
- .. code-block:: javascript
-
- odoo.define('my_addon.utils_tests', function (require) {
- "use strict";
-
- var utils = require('my_addon.utils');
-
- QUnit.module('my_addon', {}, function () {
-
- QUnit.module('utils');
-
- });
- });
-
-
-2. In *my_addon/assets.xml*, add the file to the main test assets:
-
- .. code-block:: xml
-
-
-
-
-
-
-
-
-
-
-3. Restart the server and update *my_addon*, or do it from the interface (to
- make sure the new test file is loaded)
-
-4. Add a test case after the definition of the *utils* sub test suite:
-
- .. code-block:: javascript
-
- QUnit.test("some test case that we want to test", function (assert) {
- assert.expect(1);
-
- var result = utils.myFunction(someArgument);
- assert.strictEqual(result, expectedResult);
- });
-
-5. Visit */web/tests/* to make sure the test is executed
-
-Helper functions and specialized assertions
--------------------------------------------
-
-Without help, it is quite difficult to test some parts of Odoo. In particular,
-views are tricky, because they communicate with the server and may perform many
-rpcs, which needs to be mocked. This is why we developed some specialized
-helper functions, located in `test_utils.js`_.
-
-- Mock test functions: these functions help setting up a test environment. The
- most important use case is mocking the answers given by the Odoo server. These
- functions use a `mock server`_. This is a javascript class that simulates
- answers to the most common model methods: read, search_read, nameget, ...
-
-- DOM helpers: useful to simulate events/actions on some specific target. For
- example, testUtils.dom.click performs a click on a target. Note that it is
- safer than doing it manually, because it also checks that the target exists,
- and is visible.
-
-- create helpers: they are probably the most important functions exported by
- `test_utils.js`_. These helpers are useful to create a widget, with a mock
- environment, and a lot of small detail to simulate as much as possible the
- real conditions. The most important is certainly `createView`_.
-
-- `qunit assertions`_: QUnit can be extended with specialized assertions. For
- Odoo, we frequently test some DOM properties. This is why we made some
- assertions to help with that. For example, the *containsOnce* assertion takes
- a widget/jQuery/HtmlElement and a selector, then checks if the target contains
- exactly one match for the css selector.
-
-For example, with these helpers, here is what a simple form test could look like:
-
-.. code-block:: javascript
-
- QUnit.test('simple group rendering', function (assert) {
- assert.expect(1);
-
- var form = testUtils.createView({
- View: FormView,
- model: 'partner',
- data: this.data,
- arch: '
',
- res_id: 1,
- });
-
- assert.containsOnce(form, 'table.o_inner_group');
-
- form.destroy();
- });
-
-Notice the use of the testUtils.createView helper and of the containsOnce
-assertion. Also, the form controller was properly destroyed at the end of
-the test.
-
-Best Practices
---------------
-
-In no particular order:
-
-- all test files should be added in *some_addon/static/tests/*
-- for bug fixes, make sure that the test fails without the bug fix, and passes
- with it. This ensures that it actually works.
-- try to have the minimal amount of code necessary for the test to work.
-- usually, two small tests are better than one large test. A smaller test is
- easier to understand and to fix.
-- always cleanup after a test. For example, if your test instantiates a widget,
- it should destroy it at the end.
-- no need to have full and complete code coverage. But adding a few tests helps
- a lot: it makes sure that your code is not completely broken, and whenever a
- bug is fixed, it is really much easier to add a test to an existing test suite.
-- if you want to check some negative assertion (for example, that a HtmlElement
- does not have a specific css class), then try to add the positive assertion in
- the same test (for example, by doing an action that changes the state). This
- will help avoid the test to become dead in the future (for example, if the css
- class is changed).
-
-Tips
-----
-
-- running only one test: you can (temporarily!) change the *QUnit.test(...)*
- definition into *QUnit.only(...)*. This is useful to make sure that QUnit
- only runs this specific test.
-- debug flag: most create utility functions have a debug mode (activated by the
- debug: true parameter). In that case, the target widget will be put in the DOM
- instead of the hidden qunit specific fixture, and more information will be
- logged. For example, all mocked network communications will be available in the
- console.
-- when working on a failing test, it is common to add the debug flag, then
- comment the end of the test (in particular, the destroy call). With this, it
- is possible to see the state of the widget directly, and even better, to
- manipulate the widget by clicking/interacting with it.
+- :doc:`Mock server <../frontend/unit_testing/mock_server>`
.. _reference/testing/integration-testing:
@@ -982,8 +747,6 @@ you can use the :meth:`~odoo.tests.BaseCase.assertQueryCount` method, integrated
.. _qunit: https://qunitjs.com/
.. _qunit_config.js: https://github.com/odoo/odoo/blob/51ee0c3cb59810449a60dae0b086b49b1ed6f946/addons/web/static/tests/helpers/qunit_config.js#L49
.. _web.tests_assets: https://github.com/odoo/odoo/blob/51ee0c3cb59810449a60dae0b086b49b1ed6f946/addons/web/views/webclient_templates.xml#L594
-.. _web.qunit_suite: https://github.com/odoo/odoo/blob/51ee0c3cb59810449a60dae0b086b49b1ed6f946/addons/web/views/webclient_templates.xml#L660
-.. _web.qunit_suite_tests: https://github.com/odoo/odoo/blob/51ee0c3cb59810449a60dae0b086b49b1ed6f946/addons/web/views/webclient_templates.xml#L680
.. _controller: https://github.com/odoo/odoo/blob/51ee0c3cb59810449a60dae0b086b49b1ed6f946/addons/web/controllers/main.py#L637
.. _test_js.py: https://github.com/odoo/odoo/blob/51ee0c3cb59810449a60dae0b086b49b1ed6f946/addons/web/tests/test_js.py#L13
.. _test_utils.js: https://github.com/odoo/odoo/blob/51ee0c3cb59810449a60dae0b086b49b1ed6f946/addons/web/static/tests/helpers/test_utils.js
diff --git a/content/developer/reference/frontend/assets.rst b/content/developer/reference/frontend/assets.rst
index c4d912842..7f28b412c 100644
--- a/content/developer/reference/frontend/assets.rst
+++ b/content/developer/reference/frontend/assets.rst
@@ -75,8 +75,8 @@ like this:
'web/static/src/js/webclient.js',
'web/static/src/xml/webclient.xml',
],
- 'web.qunit_suite_tests': [
- 'web/static/src/js/webclient_tests.js',
+ 'web.assets_unit_tests': [
+ 'web/static/src/js/webclient.test.js',
],
},
@@ -94,10 +94,7 @@ know:
- `web.assets_frontend`: this bundle is about all that is specific to the public
website: ecommerce, portal, forum, blog, ...
-- `web.qunit_suite_tests`: all javascript qunit testing code (tests, helpers, mocks)
-
-- `web.qunit_mobile_suite_tests`: mobile specific qunit testing code
-
+- `web.assets_unit_tests`: all javascript unit testing code (tests, helpers, mocks)
Operations
----------
diff --git a/content/developer/reference/frontend/unit_testing/hoot.rst b/content/developer/reference/frontend/unit_testing/hoot.rst
index beb53450c..8fb4a816f 100644
--- a/content/developer/reference/frontend/unit_testing/hoot.rst
+++ b/content/developer/reference/frontend/unit_testing/hoot.rst
@@ -15,12 +15,12 @@ key features are:
As such, it has been integrated as a :file:`lib/` in the Odoo codebase and exports 2 main modules:
-- :file:`@odoo/hoot-dom`: (can be used in production code) helpers to:
+- :file:`@odoo/hoot-dom`: (can be used in tours) helpers to:
- **interact** with the DOM, such as :js:meth:`click` and :js:meth:`press`;
- **query** elements from the DOM, such as :js:meth:`queryAll` and :js:meth:`waitFor`;
-- :file:`@odoo/hoot`: (only to be used in tests) all the test framework features:
+- :file:`@odoo/hoot`: (only to be used in unit tests) all the test framework features:
- `test`, `describe` and `expect`
- test hooks like `after` and `afterEach`