2010-03-28 31 views
8

Tôi muốn có một mô-đun python chứa một số bài kiểm tra đơn vị mà tôi có thể chuyển đến hg bisect --command.Làm thế nào để thiết lập và teardown tạm thời django db để kiểm tra đơn vị?

Các xét nghiệm đơn vị đang thử nghiệm một số chức năng của một ứng dụng django, nhưng tôi không nghĩ rằng tôi có thể sử dụng hg bisect --command manage.py test mytestappmytestapp sẽ phải được cho phép trong settings.py, và các chỉnh sửa để settings.py sẽ được clobbered khi hg bisect cập nhật thư mục làm việc.

Vì vậy, tôi muốn biết nếu cái gì đó như sau đây là cách tốt nhất để đi:

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() 

tôi nên biết ơn nhất nếu bạn có thể tư vấn cho một trong hai:

  1. Nếu có một cách đơn giản hơn, có lẽ là phân lớp django.test.TestCase nhưng không chỉnh sửa settings.py hoặc, nếu không;
  2. Những dòng ở trên có nội dung "Thiết lập db tạm thời django" và "Xé xuống tạm thời django db" phải không?

Trả lời

8

Nứt nó. Bây giờ tôi có một tệp python hoàn toàn độc lập với bất kỳ ứng dụng django nào có thể chạy thử nghiệm đơn vị với cơ sở dữ liệu thử nghiệm:

#!/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() 
+0

+1 để đăng giải pháp cuối cùng. –

+0

Cảm ơn. Tôi hy vọng rằng điều này cho thấy những người khác làm thế nào để thiết lập cơ sở dữ liệu kiểm tra django cho bất kỳ bài kiểm tra đơn vị tùy ý, bao gồm cả các bài kiểm tra mũi. – blokeley

5

Bạn phải sử dụng bộ kiểm tra nội bộ Django để làm như vậy.

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.') 

Nó hoàn toàn tương thích với unittest để mã của bạn không cần phải thay đổi nhiều.

Bạn có thể tìm hiểu thêm về các lệnh django.test, fixtures, flushloaddata.

Nếu bạn muốn sử dụng trang trí để thực hiện công việc, bạn có thể sử dụng call_command để sử dụng trong chương trình python của bạn bất kỳ lệnh django nào. ví dụ:

from django.core.management import call_command 

call_command('flush', 'myapp') 
call_command('loaddata', 'myapp') 
+0

Nếu tôi đặt mã của bạn vào tệp có tên mytest.py, tôi vẫn không thể chạy 'python mytest.py' để chạy các bài kiểm tra đơn vị, đó là những gì tôi cần. – blokeley

+1

@blokeley: Bạn có hai lựa chọn rõ ràng. Các thử nghiệm đi trong 'models.py' hoặc chúng đi trong' tests.py'. Nếu bạn sử dụng 'tests.py' thay vì' mytest.py' bạn sẽ thấy hạnh phúc. –

Các vấn đề liên quan