测试计划库python-时间和事件

假设我正在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.

上一篇:1335. Minimum Difficulty of a Job Schedule


下一篇:schedule