2012-05-18 32 views
17

Tôi đã xây dựng hệ thống lập hóa đơn CMS + chi phí cho khách hàng và tôi cần phải kiểm tra nghiêm ngặt hơn.Mô phỏng thời gian bỏ qua

Tôi giữ tất cả dữ liệu của mình trong ORM Django và có một loạt tác vụ Celery chạy theo các khoảng thời gian khác nhau.

Ví dụ tôi muốn trở thành một thể chạy một bài kiểm tra đó:

  1. Tạo một người dùng mới và tạo ra một hóa đơn cho ngày X của quyền truy cập vào các trang web

  2. Mô phỏng các thông qua X + 1 ngày và chạy tất cả các tác vụ tôi đã thiết lập trong Celery.

  3. Kiểm tra xem hóa đơn mới cho một X ngày khác đã được phát hành cho người dùng hay chưa.

Cách tiếp cận KISS mà tôi đã thực hiện cho đến nay là thực hiện tất cả thử nghiệm trên máy riêng và thực sự thao tác ngày/giờ ở cấp hệ điều hành. Vì vậy, các kịch bản thử nghiệm sẽ:

  1. Thiết lập ngày hệ thống cho đến ngày 1

  2. Tạo một người dùng mới và tạo ra các hóa đơn đầu tiên cho ngày X tiếp cận

  3. Trước đó ngày hệ thống 1 ngày . Chạy tất cả các nhiệm vụ cần tây của tôi. Lặp lại cho đến khi X + 1 ngày đã "qua"

  4. Kiểm tra xem một hóa đơn mới đã được ban hành

Đó là một chút thời gian nhưng tôi nghĩ rằng nó có thể làm việc. Bất kỳ ý tưởng nào khác về cách hoàn thành nó?

Trả lời

17

Bạn có thể sử dụng mock để thay đổi giá trị trả về của hàm bạn sử dụng để nhận thời gian (ví dụ: datetime.datetime.now).

Có rất nhiều cách để làm như vậy (xem tài liệu giả), nhưng đây là một trong:

import unittest 
import datetime 
from mock import patch 

class SomeTestCase(unittest.TestCase): 
    def setUp(self): 
     self.time = datetime.datetime(2012, 5, 18) 
     class fakedatetime(datetime.datetime): 
      @classmethod 
      def now(cls): 
       return self.time 
     patcher = patch('datetime.datetime', fakedatetime) 
     self.addCleanup(patcher.stop) 
     patcher.start() 

    def test_something(self): 
     self.assertEqual(datetime.datetime.now(), datetime.datetime(2012, 5, 18)) 
     self.time = datetime.datetime(2012, 5, 20) 
     self.assertEqual(datetime.datetime.now(), datetime.datetime(2012, 5, 20)) 

Bởi vì chúng ta không thể thay thế trực tiếp datetime.datetime.now, chúng tôi tạo ra một lớp datetime giả mà làm mọi thứ cùng cách, ngoại trừ trả về một giá trị không đổi khi được gọi.

+0

Tôi gặp lỗi khi thực hiện việc này: TypeError: không thể đặt thuộc tính của kiểu mở rộng/mở rộng 'datetime.datetime'.Dấu vết: Traceback (cuộc gọi gần đây nhất): // Tệp "", dòng 1, trong // Tệp "/usr/lib/python2.7/dist-packages/mock.py", dòng 623, trong __enter__ // setattr (self.target, self.attribute, new_attr) – Alfe

+0

Xin lỗi, tôi quên điều đó. Gần đây tôi đã gặp vấn đề đó và tôi có một giải pháp. Chỉ cần cho tôi một vài phút và tôi sẽ cập nhật câu trả lời. – madjar

+0

Hmm, cũng không nhận được phiên bản đang chạy, xin lỗi. Sau khi gọi 'setUp()', kết quả của 'datetime.datetime.now()' không bị ảnh hưởng bởi việc thiết lập 'self.time'. Có lẽ tôi đang nhận được nó sai vẫn còn. – Alfe

4

Nếu không sử dụng thư viện mô phỏng đặc biệt, tôi đề xuất chuẩn bị mã để ở chế độ mô phỏng (có thể là do biến toàn cục). Trong chế độ giả lập thay vì gọi hàm thời gian bình thường (như time.time() hoặc bất kỳ thứ gì), bạn có thể gọi hàm thời gian mô phỏng trả về bất cứ thứ gì bạn cần trong trường hợp đặc biệt của bạn.

Tôi sẽ bỏ phiếu để thay đổi thời gian của hệ thống. Điều đó không có vẻ giống như một bài kiểm tra đơn vị mà là một bài kiểm tra chức năng vì nó không thể được thực hiện song song với bất kỳ thứ gì khác trên máy đó.

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