[IMP] tests: log a warning when HttpCase test in at_install
When loading a page on an existing starting database, registry is not fully loaded causing potential error when trying to access model existing in database (views, menitem, ...) since model added in last loaded module does not exist in registry. Thus, executing browser js test may lead to errors when executed during an update on a database with other modules installed. HTTPCase should be executed post_install to ensure that registry is fully loaded to avoid this problem. Since HTTPCase are slower than other test, it is also a good idea to execute them at the end, in order to prioritize fast fail. With this commit, a warning is isued if such a test class is tagged to run at install time. While at it, remove deprecated at_install and post_install helpers and remove the deprecated phantom_js alias. closes odoo/odoo#39462 Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from odoo.tests.common import HttpCase
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class AccountingTestTemplConsistency(HttpCase):
|
||||
class AccountingTestTemplConsistency(TransactionCase):
|
||||
'''Test the templates consistency between some objects like account.account when account.account.template.
|
||||
'''
|
||||
|
||||
|
||||
@@ -8,4 +8,4 @@ import odoo.tests
|
||||
class IMSupportSuite(odoo.tests.HttpCase):
|
||||
|
||||
def test_im_support_js(self):
|
||||
self.phantom_js('/im_support/tests?mod=web&failfast', "", "", login='admin', timeout=180)
|
||||
self.browser_js('/im_support/tests?mod=web&failfast', "", "", login='admin', timeout=180)
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.survey.tests import common
|
||||
from odoo.tests.common import HttpCase
|
||||
from psycopg2 import IntegrityError
|
||||
from odoo.exceptions import AccessError
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
|
||||
class TestCertificationBadge(common.SurveyCase, HttpCase):
|
||||
class TestCertificationBadge(common.SurveyCase):
|
||||
def setUp(self):
|
||||
super(TestCertificationBadge, self).setUp()
|
||||
self.certification_survey = self.env['survey.survey'].with_user(self.survey_manager).create({
|
||||
|
||||
@@ -9,7 +9,7 @@ from odoo.tests import tagged
|
||||
from odoo.tests.common import HttpCase
|
||||
|
||||
|
||||
@tagged('functional')
|
||||
@tagged('-at_install', 'post_install', 'functional')
|
||||
class TestCertificationFlow(common.SurveyCase, HttpCase):
|
||||
def _answer_question(self, question, answer, answer_token, csrf_token, button_submit='next'):
|
||||
# Employee submits the question answer
|
||||
|
||||
@@ -6,7 +6,7 @@ from odoo.tests import tagged
|
||||
from odoo.tests.common import HttpCase
|
||||
|
||||
|
||||
@tagged('functional')
|
||||
@tagged('-at_install', 'post_install', 'functional')
|
||||
class TestSurveyFlow(common.SurveyCase, HttpCase):
|
||||
def _format_submission_data(self, page, answer_data, additional_post_data):
|
||||
post_data = {}
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from werkzeug.urls import url_decode, url_parse
|
||||
from odoo.tests.common import HttpCase
|
||||
from odoo.tests.common import HttpCase, tagged
|
||||
|
||||
|
||||
@tagged('-at_install', 'post_install')
|
||||
class TestMultiCompany(HttpCase):
|
||||
|
||||
def test_redirect_to_records(self):
|
||||
|
||||
@@ -16,7 +16,7 @@ class TestUi(tests.HttpCase):
|
||||
})
|
||||
self.env.ref('website_slides.slide_channel_demo_6_furn3')._remove_membership(self.env.ref('base.partner_demo').ids)
|
||||
|
||||
self.phantom_js(
|
||||
self.browser_js(
|
||||
'/slides',
|
||||
'odoo.__DEBUG__.services["web_tour.tour"].run("certification_member")',
|
||||
'odoo.__DEBUG__.services["web_tour.tour"].tours.certification_member.ready',
|
||||
|
||||
@@ -6,7 +6,7 @@ from datetime import date
|
||||
from unittest.mock import patch
|
||||
|
||||
from odoo import http
|
||||
from odoo.tests import common
|
||||
from odoo.tests import common, tagged
|
||||
from odoo.addons.web.controllers.main import ExportXlsxWriter
|
||||
from odoo.addons.test_mail.tests.common import mail_new_test_user
|
||||
|
||||
@@ -69,6 +69,7 @@ class XlsxCreatorCase(common.HttpCase):
|
||||
self.assertFalse(value, "There are unexpected cells in the export")
|
||||
|
||||
|
||||
@tagged('-at_install', 'post_install')
|
||||
class TestGroupedExport(XlsxCreatorCase):
|
||||
model_name = 'export.group_operator'
|
||||
|
||||
|
||||
@@ -6,9 +6,10 @@ import base64
|
||||
|
||||
from PIL import Image
|
||||
|
||||
from odoo.tests.common import HttpCase
|
||||
from odoo.tests.common import HttpCase, tagged
|
||||
|
||||
|
||||
@tagged('-at_install', 'post_install')
|
||||
class TestImage(HttpCase):
|
||||
def test_01_content_image_resize_placeholder(self):
|
||||
"""The goal of this test is to make sure the placeholder image is
|
||||
|
||||
@@ -12,7 +12,7 @@ class WebSuite(odoo.tests.HttpCase):
|
||||
|
||||
def test_js(self):
|
||||
# webclient desktop test suite
|
||||
self.phantom_js('/web/tests?mod=web&failfast', "", "", login='admin', timeout=1800)
|
||||
self.browser_js('/web/tests?mod=web&failfast', "", "", login='admin', timeout=1800)
|
||||
|
||||
def test_check_suite(self):
|
||||
# verify no js test is using `QUnit.only` as it forbid any other test to be executed
|
||||
@@ -39,4 +39,4 @@ class MobileWebSuite(odoo.tests.HttpCase):
|
||||
|
||||
def test_mobile_js(self):
|
||||
# webclient mobile test suite
|
||||
self.phantom_js('/web/tests/mobile?mod=web&failfast', "", "", login='admin', timeout=1800)
|
||||
self.browser_js('/web/tests/mobile?mod=web&failfast', "", "", login='admin', timeout=1800)
|
||||
|
||||
@@ -184,6 +184,7 @@ class TestPage(common.TransactionCase):
|
||||
self.assertTrue(website_id not in View.search([('name', 'in', ('Base', 'Extension'))]).mapped('website_id').ids, "Same for views")
|
||||
|
||||
|
||||
@tagged('-at_install', 'post_install')
|
||||
class Crawler(HttpCase):
|
||||
def test_unpublished_page(self):
|
||||
Page = self.env['website.page']
|
||||
|
||||
@@ -93,7 +93,7 @@ class TestUiTranslate(odoo.tests.HttpCase):
|
||||
class TestUi(odoo.tests.HttpCase):
|
||||
|
||||
def test_01_public_homepage(self):
|
||||
self.phantom_js("/", "console.log('test successful')", "'website.content.snippets.animation' in odoo.__DEBUG__.services")
|
||||
self.browser_js("/", "console.log('test successful')", "'website.content.snippets.animation' in odoo.__DEBUG__.services")
|
||||
|
||||
def test_02_admin_tour_banner(self):
|
||||
self.start_tour("/", 'banner', login='admin')
|
||||
|
||||
@@ -897,6 +897,7 @@ class TestCowViewSaving(common.TransactionCase):
|
||||
# 3 | Extension 2 | , extended content 2 | 1 | 5 | website.extension_view_2
|
||||
|
||||
|
||||
@tagged('-at_install', 'post_install')
|
||||
class Crawler(HttpCase):
|
||||
def setUp(self):
|
||||
super(Crawler, self).setUp()
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# coding: utf-8
|
||||
from odoo.tests import HttpCase
|
||||
from odoo.tests import HttpCase, tagged
|
||||
|
||||
|
||||
@tagged('-at_install', 'post_install')
|
||||
class WebsiteVisitorTests(HttpCase):
|
||||
def test_create_visitor_on_tracked_page(self):
|
||||
Page = self.env['website.page']
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo.tests import common
|
||||
from odoo.tests import common, tagged
|
||||
from odoo.tools.misc import mute_logger, ustr
|
||||
|
||||
|
||||
@tagged('-at_install', 'post_install')
|
||||
class TestConfirmUnsubscribe(common.HttpCase):
|
||||
def setUp(self):
|
||||
super(TestConfirmUnsubscribe, self).setUp()
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
import odoo.tests
|
||||
|
||||
|
||||
@odoo.tests.common.at_install(False)
|
||||
@odoo.tests.common.post_install(True)
|
||||
@odoo.tests.tagged('-at_install', 'post_install')
|
||||
class TestUi(odoo.tests.HttpCase):
|
||||
def test_01_wishlist_tour(self):
|
||||
self.start_tour("/", 'shop_wishlist')
|
||||
|
||||
@@ -15,7 +15,7 @@ class TestUi(tests.HttpCase):
|
||||
})
|
||||
self.env.ref('website_slides.slide_channel_demo_0_gard_0')._remove_membership(self.env.ref('base.partner_demo').ids)
|
||||
|
||||
self.phantom_js(
|
||||
self.browser_js(
|
||||
'/slides',
|
||||
'odoo.__DEBUG__.services["web_tour.tour"].run("course_member")',
|
||||
'odoo.__DEBUG__.services["web_tour.tour"].tours.course_member.ready',
|
||||
@@ -31,7 +31,7 @@ class TestUi(tests.HttpCase):
|
||||
})
|
||||
self.env.ref('website_slides.slide_channel_demo_0_gard_0')._remove_membership(self.env.ref('base.partner_demo').ids)
|
||||
|
||||
self.phantom_js(
|
||||
self.browser_js(
|
||||
'/slides',
|
||||
'odoo.__DEBUG__.services["web_tour.tour"].run("course_member")',
|
||||
'odoo.__DEBUG__.services["web_tour.tour"].tours.course_member.ready',
|
||||
@@ -44,7 +44,7 @@ class TestUi(tests.HttpCase):
|
||||
user_portal.flush()
|
||||
self.env.ref('website_slides.slide_channel_demo_0_gard_0')._remove_membership(self.env.ref('base.partner_demo_portal').ids)
|
||||
|
||||
self.phantom_js(
|
||||
self.browser_js(
|
||||
'/slides',
|
||||
'odoo.__DEBUG__.services["web_tour.tour"].run("course_member")',
|
||||
'odoo.__DEBUG__.services["web_tour.tour"].tours.course_member.ready',
|
||||
@@ -63,7 +63,7 @@ class TestUiYoutube(tests.HttpCase):
|
||||
})
|
||||
self.env.ref('website_slides.slide_channel_demo_3_furn0')._remove_membership(self.env.ref('base.partner_demo').ids)
|
||||
|
||||
self.phantom_js(
|
||||
self.browser_js(
|
||||
'/slides',
|
||||
'odoo.__DEBUG__.services["web_tour.tour"].run("course_member_youtube")',
|
||||
'odoo.__DEBUG__.services["web_tour.tour"].tours.course_member_youtube.ready',
|
||||
@@ -78,7 +78,7 @@ class TestUiYoutube(tests.HttpCase):
|
||||
'groups_id': [(5, 0), (4, self.env.ref('base.group_user').id), (4, self.env.ref('website.group_website_designer').id)]
|
||||
})
|
||||
|
||||
self.phantom_js(
|
||||
self.browser_js(
|
||||
'/slides',
|
||||
'odoo.__DEBUG__.services["web_tour.tour"].run("course_publisher")',
|
||||
'odoo.__DEBUG__.services["web_tour.tour"].tours.course_publisher.ready',
|
||||
|
||||
@@ -54,6 +54,7 @@ class TestViews(TransactionCase):
|
||||
self.assertEqual(specific_main_view_children.website_id, website_1, "..and the website is the correct one.")
|
||||
|
||||
|
||||
@tagged('-at_install', 'post_install')
|
||||
class Crawler(HttpCase):
|
||||
def test_multi_website_views_retrieving(self):
|
||||
View = self.env['ir.ui.view']
|
||||
|
||||
@@ -56,7 +56,7 @@ related to testing Odoo content (modules, mainly):
|
||||
.. autoclass:: odoo.tests.common.SavepointCase
|
||||
|
||||
.. autoclass:: odoo.tests.common.HttpCase
|
||||
:members: browse_ref, ref, url_open, phantom_js
|
||||
:members: browse_ref, ref, url_open, browser_js
|
||||
|
||||
.. autofunction:: odoo.tests.common.tagged
|
||||
|
||||
@@ -321,7 +321,7 @@ infrastructure:
|
||||
|
||||
- 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 phantom_js method does not spawn phantom_js, but Chrome headless instead.
|
||||
the browser_js method spawns a Chrome headless instance.
|
||||
|
||||
|
||||
Modularity and testing
|
||||
@@ -501,7 +501,7 @@ Testing Python code and JS code separately is very useful, but it does not prove
|
||||
that the web client and the server work together. In order to do that, we can
|
||||
write another kind of test: tours. A tour is a mini scenario of some interesting
|
||||
business flow. It explains a sequence of steps that should be followed. The
|
||||
test runner will then create a phantom_js browser, point it to the proper url
|
||||
test runner will then create a Chrome headless browser, point it to the proper url
|
||||
and simulate the click and inputs, according to the scenario.
|
||||
|
||||
Screenshots and screencasts during browser_js tests
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import odoo.tests
|
||||
|
||||
|
||||
class TestMonetaryAccess(odoo.tests.HttpCase):
|
||||
class TestMonetaryAccess(odoo.tests.TransactionCase):
|
||||
|
||||
def test_monetary_access_create(self):
|
||||
"""Monetary fields that depend on compute/related currency
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import odoo.tests
|
||||
|
||||
|
||||
@odoo.tests.tagged('-at_install', 'post_install')
|
||||
class TestAccess(odoo.tests.HttpCase):
|
||||
def setUp(self):
|
||||
super(TestAccess, self).setUp()
|
||||
|
||||
@@ -12,7 +12,7 @@ from odoo import api
|
||||
from odoo.addons.base.models.assetsbundle import AssetsBundle
|
||||
from odoo.addons.base.models.ir_attachment import IrAttachment
|
||||
from odoo.modules.module import get_resource_path
|
||||
from odoo.tests import HttpCase
|
||||
from odoo.tests import HttpCase, tagged
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
GETMTINE = os.path.getmtime
|
||||
@@ -512,11 +512,12 @@ class TestJavascriptAssetsBundle(FileTouchable):
|
||||
</html>""").encode('utf8'))
|
||||
|
||||
|
||||
@tagged('-at_install', 'post_install')
|
||||
class TestAssetsBundleInBrowser(HttpCase):
|
||||
def test_01_js_interpretation(self):
|
||||
""" Checks that the javascript of a bundle is correctly interpreted.
|
||||
"""
|
||||
self.phantom_js(
|
||||
self.browser_js(
|
||||
"/test_assetsbundle/js",
|
||||
"a + b + c === 6 ? console.log('test successful') : console.log('error')",
|
||||
login="admin"
|
||||
@@ -542,7 +543,7 @@ class TestAssetsBundleInBrowser(HttpCase):
|
||||
})
|
||||
self.env.user.flush()
|
||||
|
||||
self.phantom_js(
|
||||
self.browser_js(
|
||||
"/test_assetsbundle/js",
|
||||
"a + b + c + d === 10 ? console.log('test successful') : console.log('error')",
|
||||
login="admin",
|
||||
|
||||
@@ -17,6 +17,7 @@ class TestUi(odoo.tests.HttpCase):
|
||||
'widget_x2many', step_delay=100, login="admin", timeout=120)
|
||||
|
||||
|
||||
@odoo.tests.tagged('-at_install', 'post_install')
|
||||
class TestUiTranslation(odoo.tests.HttpCase):
|
||||
|
||||
@mute_logger('odoo.sql_db', 'odoo.http')
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
from functools import partial
|
||||
|
||||
from odoo.tests import common
|
||||
from odoo.tests import common, tagged
|
||||
from odoo.tools.misc import mute_logger
|
||||
|
||||
|
||||
@tagged('-at_install', 'post_install')
|
||||
class TestError(common.HttpCase):
|
||||
def setUp(self):
|
||||
super(TestError, self).setUp()
|
||||
|
||||
+2
-34
@@ -87,37 +87,6 @@ def get_db_name():
|
||||
DB = get_db_name()
|
||||
|
||||
|
||||
def at_install(flag):
|
||||
""" Sets the at-install state of a test, the flag is a boolean specifying
|
||||
whether the test should (``True``) or should not (``False``) run during
|
||||
module installation.
|
||||
|
||||
By default, tests are run right after installing the module, before
|
||||
starting the installation of the next module.
|
||||
|
||||
.. deprecated:: 12.0
|
||||
|
||||
``at_install`` is now a flag, you can use :func:`tagged` to
|
||||
add/remove it, although ``tagged`` only works on test classes
|
||||
"""
|
||||
return tagged('at_install' if flag else '-at_install')
|
||||
|
||||
def post_install(flag):
|
||||
""" Sets the post-install state of a test. The flag is a boolean
|
||||
specifying whether the test should or should not run after a set of
|
||||
module installations.
|
||||
|
||||
By default, tests are *not* run after installation of all modules in the
|
||||
current installation set.
|
||||
|
||||
.. deprecated:: 12.0
|
||||
|
||||
``post_install`` is now a flag, you can use :func:`tagged` to
|
||||
add/remove it, although ``tagged`` only works on test classes
|
||||
"""
|
||||
return tagged('post_install' if flag else '-post_install')
|
||||
|
||||
|
||||
def new_test_user(env, login='', groups='base.group_user', context=None, **kwargs):
|
||||
""" Helper function to create a new test user. It allows to quickly create
|
||||
users given its login and groups (being a comma separated list of xml ids).
|
||||
@@ -955,7 +924,8 @@ class HttpCase(TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(HttpCase, self).setUp()
|
||||
|
||||
if not self.env.registry.loaded:
|
||||
self._logger.warning('HttpCase test should be in post_install only')
|
||||
if self.registry_test_mode:
|
||||
self.registry.enter_test_mode(self.cr)
|
||||
self.addCleanup(self.registry.leave_test_mode)
|
||||
@@ -1102,8 +1072,6 @@ class HttpCase(TransactionCase):
|
||||
self.env.cache.invalidate()
|
||||
return res
|
||||
|
||||
phantom_js = browser_js
|
||||
|
||||
|
||||
def users(*logins):
|
||||
""" Decorate a method to execute it once for each given user. """
|
||||
|
||||
Reference in New Issue
Block a user