[IMP] running speed of some tests & new testcase type

Some tests (e.g. mail) have expensive and significant DB setup for a
number of small and cheap tests. Using a TransactionCase, the DB setup
far dominates the tests themselves, by up to 10x (mail unit tests take
~130s on my machine, the tests themselves take ~15s).

The SavepointCase introduced here is an hybrid of SingleTransactionCase
and TransactionCase: it uses a single transaction for all tests in a
class, but each test case is isolated by a rollbacked savepoint. This
allows a common DB setup (via setUpClass) while keeping independent
tests.

TransactionCase should remain the primary test case superclass, but
SavepointCase can be a fair optimisation when setup costs far dominate.
This commit is contained in:
Xavier Morel 2015-06-23 13:14:07 +02:00
parent 386f76eb46
commit 11ba4689b1
15 changed files with 144 additions and 181 deletions

View File

@ -22,63 +22,66 @@
from openerp.tests import common from openerp.tests import common
class TestMail(common.TransactionCase): class TestMail(common.SavepointCase):
def _init_mock_build_email(self): @classmethod
self._build_email_args_list = [] def _init_mock_build_email(cls):
self._build_email_kwargs_list = [] cls._build_email_args_list = []
cls._build_email_kwargs_list = []
def setUp(self): def setUp(self):
super(TestMail, self).setUp() super(TestMail, self).setUp()
cr, uid = self.cr, self.uid self._build_email_args_list[:] = []
self._build_email_kwargs_list[:] = []
# Install mock SMTP gateway @classmethod
test = self def setUpClass(cls):
super(TestMail, cls).setUpClass()
cr, uid = cls.cr, cls.uid
def build_email(self, *args, **kwargs): def build_email(self, *args, **kwargs):
test._build_email_args_list.append(args) cls._build_email_args_list.append(args)
test._build_email_kwargs_list.append(kwargs) cls._build_email_kwargs_list.append(kwargs)
return build_email.origin(self, *args, **kwargs) return build_email.origin(self, *args, **kwargs)
def send_email(self, cr, uid, message, *args, **kwargs): def send_email(self, cr, uid, message, *args, **kwargs):
return message['Message-Id'] return message['Message-Id']
self._init_mock_build_email() cls._init_mock_build_email()
self.registry('ir.mail_server')._patch_method('build_email', build_email) cls.registry('ir.mail_server')._patch_method('build_email', build_email)
self.registry('ir.mail_server')._patch_method('send_email', send_email) cls.registry('ir.mail_server')._patch_method('send_email', send_email)
# Usefull models # Usefull models
self.ir_model = self.registry('ir.model') cls.ir_model = cls.registry('ir.model')
self.ir_model_data = self.registry('ir.model.data') cls.ir_model_data = cls.registry('ir.model.data')
self.ir_attachment = self.registry('ir.attachment') cls.ir_attachment = cls.registry('ir.attachment')
self.mail_alias = self.registry('mail.alias') cls.mail_alias = cls.registry('mail.alias')
self.mail_thread = self.registry('mail.thread') cls.mail_thread = cls.registry('mail.thread')
self.mail_group = self.registry('mail.group') cls.mail_group = cls.registry('mail.group')
self.mail_mail = self.registry('mail.mail') cls.mail_mail = cls.registry('mail.mail')
self.mail_message = self.registry('mail.message') cls.mail_message = cls.registry('mail.message')
self.mail_notification = self.registry('mail.notification') cls.mail_notification = cls.registry('mail.notification')
self.mail_followers = self.registry('mail.followers') cls.mail_followers = cls.registry('mail.followers')
self.mail_message_subtype = self.registry('mail.message.subtype') cls.mail_message_subtype = cls.registry('mail.message.subtype')
self.res_users = self.registry('res.users') cls.res_users = cls.registry('res.users')
self.res_partner = self.registry('res.partner') cls.res_partner = cls.registry('res.partner')
# Find Employee group # Find Employee group
group_employee_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_user') cls.group_employee_id = cls.env.ref('base.group_user').id or False
self.group_employee_id = group_employee_ref and group_employee_ref[1] or False
# Partner Data # Partner Data
# User Data: employee, noone # User Data: employee, noone
self.user_employee_id = self.res_users.create(cr, uid, { cls.user_employee_id = cls.res_users.create(cr, uid, {
'name': 'Ernest Employee', 'name': 'Ernest Employee',
'login': 'ernest', 'login': 'ernest',
'alias_name': 'ernest', 'alias_name': 'ernest',
'email': 'e.e@example.com', 'email': 'e.e@example.com',
'signature': '--\nErnest', 'signature': '--\nErnest',
'notify_email': 'always', 'notify_email': 'always',
'groups_id': [(6, 0, [self.group_employee_id])] 'groups_id': [(6, 0, [cls.group_employee_id])]
}, {'no_reset_password': True}) }, {'no_reset_password': True})
self.user_noone_id = self.res_users.create(cr, uid, { cls.user_noone_id = cls.res_users.create(cr, uid, {
'name': 'Noemie NoOne', 'name': 'Noemie NoOne',
'login': 'noemie', 'login': 'noemie',
'alias_name': 'noemie', 'alias_name': 'noemie',
@ -89,16 +92,16 @@ class TestMail(common.TransactionCase):
}, {'no_reset_password': True}) }, {'no_reset_password': True})
# Test users to use through the various tests # Test users to use through the various tests
self.res_users.write(cr, uid, uid, {'name': 'Administrator'}) cls.res_users.write(cr, uid, uid, {'name': 'Administrator'})
self.user_raoul_id = self.res_users.create(cr, uid, { cls.user_raoul_id = cls.res_users.create(cr, uid, {
'name': 'Raoul Grosbedon', 'name': 'Raoul Grosbedon',
'signature': 'SignRaoul', 'signature': 'SignRaoul',
'email': 'raoul@raoul.fr', 'email': 'raoul@raoul.fr',
'login': 'raoul', 'login': 'raoul',
'alias_name': 'raoul', 'alias_name': 'raoul',
'groups_id': [(6, 0, [self.group_employee_id])] 'groups_id': [(6, 0, [cls.group_employee_id])]
}) })
self.user_bert_id = self.res_users.create(cr, uid, { cls.user_bert_id = cls.res_users.create(cr, uid, {
'name': 'Bert Tartignole', 'name': 'Bert Tartignole',
'signature': 'SignBert', 'signature': 'SignBert',
'email': 'bert@bert.fr', 'email': 'bert@bert.fr',
@ -106,27 +109,28 @@ class TestMail(common.TransactionCase):
'alias_name': 'bert', 'alias_name': 'bert',
'groups_id': [(6, 0, [])] 'groups_id': [(6, 0, [])]
}) })
self.user_raoul = self.res_users.browse(cr, uid, self.user_raoul_id) cls.user_raoul = cls.res_users.browse(cr, uid, cls.user_raoul_id)
self.user_bert = self.res_users.browse(cr, uid, self.user_bert_id) cls.user_bert = cls.res_users.browse(cr, uid, cls.user_bert_id)
self.user_admin = self.res_users.browse(cr, uid, uid) cls.user_admin = cls.res_users.browse(cr, uid, uid)
self.partner_admin_id = self.user_admin.partner_id.id cls.partner_admin_id = cls.user_admin.partner_id.id
self.partner_raoul_id = self.user_raoul.partner_id.id cls.partner_raoul_id = cls.user_raoul.partner_id.id
self.partner_bert_id = self.user_bert.partner_id.id cls.partner_bert_id = cls.user_bert.partner_id.id
# Test 'pigs' group to use through the various tests # Test 'pigs' group to use through the various tests
self.group_pigs_id = self.mail_group.create( cls.group_pigs_id = cls.mail_group.create(
cr, uid, cr, uid,
{'name': 'Pigs', 'description': 'Fans of Pigs, unite !', 'alias_name': 'group+pigs'}, {'name': 'Pigs', 'description': 'Fans of Pigs, unite !', 'alias_name': 'group+pigs'},
{'mail_create_nolog': True} {'mail_create_nolog': True}
) )
self.group_pigs = self.mail_group.browse(cr, uid, self.group_pigs_id) cls.group_pigs = cls.mail_group.browse(cr, uid, cls.group_pigs_id)
# Test mail.group: public to provide access to everyone # Test mail.group: public to provide access to everyone
self.group_jobs_id = self.mail_group.create(cr, uid, {'name': 'Jobs', 'public': 'public'}) cls.group_jobs_id = cls.mail_group.create(cr, uid, {'name': 'Jobs', 'public': 'public'})
# Test mail.group: private to restrict access # Test mail.group: private to restrict access
self.group_priv_id = self.mail_group.create(cr, uid, {'name': 'Private', 'public': 'private'}) cls.group_priv_id = cls.mail_group.create(cr, uid, {'name': 'Private', 'public': 'private'})
def tearDown(self): @classmethod
def tearDownClass(cls):
# Remove mocks # Remove mocks
self.registry('ir.mail_server')._revert_method('build_email') cls.registry('ir.mail_server')._revert_method('build_email')
self.registry('ir.mail_server')._revert_method('send_email') cls.registry('ir.mail_server')._revert_method('send_email')
super(TestMail, self).tearDown() super(TestMail, cls).tearDownClass()

