2009-06-11 29 views
21

Trong các thử nghiệm đơn vị tôi cần phải tải đồ đạc, như sau:Làm thế nào để tải đồ đạc chỉ một lần trong các bài kiểm tra đơn vị django?

class TestQuestionBankViews(TestCase): 

     # Load fixtures 
     fixtures = ['qbank'] 

     def setUp(self):       
      login = self.client.login(email="[email protected]",password="welcome")   


     def test_starting_an_exam_view(self):    
      candidate = Candidate.objects.get(email="[email protected]") 
      .......etc 


     def test_review_view(self): 
      self.assertTrue(True)    
      ......... 

     def test_review_view2(self): 
      self.assertTrue(True) 
      ......... 

Vấn đề:

Những đồ đạc đang tải cho mỗi thử nghiệm, tức là trước khi test_review_view, test_review_view2, vv ., như Django flushes cơ sở dữ liệu sau mỗi thử nghiệm.

Hành vi này gây ra các thử nghiệm mất nhiều thời gian để hoàn thành.

Làm cách nào để ngăn việc tải lịch thi đấu thừa này?

Có cách nào để tải đồ đạc trong setUp và tuôn ra khi lớp kiểm tra kết thúc, thay vì xả giữa mỗi lần kiểm tra?

+0

oh ......... tôi nghĩ rằng tôi có thể giải quyết vấn đề này bằng cách sử dụng lịch thi đấu intial_data và kế thừa "unittest.Testcase" thay vì "test.TestCase"? Bất kỳ suy nghĩ nào khác? –

Trả lời

3

Tôi đã gặp sự cố tương tự. Nói chung, không có một cách thực sự tốt để làm điều đó bằng cách sử dụng Á hậu thử nghiệm của django. Bạn có thể quan tâm đến điều này thread

Với điều đó được nói, nếu tất cả các testcases sử dụng cùng một vật cố định và chúng không sửa đổi dữ liệu theo bất kỳ cách nào, thì việc sử dụng dữ liệu ban đầu sẽ hoạt động.

+0

Cảm ơn con trỏ, & Có (tôi đã không nghĩ về điều này trước đây), chúng tôi chỉ có thể sử dụng intial_data nếu mọi trường hợp kiểm tra không sửa đổi cơ sở dữ liệu –

+0

. Tôi quyết định sử dụng unittest.TestCase với intial_data. Bất kỳ ý tưởng về làm thế nào để có được tất cả các tiện ích được cung cấp bởi django.test.TestCase? –

1

Tôi đã gặp phải sự cố tương tự một lần và kết thúc bằng việc viết nhân vật thử nghiệm của riêng mình. Trong trường hợp của tôi initial_data không đúng nơi như initial_data sẽ được tải trong thời gian syncdb, điều tôi không muốn. Tôi overrode setup_teardown_test_environment phương pháp để tải vật cố định tùy chỉnh của tôi trước khi bộ thử nghiệm được chạy và để loại bỏ nó sau khi thực hiện.

16

Sử dụng django-nose và một chút mã, bạn có thể thực hiện chính xác những gì bạn đã yêu cầu. Với django-mũi, bạn có thể có các chức năng thiết lập và đóng gói cho mỗi gói, mỗi mô-đun và từng lớp. Điều đó cho phép bạn tải đồ đạc của bạn trong một trong những chức năng thiết lập cao hơn và vô hiệu hóa việc đặt lại django.test.TestCase của đồ đạc giữa các bài kiểm tra.

Dưới đây là một ví dụ tập tin thử nghiệm:

from django.test import TestCase 
from django.core import management 

    def setup(): 
     management.call_command('loaddata', 'MyFixture.json', verbosity=0) 

    def teardown(): 
     management.call_command('flush', verbosity=0, interactive=False) 

    class MyTestCase(TestCase): 

     def _fixture_setup(self): 
      pass 

     def test_something(self): 
      self.assertEqual(1, 1) 

Chú ý rằng thiết lập và teardown nằm ngoài của lớp. Thiết lập sẽ được chạy trước tất cả các lớp thử nghiệm trong tệp này, và teardown sẽ được chạy sau tất cả các lớp thử nghiệm.

Bên trong lớp học, bạn sẽ thấy phương thức def _fixture_setup (tự). Điều này ghi đè chức năng đặt lại cơ sở dữ liệu ở giữa mỗi bài kiểm tra.

Hãy nhớ rằng nếu các bài kiểm tra của bạn viết bất kỳ thứ gì vào cơ sở dữ liệu, điều này có thể làm mất hiệu lực các bài kiểm tra của bạn. Vì vậy, bất kỳ thử nghiệm nào khác cần đồ đạc nạp lại cho mỗi thử nghiệm phải được đặt trong một tệp thử nghiệm khác.

+0

+1 cho giải pháp chức năng thực sự rời khỏi phòng theo cách tiếp cận khác với sử dụng initial_data.json/yaml. (Tôi sử dụng một lệnh quản lý tùy chỉnh và một kịch bản gọi là Django ORM, để tạo dữ liệu ban đầu của tôi. Điều này cho phép tôi tích hợp hoàn hảo.) Đây phải là câu trả lời được chấp nhận, nó đã giúp tôi rất nhiều! – hangtwenty

+1

Giải pháp tuyệt vời! Một điều mà tôi đã khám phá ra khá hữu ích. Nếu bạn không đặt phương thức _fixture_setup (self) def, và cho phép Django TestCase rớt xuống như bình thường, mọi thay đổi cơ sở dữ liệu được thực hiện trong một trường hợp thử nghiệm sẽ không ảnh hưởng đến trường hợp tiếp theo. Điều này là do khi bắt đầu một trường hợp thử nghiệm, một giao dịch cơ sở dữ liệu được bắt đầu, và trong giai đoạn rớt xuống, trường hợp kiểm tra sẽ thực hiện một phép khôi phục db để đặt lại trạng thái của cơ sở dữ liệu. Vì vậy, bỏ qua def _fixture_setup() sẽ cung cấp cho bạn các cược của cả hai thế giới! – LeeMobile

9

Hoặc sử dụng setUpModule:

def setUpModule(): 
    print 'Module setup...' 

def tearDownModule(): 
    print 'Module teardown...' 

class Test(unittest.TestCase): 
    def setUp(self): 
     print 'Class setup...' 

    def tearDown(self): 
     print 'Class teardown...' 

    def test_one(self): 
     print 'One' 

    def test_two(self): 
     print 'Two' 

in:

Creating test database for alias 'default'... 
Module setup... 
Class setup... 
One 
Class teardown... 
Class setup... 
Two 
Class teardown... 
Module teardown... 
+1

Điều này chỉ hoạt động nếu mọi thử nghiệm trên mô-đun sử dụng cùng một lịch thi đấu. Nói cách khác, nó buộc bạn phải đặt các bài kiểm tra trên một mô-đun nhất định bởi những gì họ sử dụng, thay vì những gì họ kiểm tra. –

0

django-mũi cung cấp một giải pháp readymade cho vấn đề này: chỉ cần phân lớp django_nose.FastFixtureTestCase.

Ngoài ra, django-mũi hỗ trợ ghép lịch thi đấu, có thể tăng tốc độ thử nghiệm của bạn chạy nhiều hơn bằng cách chỉ tải từng bộ đồ đạc duy nhất một lần cho mỗi lần chạy thử nghiệm. Sau khi đã được phân lớp FastFixtureTestCase khi thích hợp, hãy chạy thử nghiệm thử nghiệm django-nose bằng cách sử dụng tùy chọn --with-fixture-bundling.

Xem django-nose on pypi để biết thêm thông tin.

4

Nếu bạn không muốn cài đặt gói mới chỉ nhằm mục đích này, bạn có thể kết hợp Tom Wainwright's solutionmhost's solution.

Trong testfile của bạn, thêm các chức năng bên ngoài của bất kỳ lớp:

from django.core.management import call_command 

def setUpModule(): 
    call_command(
     'loaddata', 
     'path_to_fixture.json', 
     verbosity=0 
    ) 

def tearDownModule(): 
    call_command('flush', interactive=False, verbosity=0) 

Nếu bạn không muốn có những đồ đạc nạp vào cơ sở dữ liệu cho tất cả các trường hợp thử nghiệm, split the test into multiple files bằng cách tạo ra một thư mục mới trong ứng dụng gọi tests, thêm một __init__.py tập tin rỗng nói với Python rằng đây là một gói phần mềm, và thêm các tập tin thử nghiệm của bạn với tên tập tin bắt đầu với test, kể từ khi Á hậu sẽ tìm kiếm các file phù hợp với mô hình test*.py

3

đối với những gì nó có giá trị , và kể từ khi không có câu trả lời được chấp nhận, Django 1.8 bây giờ cung cấp chức năng này ra khỏi hộp - miễn là bạn đang sử dụng một cơ sở dữ liệu phụ trợ hỗ trợ các giao dịch.

Nó cũng thêm phương thức TestCase.setUpTestData() để tạo thủ công dữ liệu thử nghiệm một lần cho mỗi lớp TestCase.

Xem the Django 1.8 release notes.

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