测试时间表库 python - 时间和事件

Jua*_*ano 5 python ubuntu schedule

假设我正在 Ubuntu 远程服务器上使用计划库每 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)
Run Code Online (Sandbox Code Playgroud)

如何加快时钟速度或测试此代码?

Mat*_*ith 3

您可以用不同的方式测试此代码,而不是伪造时钟。

显然,您可以为该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)
Run Code Online (Sandbox Code Playgroud)

那么这是怎么回事呢?如果运行代码片段,您会注意到该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)
Run Code Online (Sandbox Code Playgroud)

PS(这与您的问题有些无关,但您可能会发现它很有用):如果您希望将其合并到测试框架中,请查看包mock,特别是@patch装饰器。它允许您在单元测试(或与此相关的任何函数)内对函数进行猴子修补。exit()如果您还有其他测试,您也不想打电话。使用 退出特定测试很容易pytest,使用内置的则有点困难unittest,但肯定是可能的。但是,我离题了。

HTH。