2016-12-17 60 views
3

假設我使用Ubuntu遠程服務器上的計劃庫每3天觸發一個事件。測試計劃庫python - 時間和事件

代碼看起來應該與此類似:

import schedule 
import time 

def job(): 
    print("I'm working...") 

schedule.every(3).days.at("10:30").do(job) 

while True: 
    schedule.run_pending() 
    time.sleep(1) 

我怎樣才能加快我的時鐘或測試該代碼?

回答

2

而不是僞造時鐘,您可以以不同的方式測試此代碼。

顯然你可以爲job()函數編寫單元測試(即確保它正在做它應該做的)。這可能很明顯。您可能想知道如何測試主腳本將正確調用您的函數,但在運行測試時無法確保它是10:30。

輸入着名的「猴子補丁」。由於Python具有頭等功能,因此可以簡單地將名稱綁定到函數。我不打算進入的單元測試框架以及如何使用mock庫,但這裏的你可能會尋找一個簡單的例子:

import schedule 
import time 

def mock_run_pending(): 
    job() 

def mock_time_sleep(num): 
    exit() 

schedule.run_pending = mock_run_pending 
time.sleep = mock_time_sleep 

def job(): 
    print("I'm working...") 

schedule.every(3).days.at("10:30").do(job) 

while True: 
    schedule.run_pending() 
    time.sleep(1) 

所以這是怎麼回事呢?如果您運行代碼片段,您會注意到job函數實際上被稱爲!它只被調用一次,然後程序退出。原因是,我們只是將timeschedule模塊中的函數名稱重新命名爲我們的「模擬」版本(以使它們更易於測試)。

編輯:我們可以去更瘋狂和測試,我們通過在適當的參數傳遞給調度程序(我情不自禁):

import schedule 
import time 

class MockEvery(object): 
    def __init__(self, num): 
     assert(num == 3) 
     self.days = MockDays() 

class MockDays(object): 
    def __init__(self): 
     pass 

    def at(self, time): 
     assert(time == "10:30") 
     return MockAt() 

class MockAt(object): 
    def __init__(self): 
     pass 

    def do(self, func): 
     assert(func == job) 

def mock_every(num): 
    return MockEvery(num) 

def mock_run_pending(): 
    job() 

def mock_time_sleep(num): 
    exit() 

schedule.run_pending = mock_run_pending 
time.sleep = mock_time_sleep 
schedule.every = mock_every 

def job(): 
    print("I'm working...") 

schedule.every(3).days.at("10:30").do(job) 

while True: 
    schedule.run_pending() 
    time.sleep(1) 

附: (這與您的問題有些不相干,但您可能會發現它很有用):如果您希望將其納入測試框架,請查看mock包,特別是@patch裝飾器。它允許你在一個單元測試(或任何功能)中使用補丁函數。如果您有其他測試,您也不想撥打exit()。使用pytest退出特定測試很容易,但使用內置的unittest有點困難,但當然可以。但是,我離題了。

HTH。