假设我正在Ubuntu远程服务器上使用Schedule库每3天触发一次事件.
代码应类似于以下内容:
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)
如何加快时钟速度或测试此代码?
解决方法:
您可以用其他方法测试此代码,而不用花费时间.
显然,您可以为job()函数编写一个单元测试(即,确保它正在执行预期的操作).这对您来说可能很明显.您可能想知道如何测试主脚本将正确调用您的函数,但是在运行测试时不能确保它是10:30.
输入著名的“猴子补丁”.由于Python具有一流的函数,因此您可以简单地将名称绑定到函数.我不会涉及单元测试框架以及如何使用模拟库,但是这里有一个您可能正在寻找的快速示例:
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函数实际上已被调用!它只被调用一次,然后程序退出.原因是,我们只是将时间和调度模块中的函数名称重新绑定到我们的“模拟”版本(以使其更具可测试性).
编辑:我们甚至可以更疯狂地测试我们是否将正确的args传递给调度程序(我无法帮助自己):
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)
附言(这与您的问题无关紧要,但是您可能会发现它很有用):如果您希望将其合并到测试框架中,请签出模拟包,尤其是@patch装饰器.它使您可以在单元测试中猴子修补功能(或与此相关的任何功能).如果您还有其他测试,也不想调用exit().使用pytest退出特定的测试很容易,使用内置的unittest则比较困难,但是肯定可以.但是,我离题了.
HTH.