2

对于我正在开发的 PHP 应用程序,我需要读取当前的 git 修订版 SHA,当然我可以通过使用 shell_exec 或反引号来执行 git 命令行客户端轻松获得。

我显然已经把这个调用放到了它自己的方法中,这样我就可以很容易地为我的其余单元测试隔离和模拟它。所以我的课看起来有点像这样:

class Task_Bundle
{

    public function execute()
    {
        // Do things
        $revision = $this->git_sha();
        // Do more things
    }

    protected function git_sha()
    {
        return `git rev-parse --short HEAD`;
    }
}

当然,虽然我可以通过模拟 git_sha 来测试大部分课程,但我很难了解如何测试实际的 git_sha() 方法,因为我看不到为它创建已知状态的方法。我认为单元测试中没有任何真正的价值,它也要求git rev-parse比较结果?我想知道至少断言该命令已运行,但我看不到任何方法来获取 PHP 执行的 shell 命令的历史记录——即使我指定 PHP 应该使用 BASH 而不是 SH,历史列表也会出现空的,我想是因为单独的反引号执行是单独的终端会话。

我很想听听有关如何测试它的任何建议,或者是否可以不测试该方法并在将来维护应用程序时小心使用它?

4

3 回答 3

6

尽管您已经接受了答案,但让我发布一些关于单元测试应该如何工作的内容,因为即使发布的解决方案确实有效并且确实很好,它也有一些倒退。

首先,您不想实际执行您的命令,因为这会测试外部软件。从这一刻起,你就依赖于你无法控制的外部东西(如果我想在我的电脑上测试你的软件会发生什么?我必须安装 git 或任何 git-mock 吗?)。您真正想要做的是查看命令行命令是否正确并且执行良好。

正如我之前遇到的那样,这就是我所做的:我创建了一个执行 shell_exec 的类。在任何我想与 shell 交互的地方,我都会注入这个类并使用它。因此,为了进行测试,我可以模拟该类并查看是否执行了正确的方法以及是否设置了正确的参数。

这有很多好处:

  • 我有一点与外壳交互。如果将来有任何变化,或者如果我需要在执行命令之前做任何事情,我可以将行为添加到类中。PHP 函数封装得很好。
  • 它适用于每台 PC,即使 shell_exec 命令因任何原因不起作用。测试在每台电脑(开发机器、测试服务器、集成服务器)上执行,无需担心外部依赖。

当然,要验证您的软件是否可以作为一个整体运行,您必须进行不模拟任何内容的集成测试。但这是完全不同的情况。单元测试应该确保你的类(或方法)做它需要做的事情。有时这并不明确,因为您可能决定在某处使用真正的类,因为模拟它会导致大量开销。但是,就我而言,如果它依赖于可能未安装或由于某种原因可能无法工作的外部库/软件,它无论如何都不再是单元测试。

于 2012-04-15T19:50:25.020 回答
1

至少你可以做一些事情,比如检查返回的字符串是否匹配 /^[abcdef0-9]{7}$/

于 2012-04-14T23:29:11.583 回答
0

我想如果你真的想要,你可以写一个假人git并将它的位置添加到你环境的PATH. 让它做你需要做的任何验证,然后生成与真实事物一致的输出。如果你愿意,你甚至可以将它转发给真实的东西git,但是你不能保证结果。

但是,您必须小心....您希望做得足够好,以使班级可以被愚弄以为它是git真的你自己半途而废的 Git 版本。

于 2012-04-14T23:24:59.043 回答