Skip to Content

Contributors

Odoo Test framework and rollback issue

Hi everyone,

I'm currently developing on 14.0 a test for one of my module and I'm having a headache trying to understand why an action is not properly rolled back after the exception is raised.

My code sample:
class TestSoftwareLicensePass(TransactionCase):
    def test_activation(self):
        ...
        self.assertEqual(pass_lic1.get_remaining_activation(), 1)
        with self.assertRaisesRegex(ValidationError, r"Max activation reached"):
            pass_lic1.activate("device_uuid_4/3")
        self.assertEqual(pass_lic1.get_remaining_activation(), 1)
        with self.assertRaisesRegex(ValidationError, r"Max activation reached"):
            pass_lic1.activate("device_uuid_4/3")

The second assertEqual statement FAILS because get_remaining_activation() returns 0, but since the exception has been correctly captured by the  with self.assertRaisesRegex statement, this part should have been rolled back by the odoo framework.
(and no cr.commit in the activate function)

Looking in other tests, I can see that a lot of with self.assert statements have a self.cr.savepoint() at their side (like this code sample in odoo/odoo/addons/base/tests/test_views.py):

class TestViewInheritance(ViewCase):   
    def test_no_recursion(self):
        r1 = self.makeView('R1')
        with self.assertRaises(ValidationError), self.cr.savepoint():
            r1.write({'inherit_id': r1.id})

Is this related to the TransactionCase class ? (Probably not, I made a test with SavepointCase and same issue)
Should I always append self.cr.savepoint() ?

Yann.

by Yann Papouin - 06:16 - 15 Nov 2023

Follow-Ups

  • Re: Odoo Test framework and rollback issue
    Thank you all for your feedback.

    So I will (when possible) try to split my tests and re-arrange their content so that the exception assertions are (is) processed at the very end.
    Anyway, I will always add the self.cr.savepoint() in the with context (looking at the Odoo 14.0 code, clear_upon_failure is automatically called by assertRaises).

    --
    Yann PAPOUIN


    Le ven. 17 nov. 2023 à 13:42, Pedro M. Baeza <notifications@odoo-community.org> a écrit :
    Holger Brunn has pointed to me that there's a way to recover properly in SavepointCase tests after a raise:


    You have to add the reset_on_failure to your `with` statement. And it seems that since v15, the savepoint is enough.

    Anyway, think twice about piling a lot of asserts in the same test, being raise or not, as having an early failure makes you to iterate several times until having a pass one, although testing flows is usual to have that sequential asserts.

    Thanks for the extra insights, Holger!

    Regards.

    _______________________________________________
    Mailing-List: https://odoo-community.org/groups/contributors-15
    Post to: mailto:contributors@odoo-community.org
    Unsubscribe: https://odoo-community.org/groups?unsubscribe


    by Yann Papouin - 02:51 - 23 Nov 2023
  • Re: Odoo Test framework and rollback issue
    Holger Brunn has pointed to me that there's a way to recover properly in SavepointCase tests after a raise:


    You have to add the reset_on_failure to your `with` statement. And it seems that since v15, the savepoint is enough.

    Anyway, think twice about piling a lot of asserts in the same test, being raise or not, as having an early failure makes you to iterate several times until having a pass one, although testing flows is usual to have that sequential asserts.

    Thanks for the extra insights, Holger!

    Regards.

    by Pedro M. Baeza - 01:41 - 17 Nov 2023
  • Re: Odoo Test framework and rollback issue
    Hi,

    In Odoo 14, you should append self.cr.savepoint() when you want to add additional tests after the assertRaises. It's required to restore the db cursor, the environment and the cache at the state prior to the exception. You should also question why you want to add additional tests after this assertion? Maybe they can be put into another specific test method. In Odoo 16 (at least), odoo overrides the assertRaises method to add the call to the savepoint and ensures a cleanup of the environment. https://github.com/odoo/odoo/blob/16.0/odoo/tests/common.py#L367

    Regards,

    lmi

    On Wed, Nov 15, 2023 at 6:24 PM Yann Papouin <notifications@odoo-community.org> wrote:
    Hi everyone,

    I'm currently developing on 14.0 a test for one of my module and I'm having a headache trying to understand why an action is not properly rolled back after the exception is raised.

    My code sample:
    class TestSoftwareLicensePass(TransactionCase):
        def test_activation(self):
            ...
            self.assertEqual(pass_lic1.get_remaining_activation(), 1)
            with self.assertRaisesRegex(ValidationError, r"Max activation reached"):
                pass_lic1.activate("device_uuid_4/3")
            self.assertEqual(pass_lic1.get_remaining_activation(), 1)
            with self.assertRaisesRegex(ValidationError, r"Max activation reached"):
                pass_lic1.activate("device_uuid_4/3")

    The second assertEqual statement FAILS because get_remaining_activation() returns 0, but since the exception has been correctly captured by the  with self.assertRaisesRegex statement, this part should have been rolled back by the odoo framework.
    (and no cr.commit in the activate function)

    Looking in other tests, I can see that a lot of with self.assert statements have a self.cr.savepoint() at their side (like this code sample in odoo/odoo/addons/base/tests/test_views.py):

    class TestViewInheritance(ViewCase):   
        def test_no_recursion(self):
            r1 = self.makeView('R1')
            with self.assertRaises(ValidationError), self.cr.savepoint():
                r1.write({'inherit_id': r1.id})

    Is this related to the TransactionCase class ? (Probably not, I made a test with SavepointCase and same issue)
    Should I always append self.cr.savepoint() ?

    Yann.

    _______________________________________________
    Mailing-List: https://odoo-community.org/groups/contributors-15
    Post to: mailto:contributors@odoo-community.org
    Unsubscribe: https://odoo-community.org/groups?unsubscribe


    by Laurent Mignon - 08:51 - 16 Nov 2023
  • Re: Odoo Test framework and rollback issue
    It's just a problem with how Odoo handles rollbacks and savepoints in tests. The thumb rule is to not do anything more after testing a raise. Do it in another test method.

    Regards.

    by Pedro M. Baeza - 07:47 - 15 Nov 2023