gpt4 book ai didi

Django 测试 - InternalError : current transaction is aborted, 命令被忽略,直到事务 block 结束

转载 作者:行者123 更新时间:2023-11-29 11:55:59 26 4
gpt4 key购买 nike

在我的测试中,我不仅测试完美的情况,而且特别测试边缘情况和错误条件。所以我想确保一些唯一性约束起作用。

虽然我的测试和测试装置非常复杂,但我能够将问题追溯到以下示例,该示例不使用任何自定义模型。要重现该行为,只需将代码保存到tests.py 并运行django 测试运行程序即可。

from django.contrib.auth.models import User
from django.db import IntegrityError
from django.test import TransactionTestCase

class TransProblemTest(TransactionTestCase):
def test_uniqueness1(self):
User.objects.create_user(username='user1', email='<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c6b3b5a3b4f786a3bea7abb6aaa3e8a5a9ab" rel="noreferrer noopener nofollow">[email protected]</a>', password='secret')
self.assertRaises(IntegrityError, lambda :
User.objects.create_user(username='user1', email='<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="93e6e0f6e1a2d3f6ebf2fee3fff6bdf0fcfe" rel="noreferrer noopener nofollow">[email protected]</a>', password='secret'))

def test_uniqueness2(self):
User.objects.create_user(username='user1', email='<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c2b7b1a7b0f382a7baa3afb2aea7eca1adaf" rel="noreferrer noopener nofollow">[email protected]</a>', password='secret')
self.assertRaises(IntegrityError, lambda :
User.objects.create_user(username='user1', email='<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c6b3b5a3b4f786a3bea7abb6aaa3e8a5a9ab" rel="noreferrer noopener nofollow">[email protected]</a>', password='secret'))

具有单个测试方法的测试类可以工作,但如果有两个相同的方法实现,则会失败。第一个测试抛出异常破坏了 Django 测试环境并导致以下所有测试失败。

我正在使用 Django 1.1 和 Ubuntu 10.04、Postgres 8.4 和 psycopg2。

Django 1.2 中还存在这个问题吗?

这是一个已知的错误还是我遗漏了什么?

最佳答案

Django 有两种类型的 TestCase:“plain”TestCaseTransactionTestCasedocumentation关于两者的区别有以下几点:

TransactionTestCase and TestCase are identical except for the manner in which the database is reset to a known state and the ability for test code to test the effects of commit and rollback. A TransactionTestCase resets the database before the test runs by truncating all tables and reloading initial data. A TransactionTestCase may call commit and rollback and observe the effects of these calls on the database.

A TestCase, on the other hand, does not truncate tables and reload initial data at the beginning of a test. Instead, it encloses the test code in a database transaction that is rolled back at the end of the test.

您正在使用TransactionTestCase来执行这些测试。切换到普通的 TestCase,只要您维护现有的测试代码,您就会发现问题消失。

为什么会发生这种情况? TestCase 在事务 block 内执行测试方法。这意味着测试类中的每个测试方法将在单独的事务而不是同一事务中运行。当断言(或者更确切地说是内部的 lambda )引发错误时,它会随事务一起终止。下一个测试方法是在事务中执行的,因此您不会看到收到的错误。

但是,如果您在相同测试方法中添加另一个相同的断言,您将再次看到错误:

class TransProblemTest(django.test.TestCase):
def test_uniqueness1(self):
User.objects.create_user(username='user1', email='<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f085839582c1b09588919d809c95de939f9d" rel="noreferrer noopener nofollow">[email protected]</a>', password='secret')
self.assertRaises(IntegrityError, lambda :
User.objects.create_user(username='user1', email='<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="3f4a4c5a4d0e7f5a475e524f535a115c5052" rel="noreferrer noopener nofollow">[email protected]</a>', password='secret'))
# Repeat the test condition.
self.assertRaises(IntegrityError, lambda :
User.objects.create_user(username='user1', email='<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="9feaecfaedaedffae7fef2eff3fab1fcf0f2" rel="noreferrer noopener nofollow">[email protected]</a>', password='secret'))

这是因为第一个断言将创建一个导致事务中止的错误。因此第二个无法执行。由于两个断言都发生在同一测试方法内,因此与之前的情况不同,尚未启动新事务。

希望这有帮助。

关于Django 测试 - InternalError : current transaction is aborted, 命令被忽略,直到事务 block 结束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3601128/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com