簡體   English   中英

Django pytest:在運行測試用例后清除數據庫

[英]Django pytest: Clear DB after a running a test case

我有一個測試(django pytest),需要測試數據庫中的對象。 問題是在測試之后,數據庫“臟了”,其他測試失敗了。 我看到了一些有關TransactionTestCase的信息,但我不明白它如何與Django測試一起使用。

這是我當前代碼的一個簡單示例:

@pytest.mark.django_db
def test_something(mock_my_obj):
    mock_my_obj.save()
    # test test test
    ...
    # I don't want to delete the obj here...

更新:第二次嘗試:我讀到TestCase應該使用事務並將其回滾到每個測試。 不為我工作:

from django.test import TestCase

class MyTests(TestCase):
    def test_yair_a(self):
        print 'AAAAAAA'
        print Account.objects.all()
        Account.objects.create(account_id=1,account_name='1')
        print Account.objects.all()

    def test_yair_b(self):
        print 'BBBBBBBB'
        print Account.objects.all()
        Account.objects.create(account_id=2,account_name='2')
        print Account.objects.all()

結果(有趣的部分):

> py.test -s -v -k test_yair
AAAAAAA
[]
[<Account: 1>]
PASSED

BBBBBBBB
[<Account: 1>]
[<Account: 1>, <Account: 2>]
PASSED

這意味着在test_a的末尾沒有事務回滾。

問題在於,默認情況下,django在默認數據庫上創建一個事務。 我需要另一個數據庫上的事務。 這是我的設置文件:

ROOT_PASS = 'ohnoyoudidnt'
ROOT_USER = 'root'
ROOT_HOST = 'localhost'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'default_db',
        'USER': ROOT_USER,
        'PASSWORD': ROOT_PASS,
        'HOST': ROOT_HOST,
        'PORT': '3306',
    },
    'my_app': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'my_app_db',
        'USER': ROOT_USER,
        'PASSWORD': ROOT_PASS,
        'HOST': ROOT_HOST,
        'PORT': '3306'
    },

為了解決這個問題,需要使用transaction.atomic(using='my_app')塊,並向其中拋出錯誤以進行回滾。 自然,我想為此編寫一個裝飾器,但是與pytest一起使用它並沒有我最初想到的那么簡單,因為pytest本身會在代碼之前(使用模擬和補丁時)操縱該方法。

花了幾個小時后,我得到了這個可以使用的裝飾器!

from decorator import decorator
import pytest
from django.db import transaction


class TestTempException(Exception):
    pass


def testing_w_transaction(using):
    def testing_w_transaction_inner(function):
        def func_wrapper(f, *args, **kwargs):
            try:
                with transaction.atomic(using=using):
                    f(*args, **kwargs)
                    raise TestTempException()
            except TestTempException:
                pass
        return decorator(func_wrapper, pytest.mark.django_db(function))
    return testing_w_transaction_inner

用法:

@testing_w_transaction(using='my_app')
def test_my_method(mock_object, ...):
     # test test test

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM