2015-04-03 13 views
25

Django 1.8 được vận chuyển với a refactored TestCase cho phép khởi tạo dữ liệu ở cấp lớp bằng cách sử dụng giao dịch và điểm lưu trữ thông qua phương thức setUpTestData(). Điều này trái ngược với số setUp() của unittest chạy trước mỗi phương pháp thử nghiệm duy nhất.Django setUpTestData() so với setUp()

Câu hỏi: Trường hợp sử dụng cho setUp() ở Django hiện tại là setUpTestData() tồn tại là gì?

Tôi chỉ tìm câu trả lời khách quan, cấp cao, nếu không thì câu hỏi này sẽ quá rộng đối với Stack Overflow.

Trả lời

20

Không có gì lạ khi có mã thiết lập không thể chạy dưới dạng phương thức lớp. Một ví dụ đáng chú ý là Django test client: bạn có thể không muốn sử dụng lại cùng một cá thể ứng dụng trên các thử nghiệm mà nếu không chia sẻ nhiều dữ liệu giống nhau, và thực sự, các cá thể khách hàng sẽ tự động được bao gồm trong các lớp con củacủa Django là created per test method thay vì cho toàn bộ lớp . Giả sử bạn đã có một bài kiểm tra từ 1,8 thế giới trước Django với một phương pháp setUp như thế này:

 
    def setUp(self): 
     self.the_user = f.UserFactory.create() 
     self.the_post = f.PostFactory.create(author=self.the_user) 
     self.client.login(
      username=self.the_user.username, password=TEST_PASSWORD 
     ) 
     # ... &c. 

Bạn có thể bị cám dỗ để hiện đại hóa các trường hợp thử nghiệm bằng cách thay đổi setUp để setUpTestData, tát một decorator @classmethod trên đầu trang, và thay đổi tất cả số self s đến cls. Nhưng điều đó sẽ thất bại với AttributeError: type object 'MyTestCase' has no attribute 'client'! Thay vào đó, bạn nên sử dụng setUpTestData cho dữ liệu được chia sẻ và setUp cho khách hàng mỗi thử nghiệm phương pháp:

 
    @classmethod 
    def setUpTestData(cls): 
     cls.the_user = f.UserFactory.create() 
     cls.the_post = f.PostFactory.create(author=cls.the_user) 
     # ... &c. 

    def setUp(self): 
     self.client.login(
      username=self.the_user.username, password=TEST_PASSWORD 
     ) 
+1

Đáng giá thêm một số chi tiết khác từ phương pháp này https://makina-corpus.com/blog/metier/2015/how-to-optimize-django-unit-tests-with-setuptestdata. Nếu bạn có dữ liệu thử nghiệm thay đổi theo từng thử nghiệm, bạn vẫn có thể tạo các mô hình có thể thay đổi trong 'setUpTestData', miễn là bạn thực hiện' self.model.refresh_from_db() 'trong' setUp' của bạn. Các thay đổi từ một TC được cuộn lại, nhưng không có bước thủ công đó, tệp self.model sẽ tham chiếu đến dữ liệu của lần chạy trước đó. Với bước thiết lập, bạn làm một đọc cho mỗi trường hợp thử nghiệm, nhưng thường là nhanh hơn so với làm một viết cho mỗi trường hợp thử nghiệm. – Symmetric

4

Caches vấn đề này. Ngay cả khi Django được tốt hơn trong việc cung cấp cô lập thử nghiệm với rollback giao dịch, cache vẫn được tạo ra và xóa bằng tay.

[edit]: SetUpTestData xác định trạng thái DB sẽ được khôi phục sau mỗi lần kiểm tra và thực hiện như vậy với phương thức chỉ được thực hiện một lần, hoàn nguyên giao dịch phía sau bức màn của Django. Điều này không làm việc cho cache. Nếu bạn muốn bộ nhớ cache giống nhau cho mỗi bài kiểm tra, bạn cần phải đặt lại bộ nhớ đệm giữa mỗi bài kiểm tra, do đó cần thiết lập. Django có thể khôi phục DB nhưng không thể khôi phục mọi thứ.

(Cảm ơn bạn bryan-oakley cho gợi ý)

+0

Điều này dường như không trả lời được câu hỏi đã được hỏi. –

+0

SetUpTestData xác định trạng thái DB sẽ được khôi phục sau mỗi lần kiểm tra và thực hiện như vậy với một phương thức chỉ được thực hiện một lần, giao diện rollback được thực hiện phía sau bức màn của Django. Điều này không làm việc cho cache. Nếu bạn muốn bộ nhớ cache giống nhau cho mỗi bài kiểm tra, bạn cần phải đặt lại bộ nhớ đệm giữa mỗi bài kiểm tra, do đó cần thiết lập. Django có thể khôi phục DB nhưng không thể khôi phục mọi thứ. –

+0

Bạn nên đưa ra nhận xét của mình một phần câu trả lời, bởi vì nó làm cho câu trả lời dễ hiểu hơn nhiều. –

2

Taken từ thử nghiệm hướng dẫn này: https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Testing#Views

setUpTestData() được gọi một lần vào đầu chạy thử nghiệm cho các thiết lập lớp cấp. Bạn sẽ sử dụng điều này để tạo các đối tượng sẽ không bị sửa đổi hoặc thay đổi trong bất kỳ phương thức thử nào.

setUp() được gọi trước mọi chức năng kiểm tra để thiết lập bất kỳ đối tượng nào có thể được sửa đổi bởi kiểm tra (mọi chức năng kiểm tra sẽ nhận được phiên bản "mới" của các đối tượng này).

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