【问题标题】:How to test a scheduling program in php如何在php中测试调度程序
【发布时间】:2013-07-18 17:14:11
【问题描述】:

我有一个 codeigniter 应用程序,它可以在 mysql 数据库中为特定日期和时间安排事件,有时会提前几周,另一部分将在这些日期发生时发送电子邮件提醒并执行其他操作。一种方法是如何进行基于时间的测试?有没有我可以使用或阅读的测试套件?

【问题讨论】:

  • 创建一个为您的脚本提供时间并模拟它的类。
  • 如果没有其他帮助,请更改服务器上的系统日期。但是@zerkms 提出了更好的方法。
  • 或者您可以将时间范围降低到分钟。如果它在几分钟内工作,它在几个月内工作。保持简单。
  • Zerkms,你介意扩展一下吗?我对嘲笑不是很熟悉。
  • mock 只是意味着“假装”,即让服务器认为现在是执行脚本的正确时间。

标签: php mysql codeigniter


【解决方案1】:

这是我思考了很久的事情 - 然后我意识到我的问题!我专注于时间,好像它是我无法控制和衡量的。时间就像我们的应用程序中发生的任何其他计算一样。因此,基于时间的测试很容易——我们只需要改变思考方式——以及我们构建应用程序的方式。

首先,要做的第一件事是将当前的时间生成序列分离到一个方法中。这样,我们可以稍后模拟它(即生成我们自己的方法,该方法总是返回预定的“时间”进行测试)。这可以很简单,例如...

protected function _getCurrentTime()
{
     return time();
}

有什么好处:在我们的代码中,我们将调用它来获取当前时间来进行计算。但是,在测试中,我们总是可以生成完全相同的时间。

这很重要 - 我们总是可以每次都生成完全相同的时间。

现在,我不完全确定如何在您的特定应用程序中实现这一点,但让我解释一下“假”应用程序 - 看看您是否可以根据您的规范对其进行调整。

好的,首先,我们有一个方法可以在我们的数据库中放置一个条目,该条目是从现在起 3 周内的“提醒”。

这是旧代码

public function addReminderToDB()
{
    $this->_executeSQL('insert into mytable values (1,2,date_add(now(), interval 3 week))');
}

那么,我们如何测试呢?明明每次都不一样?

好吧,让我们分手吧。这是我们的新代码...

新代码

public function addReminderToDB()
{
    $currentDate = date('m-d-Y h:i:s', $this->_getCurrentTime());
    $sql = "insert into mytable values (1,2,date_add('{$currentDate}', interval 3 week))";
    $this->_executeSQL($sql);
 }

现在,当涉及到测试...您可以设置您的测试数据库。接下来,模拟 _getCurrentTime() 方法以始终返回您知道的整数。然后,运行 addReminderToDB() (它将使用您知道的整数)。最后,查询数据源以验证插入的行是否具有您期望的正确值。

我知道这与您的问题并不完全一致,但问题也有点模糊:-/ 祝您好运!

【讨论】:

  • 谢谢亚伦。我认为这是最完整的答案 - 比尔
【解决方案2】:

您是要运行单元测试来验证您的代码是否正常工作,还是要测试生产环境?

如果您想确保您的计划任务在生产中运行...我创建的任务每次成功完成执行时都会写入一个日志。

然后我们通过检查它是否已经运行来测试它(例如:测试“每日”任务是否在 36 小时内运行)。如果它们没有运行,我们会提醒管理员。

【讨论】:

  • 我希望有条理的方式来更改应用程序看到的日期和时间,以便测试基于时间的事件和应用程序产生的操作。
【解决方案3】:

您使用的是 Cron Jobs、PHP live Scripts 还是 JavaScript?有很多方法可以实现定时应用,每种方法都有自己的测试方法。

显然,无论您使用什么解决方案,正如其他人所提到的,您都可以简单地调整时间。将其更改为 1 分钟以确认您的脚本正在正确执行指定的功能。

一旦您确信您的脚本工作正常,您就可以在更长的时间内进行最终测试。还要确保您使用的是某种日志文件。当您尝试发现错误时,这将使生活变得更加轻松。

根据您使用的解决方案,您还可以像其他人提到的那样模拟测试数据库,但这取决于您实现目标的方式。

希望有帮助

【讨论】:

    【解决方案4】:

    我们在这里所做的是遍历所有表、所有列,如果它是日期/时间列之一,则从中减去所需时间:

        // $con is PDO connection
        // $interval can be eg. "5 DAY"
        $tables = $con->query('show tables');
        foreach($tables->fetchAll(PDO::FETCH_COLUMN) as $table) {
                $columns = $con->query(sprintf("show columns from %s where Type in ('date', 'datetime')", $table));
                $fields = array();
                foreach($columns->fetchAll(PDO::FETCH_ASSOC) as $field) {
                        $field = $field['Field'];
                        $fields[] = sprintf('%s = DATE_SUB(%s, INTERVAL %s)', $field, $field, $interval);
                }
                if ($fields) {
                        $q = sprintf('UPDATE %s SET %s', $table, implode(', ', $fields));
                        $con->query($q);
                }
        }
    

    然后像往常一样继续测试 - 原定 5 天后发生的事情,现在安排好了。

    【讨论】:

    • 有趣的想法 - 比尔
    猜你喜欢
    • 1970-01-01
    • 2016-07-29
    • 2021-10-03
    • 2020-03-16
    • 1970-01-01
    • 2011-07-28
    • 2011-10-16
    • 2022-08-05
    • 2011-06-21
    相关资源
    最近更新 更多