View File

@ -19,7 +19,7 @@
# #
############################################################################## ##############################################################################
from openerp.addons.mail.tests.common import TestMail from .common import TestMail
class test_invite(TestMail): class test_invite(TestMail):

View File

@ -19,9 +19,9 @@
# #
############################################################################## ##############################################################################
from openerp.addons.mail.mail_mail import mail_mail from ..mail_mail import mail_mail
from openerp.addons.mail.mail_thread import mail_thread from ..mail_thread import mail_thread
from openerp.addons.mail.tests.common import TestMail from .common import TestMail
from openerp.tools import mute_logger, email_split, html2plaintext from openerp.tools import mute_logger, email_split, html2plaintext
from openerp.tools.mail import html_sanitize from openerp.tools.mail import html_sanitize

View File

@ -19,7 +19,7 @@
# #
############################################################################## ##############################################################################
from openerp.addons.mail.tests.common import TestMail from .common import TestMail
from openerp.tools import mute_logger from openerp.tools import mute_logger
import socket import socket

View File

@ -19,7 +19,7 @@
# #
############################################################################## ##############################################################################
from openerp.addons.mail.tests.common import TestMail from .common import TestMail
from openerp.exceptions import AccessError from openerp.exceptions import AccessError
from openerp.osv.orm import except_orm from openerp.osv.orm import except_orm
from openerp.tools import mute_logger from openerp.tools import mute_logger

