[IMP] test_event_full: add performance on frontend and registration tour

Purpose of this commit is to add performance tests for some commonly used
URLs related to event: the main event page and browsing a given event.

A complete registration tour involving buying tickets, answering questions
and filling billing information is also added under a query counter check.
This allows to see a bit how many queries are involved in that flow. To
ease reproduction a data is added but not imported, allowing to quickly see
what happens locally instead of having to debug tests.

Task-2703285 (Event performance improvements)
Task-2703289 (Event testing and coverage)

Part-of: odoo/odoo#81068
This commit is contained in:
Thibault Delavallée
2021-12-16 17:33:49 +00:00
parent eee03e9ce0
commit 2411a6b69c
5 changed files with 298 additions and 1 deletions
+2
View File
@@ -17,6 +17,7 @@ automatic lead generation, full Online support, ...
'event_crm_sale',
'event_sale',
'event_sms',
'payment_test',
'website_event_booth_sale_exhibitor',
'website_event_crm_questions',
'website_event_exhibitor',
@@ -28,6 +29,7 @@ automatic lead generation, full Online support, ...
'website_event_track_quiz',
],
'data': [
# 'data/event_type_data.xml', # uncomment to reproduce test tour
'data/ir_actions_report_data.xml',
'views/event_registration_templates_reports.xml',
],
@@ -0,0 +1,122 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo><data noupdate="0">
<record id="event_booth_category_data_1" model="event.booth.category">
<field name="description" type="html"><p>Standard</p></field>
<field name="name">Standard</field>
<field name="product_id" ref="event_booth_sale.product_product_event_booth"/>
</record>
<record id="event_booth_category_data_2" model="event.booth.category">
<field name="description" type="html"><p>Premium</p></field>
<field name="name">Premium</field>
<field name="product_id" ref="event_booth_sale.product_product_event_booth"/>
<field name="price">90</field>
</record>
<record id="event_type_data_full" model="event.type">
<field name="auto_confirm" eval="True"/>
<field name="default_timezone">Europe/Paris</field>
<field name="event_type_booth_ids" eval="[
(5, 0),
(0, 0, {'booth_category_id': ref('test_event_full.event_booth_category_data_1'),
'name': 'Standard Booth',
}
),
(0, 0, {'booth_category_id': ref('test_event_full.event_booth_category_data_1'),
'name': 'Standard Booth 2',
}
),
(0, 0, {'booth_category_id': ref('test_event_full.event_booth_category_data_2'),
'name': 'Premium Booth',
}
),
(0, 0, {'booth_category_id': ref('test_event_full.event_booth_category_data_2'),
'name': 'Premium Booth 2',
}
)]"/>
<field name="event_type_mail_ids" eval="[
(5, 0),
(0, 0, {'interval_unit': 'now',
'interval_type': 'after_sub',
'notification_type': 'mail',
'template_ref': 'mail.template,%i' % ref('event.event_subscription'),
}
),
(0, 0, {'interval_nbr': 1,
'interval_unit': 'days',
'interval_type': 'before_event',
'notification_type': 'mail',
'template_ref': 'mail.template,%i' % ref('event.event_reminder'),
}
),
(0, 0, {'interval_nbr': 1,
'interval_unit': 'days',
'interval_type': 'after_event',
'notification_type': 'sms',
'template_ref': 'sms.template,%i' % ref('event_sms.sms_template_data_event_reminder'),
}
)]"/>
<field name="event_type_ticket_ids" eval="[
(5, 0),
(0, 0, {'description': 'Ticket1 Description',
'name': 'Ticket1',
'product_id': ref('event_sale.product_product_event'),
'seats_max': 10,
}
),
(0, 0, {'description': 'Ticket2 Description',
'name': 'Ticket2',
'product_id': ref('event_sale.product_product_event'),
'price': 45,
}
)]"/>
<field name="has_seats_limitation" eval="True"/>
<field name="name">Test Type</field>
<field name="note" type="html"><p>Template note</p></field>
<field name="question_ids" eval="[(5, 0)]"/>
<field name="seats_max">30</field>
<field name="tag_ids" eval="[(5, 0)]"/>
<field name="ticket_instructions" type="html"><p>Ticket Instructions</p></field>
<field name="website_menu" eval="True"/>
</record>
<record id="event_question_type_full_1" model="event.question">
<field name="question_type">simple_choice</field>
<field name="once_per_order" eval="False"/>
<field name="event_type_id" ref="test_event_full.event_type_data_full"/>
<field name="title">Question1</field>
</record>
<record id="event_question_type_full_1_answer_1" model="event.question.answer">
<field name="name">Q1-Answer1</field>
<field name="sequence">1</field>
<field name="question_id" ref="test_event_full.event_question_type_full_1"/>
</record>
<record id="event_question_type_full_1_answer_2" model="event.question.answer">
<field name="name">Q1-Answer2</field>
<field name="sequence">2</field>
<field name="question_id" ref="test_event_full.event_question_type_full_1"/>
</record>
<record id="event_question_type_full_2" model="event.question">
<field name="question_type">simple_choice</field>
<field name="once_per_order" eval="False"/>
<field name="event_type_id" ref="test_event_full.event_type_data_full"/>
<field name="title">Question2</field>
</record>
<record id="event_question_type_full_2_answer_1" model="event.question.answer">
<field name="name">Q2-Answer1</field>
<field name="sequence">1</field>
<field name="question_id" ref="test_event_full.event_question_type_full_2"/>
</record>
<record id="event_question_type_full_2_answer_2" model="event.question.answer">
<field name="name">Q2-Answer2</field>
<field name="sequence">2</field>
<field name="question_id" ref="test_event_full.event_question_type_full_2"/>
</record>
<record id="event_question_type_full_3" model="event.question">
<field name="question_type">text_box</field>
<field name="once_per_order" eval="True"/>
<field name="event_type_id" ref="test_event_full.event_type_data_full"/>
<field name="title">Question3</field>
</record>
</data></odoo>
@@ -0,0 +1,85 @@
odoo.define('test_event_full.tour.performance', function (require) {
"use strict";
var tour = require('web_tour.tour');
var registerSteps = [{
content: "Select 2 units of 'Ticket1' ticket type",
trigger: '#o_wevent_tickets_collapse .row.o_wevent_ticket_selector[name="Ticket1"] select',
run: 'text 2',
}, {
content: "Select 1 unit of 'Ticket2' ticket type",
trigger: '#o_wevent_tickets_collapse .row.o_wevent_ticket_selector[name="Ticket2"] select',
run: 'text 1',
}, {
content: "Click on 'Register' button",
trigger: '#o_wevent_tickets .btn-primary:contains("Register"):not(:disabled)',
run: 'click',
}, {
content: "Fill attendees details",
trigger: 'form[id="attendee_registration"] .btn:contains("Continue")',
run: function () {
$("input[name='1-name']").val("Raoulette Poiluchette");
$("input[name='1-phone']").val("0456112233");
$("input[name='1-email']").val("raoulette@example.com");
$("div[name*='Question1'] select[name*='question_answer-1']").val($("select[name*='question_answer-1'] option:contains('Q1-Answer2')").val());
$("div[name*='Question2'] select[name*='question_answer-1']").val($("select[name*='question_answer-1'] option:contains('Q2-Answer1')").val());
$("input[name='2-name']").val("Michel Tractopelle");
$("input[name='2-phone']").val("0456332211");
$("input[name='2-email']").val("michel@example.com");
$("div[name*='Question1'] select[name*='question_answer-2']").val($("select[name*='question_answer-2'] option:contains('Q1-Answer1')").val());
$("div[name*='Question2'] select[name*='question_answer-2']").val($("select[name*='question_answer-2'] option:contains('Q2-Answer2')").val());
$("input[name='3-name']").val("Hubert Boitaclous");
$("input[name='3-phone']").val("0456995511");
$("input[name='3-email']").val("hubert@example.com");
$("div[name*='Question1'] select[name*='question_answer-3']").val($("select[name*='question_answer-3'] option:contains('Q1-Answer2')").val());
$("div[name*='Question2'] select[name*='question_answer-3']").val($("select[name*='question_answer-3'] option:contains('Q2-Answer2')").val());
$("textarea[name*='question_answer']").text("Random answer from random guy");
},
}, {
content: "Validate attendees details",
extra_trigger: "input[name='1-name'], input[name='2-name'], input[name='3-name']",
trigger: 'button:contains("Continue")',
run: 'click',
}, {
content: "Address filling",
trigger: 'select[name="country_id"]',
run: function () {
$('input[name="name"]').val('Raoulette Poiluchette');
$('input[name="phone"]').val('0456112233');
$('input[name="email"]').val('raoulette@example.com');
$('input[name="street"]').val('Cheesy Crust Street, 42');
$('input[name="city"]').val('CheeseCity');
$('input[name="zip"]').val('8888');
$('#country_id option:eq(1)').attr('selected', true);
},
}, {
content: "Next",
trigger: '.oe_cart .btn:contains("Next")',
}, {
content: 'Select Test payment acquirer',
trigger: '.o_payment_option_card:contains("Test")'
}, {
content: 'Add card number',
trigger: 'input[name="customer_input"]',
run: 'text 4242424242424242'
}, {
content: "Pay now",
extra_trigger: "#cart_products:contains(Ticket1):contains(Ticket2)",
trigger: 'button:contains(Pay Now)',
run: 'click',
}, {
content: 'Payment is successful',
trigger: '.oe_website_sale_tx_status:contains("Your payment has been successfully processed.")',
run: function () {}
}];
tour.register('wevent_performance_register', {
test: true
}, [].concat(
registerSteps,
)
);
});
@@ -5,6 +5,7 @@ from datetime import timedelta
from freezegun import freeze_time
from odoo.addons.test_event_full.tests.common import TestEventFullCommon
from odoo.addons.website.tests.test_performance import UtilPerf
from odoo.tests.common import users, warmup, Form
from odoo.tests import tagged
@@ -332,3 +333,90 @@ class TestRegistrationPerformance(EventPerformanceCase):
self.website_customer_data[0],
event_id=event.id)
self.env['event.registration'].create([registration_values])
@tagged('event_performance', 'event_online', 'post_install', '-at_install')
class TestOnlineEventPerformance(EventPerformanceCase, UtilPerf):
@classmethod
def setUpClass(cls):
super(TestOnlineEventPerformance, cls).setUpClass()
# if website_livechat is installed, disable it
if 'channel_id' in cls.env['website']:
cls.env['website'].search([]).channel_id = False
cash_journal = cls.env['account.journal'].create({
'name': 'Cash - Test',
'type': 'cash',
'code': 'CASH - Test'
})
cls.env['payment.acquirer'].search([('provider', '=', 'test')]).write({
'journal_id': cash_journal.id,
'state': 'test'
})
# clean even page to make it reproducible
cls.env['event.event'].search([('name', '!=', 'Test Event')]).write({'active': False})
# create noise for events
cls.noise_events = cls.env['event.event'].create([
{'name': 'Event %02d' % idx,
'date_begin': cls.reference_now + timedelta(days=(-2 + int(idx/10))),
'date_end': cls.reference_now + timedelta(days=5),
'is_published': True,
}
for idx in range(0, 50)
])
def _test_url_open(self, url):
url += ('?' not in url and '?' or '') + '&nocache'
return self.url_open(url)
@warmup
def test_event_page_event_manager(self):
# website customer data
with freeze_time(self.reference_now):
self.authenticate('user_eventmanager', 'user_eventmanager')
with self.assertQueryCount(default=65): # tef only: 64 (+1 ent)
self._test_url_open('/event/%i' % self.test_event.id)
@warmup
def test_event_page_public(self):
# website customer data
with freeze_time(self.reference_now):
self.authenticate(None, None)
with self.assertQueryCount(default=43): # tef only: 43
self._test_url_open('/event/%i' % self.test_event.id)
@warmup
def test_events_browse_event_manager(self):
# website customer data
with freeze_time(self.reference_now):
self.authenticate('user_eventmanager', 'user_eventmanager')
with self.assertQueryCount(default=51): # tef only: 50 (+1 ent)
self._test_url_open('/event')
@warmup
def test_events_browse_public(self):
# website customer data
with freeze_time(self.reference_now):
self.authenticate(None, None)
with self.assertQueryCount(default=32): # tef only: 32
self._test_url_open('/event')
# @warmup
# def test_register_public(self):
# with freeze_time(self.reference_now + timedelta(hours=3)): # be sure sales has started
# self.assertTrue(self.test_event.event_registrations_started)
# self.authenticate(None, None)
# with self.assertQueryCount(default=99999): # tef only: 1110
# self.browser_js(
# '/event/%i/register' % self.test_event.id,
# 'odoo.__DEBUG__.services["web_tour.tour"].run("wevent_performance_register")',
# 'odoo.__DEBUG__.services["web_tour.tour"].tours.wevent_performance_register.ready',
# login=None,
# timeout=200,
# )
# # minimal checkup, to be improved in future tests independently from performance
# self.assertEqual(len(self.test_event.registration_ids), 3)
# self.assertEqual(len(self.test_event.registration_ids.visitor_id), 1)
@@ -7,7 +7,7 @@ from odoo import tests
from odoo.addons.test_event_full.tests.common import TestWEventCommon
@tests.common.tagged('post_install', '-at_install')
@tests.common.tagged('event_online', 'post_install', '-at_install')
class TestWEventRegister(TestWEventCommon):
def test_register(self):