Как установить и разрушение временный django дб для поблочного тестирования?

Я хотел бы иметь модуль Python, содержащий некоторые модульные тесты, которым я могу передать hg bisect --command.

Модульные тесты тестируют некоторую функциональность django приложения, но я не думаю, что могу использовать hg bisect --command manage.py test mytestapp потому что mytestapp должен был бы быть включен в settings.py, и редактирования к settings.py будут ударены когда hg bisect обновляет рабочий каталог.

Поэтому я хотел бы знать - ли что-то как следующее лучший способ пойти:

import functools, os, sys, unittest

sys.path.append(path_to_myproject)
os.environ['DJANGO_SETTINGS_MODULE'] = 'myapp.settings'


def with_test_db(func):
    """Decorator to setup and teardown test db."""
    @functools.wraps
    def wrapper(*args, **kwargs):
        try:
            # Set up temporary django db
            func(*args, **kwargs)
        finally:
            # Tear down temporary django db


class TestCase(unittest.TestCase):

    @with_test_db
    def test(self):
        # Do some tests using the temporary django db
        self.fail('Mark this revision as bad.')


if '__main__' == __name__:
    unittest.main()

Я должен быть крайне признательным, если Вы могли бы советовать также:

  1. Если существует более простой путь, возможно, разделяя на подклассы django.test.TestCase но не редактируя settings.py или, если нет;
  2. То, что строки, выше которых говорят "Настроенный временный django дб" и, "Разъединяют временный django дб", должно быть?
9
задан blokeley 28 March 2010 в 15:41
поделиться

2 ответа

Взломал его. Теперь у меня есть один файл python, полностью независимый от любого приложения django, которое может выполнять модульные тесты с тестовой базой данных:

#!/usr/bin/env python
"""Run a unit test and return result.

This can be used with `hg bisect`.
It is assumed that this file resides in the same dir as settings.py

"""

import os
from os.path import abspath, dirname
import sys
import unittest

# Set up django
project_dir = abspath(dirname(dirname(__file__)))
sys.path.insert(0, project_dir)
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'

from django.db import connection
from django.test import TestCase
from django.test.utils import setup_test_environment, teardown_test_environment

from myproject import settings
from myproject.myapp.models import MyModel


class MyTestCase(TestCase):

    def test_something(self):
        # A failed assertion will make unittest.main() return non-zero
        # which if used with `hg bisect` will mark the revision as bad
        self.assertEqual(0, len(MyModel.objects.all())) # and so on


if '__main__' == __name__:
    try:
        setup_test_environment()
        settings.DEBUG = False    
        verbosity = 0
        old_database_name = settings.DATABASE_NAME
        connection.creation.create_test_db(verbosity)
        unittest.main()
    finally:
        connection.creation.destroy_test_db(old_database_name, verbosity)
        teardown_test_environment()
10
ответ дан 4 December 2019 в 13:46
поделиться

Вы должны использовать внутренний Django TestCase для этого.

from django.test import TestCase

class TestCase(TestCase):

    # before every call to setUp(), the db is automatically 
    # set back to the state is was after the first syncdb then
    # all these fixture files will be loaded in the db   
    fixtures = ['mammals.json', 'birds']

    # put whatever you want here, you don't need to call the
    # super()
    def setUp(self):
        # Test definitions as before.
        call_setup_methods()

    def test(self):
        # Do some tests using the temporary django db
        self.fail('Mark this revision as bad.')

Он полностью совместим с unittest, поэтому ваш код не нужно сильно менять.

Вы можете узнать больше о командах django.test, fixtures , flush и loaddata .

Если вы действительно хотите использовать декоратор для выполнения этой работы, вы можете использовать call_command , чтобы использовать в вашей программе Python любую команду django. например:

from django.core.management import call_command

call_command('flush', 'myapp')
call_command('loaddata', 'myapp')
5
ответ дан 4 December 2019 в 13:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: