2011-08-05 30 views
34

Tôi đang viết một ứng dụng django có thể tái sử dụng và tôi cần đảm bảo rằng các mô hình của nó chỉ được đồng bộ hóa khi ứng dụng ở chế độ thử nghiệm. Tôi đã cố gắng sử dụng một DjangoTestRunner tùy chỉnh, nhưng tôi không tìm thấy ví dụ về làm thế nào để làm điều đó (tài liệu chỉ cho thấy làm thế nào để xác định một Á hậu thử nghiệm tùy chỉnh).Phát hiện chế độ thử nghiệm django

Vì vậy, không ai có ý tưởng về cách thực hiện?

EDIT

Đây là cách tôi đang làm nó:

#in settings.py 
import sys 
TEST = 'test' in sys.argv 

Hy vọng nó giúp.

+0

Tuyên bố từ chối trách nhiệm: Tôi ở đây vì tôi có cùng yêu cầu. Tuy nhiên, tôi chỉ muốn chỉ ra rằng có mã của bạn hoạt động khác nhau khi một thử nghiệm đang chạy là một thực sự bi NO-NO. Càng nhiều càng tốt, bạn muốn kiểm tra mã theo cách nó thực sự hoạt động. – brianmearns

+0

Bản sao có thể có của [django - cách phát hiện môi trường thử nghiệm] (http://stackoverflow.com/questions/4088253/django-how-to-detect-test-environment) –

Trả lời

38

Tôi nghĩ câu trả lời cung cấp ở đây https://stackoverflow.com/a/7651002/465673 là một cách sạch hơn để làm việc đó:

Đặt này trong settings.py của bạn:

import sys 

TESTING = sys.argv[1:2] == ['test'] 
+20

Hôm nay tôi đang theo một cách tiếp cận tương tự: 'TEST = 'test' trong sys.argv' Cùng một hiệu ứng, nhưng sạch hơn một chút để đọc :-) –

+2

@jjmaestro là có bất kỳ lý do gì để không viết' KIỂM TRA = sys.argv [1] == 'test''. Tôi nghĩ rằng nó chính xác và đơn giản hơn – glarrain

+5

@glarrain: sử dụng một slice (như trong '[1: 2]') có nghĩa là bạn sẽ không nhận được một chỉ mục ngoài lỗi giới hạn nếu thay đổi 'sys.argv' có ít hơn hai các yếu tố trong đó. – brianmearns

19

Không hoàn toàn chắc chắn về trường hợp sử dụng của bạn, nhưng một trong những cách tôi đã nhìn thấy để phát hiện khi các bộ kiểm tra đang chạy là để kiểm tra xem django.core.mail đã một outbox thuộc tính như:

from django.core import mail 

if hasattr(mail, 'outbox'): 
    # We are in test mode! 
    pass 
else: 
    # Not in test mode... 
    pass 

này do được bổ sung bởi vận động viên thử nghiệm Django ở setup_test_environment và bị xóa trong teardown_test_environment. Bạn có thể kiểm tra nguồn gốc ở đây: https://code.djangoproject.com/browser/django/trunk/django/test/utils.py

Sửa: Nếu bạn muốn mô hình được xác định để thử nghiệm chỉ sau đó bạn nên kiểm tra Django ticket #7835 nói riêng comment #24 phần trong số đó là đưa ra dưới đây:

Rõ ràng bạn chỉ có thể xác định mô hình trực tiếp trong tests.py của bạn. Syncdb không bao giờ nhập tests.py, vì vậy các mô hình đó sẽ không được đồng bộ hóa với db bình thường , nhưng chúng sẽ được đồng bộ hóa với cơ sở dữ liệu thử nghiệm và có thể là được sử dụng trong các thử nghiệm.

+0

Nó không phải là cách thông thường. Nhưng tôi nghĩ nó sẽ hoạt động. Tôi đã nhìn thấy mã này bên trong lõi của django nhưng tôi nghĩ rằng nó sẽ có một giải pháp "cụ thể" hơn. Về trường hợp sử dụng: ứng dụng tôi đang viết sử dụng một số biến thể của mô hình và trường biểu mẫu. Vì vậy, tôi cần các mô hình làm việc chỉ trong chế độ thử nghiệm để có một phạm vi kiểm tra tốt; Ứng dụng này là mã nguồn mở và bạn có thể nhìn thấy nó ở đây: https://github.com/herberthamaral/django-jqgrid –