View File

@ -19,7 +19,7 @@
# #
############################################################################## ##############################################################################
from openerp.addons.mail.tests.common import TestMail from .common import TestMail
from openerp.exceptions import AccessError from openerp.exceptions import AccessError
from openerp.osv.orm import except_orm from openerp.osv.orm import except_orm
from openerp.tools import mute_logger from openerp.tools import mute_logger

View File

@ -19,7 +19,7 @@
# #
############################################################################## ##############################################################################
from openerp.addons.mail.tests.common import TestMail from .common import TestMail
class test_mail_access_rights(TestMail): class test_mail_access_rights(TestMail):

View File

@ -27,26 +27,26 @@ from openerp.tools.misc import mute_logger
class test_portal(TestMail): class test_portal(TestMail):
def setUp(self): @classmethod
super(test_portal, self).setUp() def setUpClass(cls):
cr, uid = self.cr, self.uid super(test_portal, cls).setUpClass()
cr, uid = cls.cr, cls.uid
# Find Portal group # Find Portal group
group_portal = self.registry('ir.model.data').get_object(cr, uid, 'base', 'group_portal') cls.group_portal_id = cls.env.ref('base.group_portal').id
self.group_portal_id = group_portal.id
# Create Chell (portal user) # Create Chell (portal user)
self.user_chell_id = self.res_users.create(cr, uid, {'name': 'Chell Gladys', 'login': 'chell', 'email': 'chell@gladys.portal', 'groups_id': [(6, 0, [self.group_portal_id])]}) cls.user_chell_id = cls.res_users.create(cr, uid, {'name': 'Chell Gladys', 'login': 'chell', 'email': 'chell@gladys.portal', 'groups_id': [(6, 0, [cls.group_portal_id])]})
self.user_chell = self.res_users.browse(cr, uid, self.user_chell_id) cls.user_chell = cls.res_users.browse(cr, uid, cls.user_chell_id)
self.partner_chell_id = self.user_chell.partner_id.id cls.partner_chell_id = cls.user_chell.partner_id.id
# Create a PigsPortal group # Create a PigsPortal group
self.group_port_id = self.mail_group.create(cr, uid, cls.group_port_id = cls.mail_group.create(cr, uid,
{'name': 'PigsPortal', 'public': 'groups', 'group_public_id': self.group_portal_id}, {'name': 'PigsPortal', 'public': 'groups', 'group_public_id': cls.group_portal_id},
{'mail_create_nolog': True}) {'mail_create_nolog': True})
# Set an email address for the user running the tests, used as Sender for outgoing mails # Set an email address for the user running the tests, used as Sender for outgoing mails
self.res_users.write(cr, uid, uid, {'email': 'test@localhost'}) cls.res_users.write(cr, uid, uid, {'email': 'test@localhost'})
@mute_logger('openerp.addons.base.ir.ir_model', 'openerp.models') @mute_logger('openerp.addons.base.ir.ir_model', 'openerp.models')
def test_00_mail_access_rights(self): def test_00_mail_access_rights(self):

View File

@ -24,76 +24,75 @@ from openerp.addons.mail.tests.common import TestMail
class TestProjectBase(TestMail): class TestProjectBase(TestMail):
def setUp(self): @classmethod
super(TestProjectBase, self).setUp() def setUpClass(cls):
cr, uid = self.cr, self.uid super(TestProjectBase, cls).setUpClass()
cr, uid = cls.cr, cls.uid
# Usefull models # Usefull models
self.project_project = self.registry('project.project') cls.project_project = cls.registry('project.project')
self.project_task = self.registry('project.task') cls.project_task = cls.registry('project.task')
self.project_task_delegate = self.registry('project.task.delegate') cls.project_task_delegate = cls.registry('project.task.delegate')
# Find Project User group # Find Project User group
group_project_user_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'project', 'group_project_user') cls.group_project_user_id = cls.env.ref('project.group_project_user').id or False
self.group_project_user_id = group_project_user_ref and group_project_user_ref[1] or False
# Find Project Manager group # Find Project Manager group
group_project_manager_ref = self.registry('ir.model.data').get_object_reference(cr, uid, 'project', 'group_project_manager') cls.group_project_manager_id = cls.env.ref('project.group_project_manager').id or False
self.group_project_manager_id = group_project_manager_ref and group_project_manager_ref[1] or False
# Test partners to use through the various tests # Test partners to use through the various tests
self.project_partner_id = self.res_partner.create(cr, uid, { cls.project_partner_id = cls.res_partner.create(cr, uid, {
'name': 'Gertrude AgrolaitPartner', 'name': 'Gertrude AgrolaitPartner',
'email': 'gertrude.partner@agrolait.com', 'email': 'gertrude.partner@agrolait.com',
}) })
self.email_partner_id = self.res_partner.create(cr, uid, { cls.email_partner_id = cls.res_partner.create(cr, uid, {
'name': 'Patrick Ratatouille', 'name': 'Patrick Ratatouille',
'email': 'patrick.ratatouille@agrolait.com', 'email': 'patrick.ratatouille@agrolait.com',
}) })
# Test users to use through the various tests # Test users to use through the various tests
self.user_projectuser_id = self.res_users.create(cr, uid, { cls.user_projectuser_id = cls.res_users.create(cr, uid, {
'name': 'Armande ProjectUser', 'name': 'Armande ProjectUser',
'login': 'Armande', 'login': 'Armande',
'alias_name': 'armande', 'alias_name': 'armande',
'email': 'armande.projectuser@example.com', 'email': 'armande.projectuser@example.com',
'groups_id': [(6, 0, [self.group_employee_id, self.group_project_user_id])] 'groups_id': [(6, 0, [cls.group_employee_id, cls.group_project_user_id])]
}) })
self.user_projectmanager_id = self.res_users.create(cr, uid, { cls.user_projectmanager_id = cls.res_users.create(cr, uid, {
'name': 'Bastien ProjectManager', 'name': 'Bastien ProjectManager',
'login': 'bastien', 'login': 'bastien',
'alias_name': 'bastien', 'alias_name': 'bastien',
'email': 'bastien.projectmanager@example.com', 'email': 'bastien.projectmanager@example.com',
'groups_id': [(6, 0, [self.group_employee_id, self.group_project_manager_id])] 'groups_id': [(6, 0, [cls.group_employee_id, cls.group_project_manager_id])]
}) })
self.user_none_id = self.res_users.create(cr, uid, { cls.user_none_id = cls.res_users.create(cr, uid, {
'name': 'Charlie Avotbonkeur', 'name': 'Charlie Avotbonkeur',
'login': 'charlie', 'login': 'charlie',
'alias_name': 'charlie', 'alias_name': 'charlie',
'email': 'charlie.noone@example.com', 'email': 'charlie.noone@example.com',
'groups_id': [(6, 0, [])] 'groups_id': [(6, 0, [])]
}) })
self.user_projectuser = self.res_users.browse(cr, uid, self.user_projectuser_id) cls.user_projectuser = cls.res_users.browse(cr, uid, cls.user_projectuser_id)
self.user_projectmanager = self.res_users.browse(cr, uid, self.user_projectmanager_id) cls.user_projectmanager = cls.res_users.browse(cr, uid, cls.user_projectmanager_id)
self.partner_projectuser_id = self.user_projectuser.partner_id.id cls.partner_projectuser_id = cls.user_projectuser.partner_id.id
self.partner_projectmanager_id = self.user_projectmanager.partner_id.id cls.partner_projectmanager_id = cls.user_projectmanager.partner_id.id
# Test 'Pigs' project # Test 'Pigs' project
self.project_pigs_id = self.project_project.create(cr, uid, { cls.project_pigs_id = cls.project_project.create(cr, uid, {
'name': 'Pigs', 'name': 'Pigs',
'privacy_visibility': 'public', 'privacy_visibility': 'public',
'alias_name': 'project+pigs', 'alias_name': 'project+pigs',
'partner_id': self.partner_raoul_id, 'partner_id': cls.partner_raoul_id,
}, {'mail_create_nolog': True}) }, {'mail_create_nolog': True})
# Already-existing tasks in Pigs # Already-existing tasks in Pigs
self.task_1_id = self.project_task.create(cr, uid, { cls.task_1_id = cls.project_task.create(cr, uid, {
'name': 'Pigs UserTask', 'name': 'Pigs UserTask',
'user_id': self.user_projectuser_id, 'user_id': cls.user_projectuser_id,
'project_id': self.project_pigs_id, 'project_id': cls.project_pigs_id,
}, {'mail_create_nolog': True}) }, {'mail_create_nolog': True})
self.task_2_id = self.project_task.create(cr, uid, { cls.task_2_id = cls.project_task.create(cr, uid, {
'name': 'Pigs ManagerTask', 'name': 'Pigs ManagerTask',
'user_id': self.user_projectmanager_id, 'user_id': cls.user_projectmanager_id,
'project_id': self.project_pigs_id, 'project_id': cls.project_pigs_id,
}, {'mail_create_nolog': True}) }, {'mail_create_nolog': True})