+1

Ah có ngay bây giờ tôi hiểu những gì bạn đang yêu cầu. Tôi đã cập nhật câu trả lời của mình để bao gồm các mô hình chỉ thử nghiệm xử lý. Tôi có một trường hợp sử dụng tương tự trong một trong các bộ thử nghiệm của dự án của tôi: https://bitbucket.org/mlavin/django-selectable –

+0

Cảm ơn bạn rất nhiều, Mark. Đây là một tài nguyên rất hữu ích và tôi nghĩ rằng nó nên đi trên doc của Django. –

36

Câu trả lời được lựa chọn là một hack lớn. :)

Một bản hack nhỏ hơn sẽ là tạo lớp con TestSuiteRunner của riêng bạn và thay đổi cài đặt hoặc thực hiện bất kỳ thứ gì bạn cần cho phần còn lại của ứng dụng. Bạn chỉ định người thử nghiệm trong cài đặt của mình:

TEST_RUNNER = 'your.project.MyTestSuiteRunner' 

Nói chung, bạn không muốn làm điều này, nhưng nó hoạt động nếu bạn thực sự cần.

from django.conf import settings 
from django.test.simple import DjangoTestSuiteRunner 

class MyTestSuiteRunner(DjangoTestSuiteRunner): 
    def __init__(self, *args, **kwargs): 
     settings.IM_IN_TEST_MODE = True 
     super(MyTestSuiteRunner, self).__init__(*args, **kwargs) 

LƯU Ý: Khi Django 1.8, DjangoTestSuiteRunner không được dùng nữa. Bạn nên sử dụng DiscoverRunner thay vì:

from django.conf import settings 
from django.test.runner import DiscoverRunner 


class MyTestSuiteRunner(DiscoverRunner): 
    def __init__(self, *args, **kwargs): 
     settings.IM_IN_TEST_MODE = True 
     super(MyTestSuiteRunner, self).__init__(*args, **kwargs) 
+0

Điều đó nên làm các thủ thuật, nhưng tôi là tất cả cho các giải pháp đơn giản :-) –

+2

Tôi thích cách tiếp cận này, nhưng lưu ý rằng mã này sẽ chạy sau khi mã khác của bạn đã được nhập khẩu. Vì vậy, nếu bạn cần phát hiện điều kiện trong mã cấp mô-đun, điều này sẽ không hoạt động. –

+1

Sửa đổi 'django.conf.settings' được khuyến khích mạnh mẽ bởi tài liệu Django, xem: https://docs.djangoproject.com/en/1.11/topics/settings/#altering-settings-at-runtime –

5

Tôi đang sử dụng ghi đè settings.py. Tôi có một settings.py toàn cầu, chứa hầu hết mọi thứ, và sau đó tôi có ghi đè cho nó.Mỗi tệp cài đặt bắt đầu bằng:

from myproject.settings import settings 

và sau đó tiếp tục ghi đè một số cài đặt.

  • prod_settings.py - thiết lập sản xuất (ví dụ như ghi đè DEBUG = False)
  • dev_settings.py - thiết lập phát triển (ví dụ như khai thác gỗ hơn)
  • test_settings.py

Và sau đó tôi có thể xác định UNIT_TESTS = Sai trong settings.py cơ sở, và ghi đè lên UNIT_TESTS = True trong test_settings.py.

Sau đó, bất cứ khi nào tôi chạy lệnh, tôi cần quyết định cài đặt nào sẽ chạy với (ví dụ: DJANGO_SETTINGS_MODULE=myproject.test_settings ./manage.py test). Tôi thích sự rõ ràng đó.

+0

Đẹp và rõ ràng, điều này là cách tôi làm điều đó. Bạn cũng có thể làm bài kiểm tra DJANGO_ENV = test ./manage.py và chọn bằng sys.env trong mã của bạn. –

+0

Hôm nay đây là lựa chọn của tôi về sự lựa chọn =) –

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