View File

@ -19,7 +19,7 @@
# #
############################################################################## ##############################################################################
from openerp.addons.project.tests.test_project_base import TestProjectBase from .test_project_base import TestProjectBase
from openerp.exceptions import AccessError from openerp.exceptions import AccessError
from openerp.tools import mute_logger from openerp.tools import mute_logger

View File

@ -1,23 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Business Applications
# Copyright (c) 2012-TODAY OpenERP S.A. <http://openerp.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from . import test_survey

View File

@ -1,40 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Business Applications
# Copyright (c) 2014-TODAY OpenERP S.A. <http://openerp.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.tests import common
class test_survey(common.TransactionCase):
def setUp(self):
super(test_survey, self).setUp()
cr, uid, context = self.cr, self.uid, {}
pass
def test_00_create_survey_and_questions(self):
cr, uid, context = self.cr, self.uid, {}
pass
def test_01_fill_survey(self):
pass
def test_02_answer_survey(self):
pass

View File

@ -15,20 +15,21 @@ KARMA = {
} }
class TestForumCommon(common.TransactionCase): class TestForumCommon(common.SavepointCase):
def setUp(self): @classmethod
super(TestForumCommon, self).setUp() def setUpClass(cls):
super(TestForumCommon, cls).setUpClass()
Forum = self.env['forum.forum'] Forum = cls.env['forum.forum']
Post = self.env['forum.post'] Post = cls.env['forum.post']
# Test users # Test users
TestUsersEnv = self.env['res.users'].with_context({'no_reset_password': True}) TestUsersEnv = cls.env['res.users'].with_context({'no_reset_password': True})
group_employee_id = self.ref('base.group_user') group_employee_id = cls.env.ref('base.group_user').id
group_portal_id = self.ref('base.group_portal') group_portal_id = cls.env.ref('base.group_portal').id
group_public_id = self.ref('base.group_public') group_public_id = cls.env.ref('base.group_public').id
self.user_employee = TestUsersEnv.create({ cls.user_employee = TestUsersEnv.create({
'name': 'Armande Employee', 'name': 'Armande Employee',
'login': 'Armande', 'login': 'Armande',
'alias_name': 'armande', 'alias_name': 'armande',
@ -36,7 +37,7 @@ class TestForumCommon(common.TransactionCase):
'karma': 0, 'karma': 0,
'groups_id': [(6, 0, [group_employee_id])] 'groups_id': [(6, 0, [group_employee_id])]
}) })
self.user_portal = TestUsersEnv.create({ cls.user_portal = TestUsersEnv.create({
'name': 'Beatrice Portal', 'name': 'Beatrice Portal',
'login': 'Beatrice', 'login': 'Beatrice',
'alias_name': 'beatrice', 'alias_name': 'beatrice',
@ -44,7 +45,7 @@ class TestForumCommon(common.TransactionCase):
'karma': 0, 'karma': 0,
'groups_id': [(6, 0, [group_portal_id])] 'groups_id': [(6, 0, [group_portal_id])]
}) })
self.user_public = TestUsersEnv.create({ cls.user_public = TestUsersEnv.create({
'name': 'Cedric Public', 'name': 'Cedric Public',
'login': 'Cedric', 'login': 'Cedric',
'alias_name': 'cedric', 'alias_name': 'cedric',
@ -54,7 +55,7 @@ class TestForumCommon(common.TransactionCase):
}) })
# Test forum # Test forum
self.forum = Forum.create({ cls.forum = Forum.create({
'name': 'TestForum', 'name': 'TestForum',
'karma_ask': KARMA['ask'], 'karma_ask': KARMA['ask'],
'karma_answer': KARMA['ans'], 'karma_answer': KARMA['ans'],
@ -79,15 +80,15 @@ class TestForumCommon(common.TransactionCase):
'karma_gen_answer_accept': 9999, 'karma_gen_answer_accept': 9999,
'karma_gen_answer_accepted': 9999, 'karma_gen_answer_accepted': 9999,
}) })
self.post = Post.create({ cls.post = Post.create({
'name': 'TestQuestion', 'name': 'TestQuestion',
'content': 'I am not a bird.', 'content': 'I am not a bird.',
'forum_id': self.forum.id, 'forum_id': cls.forum.id,
'tag_ids': [(0, 0, {'name': 'Tag0', 'forum_id': self.forum.id})] 'tag_ids': [(0, 0, {'name': 'Tag0', 'forum_id': cls.forum.id})]
}) })
self.answer = Post.create({ cls.answer = Post.create({
'name': 'TestAnswer', 'name': 'TestAnswer',
'content': 'I am an anteater.', 'content': 'I am an anteater.',
'forum_id': self.forum.id, 'forum_id': cls.forum.id,
'parent_id': self.post.id, 'parent_id': cls.post.id,
}) })

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from openerp.addons.website_forum.tests.common import KARMA, TestForumCommon from .common import KARMA, TestForumCommon
from openerp.addons.website_forum.models.forum import KarmaError from ..models.forum import KarmaError
from openerp.exceptions import Warning, AccessError from openerp.exceptions import Warning, AccessError
from openerp.tools import mute_logger from openerp.tools import mute_logger

View File

@ -13,6 +13,7 @@ import select
import subprocess import subprocess
import threading import threading
import time import time
import itertools
import unittest2 import unittest2
import urllib2 import urllib2
import xmlrpclib import xmlrpclib
@ -171,6 +172,27 @@ class SingleTransactionCase(BaseCase):
cls.cr.close() cls.cr.close()
savepoint_seq = itertools.count()
class SavepointCase(SingleTransactionCase):
""" Similar to :class:`SingleTransactionCase` in that all test methods
are run in a single transaction *but* each test case is run inside a
rollbacked savepoint (sub-transaction).
Useful for test cases containing fast tests but with significant database
setup common to all cases (complex in-db test data): :meth:`~.setUpClass`
can be used to generate db test data once, then all test cases use the
same data without influencing one another but without having to recreate
the test data either.
"""
def setUp(self):
self._savepoint_id = next(savepoint_seq)
self.cr.execute('SAVEPOINT test_%d' % self._savepoint_id)
def tearDown(self):
self.cr.execute('ROLLBACK TO SAVEPOINT test_%d' % self._savepoint_id)
self.env.clear()
self.registry.clear_caches()
class RedirectHandler(urllib2.HTTPRedirectHandler): class RedirectHandler(urllib2.HTTPRedirectHandler):
""" """
HTTPRedirectHandler is predicated upon HTTPErrorProcessor being used and HTTPRedirectHandler is predicated upon HTTPErrorProcessor being used and