TDD - 以与实现中使用的方式不同的方式检查方法的正确性

时间:2014-10-24 15:49:31

标签: java testing tdd

我正试图摆脱在编写测试时经常发生在我身上的情况。

示例场景是这样的:我有这个类Vagrant,它抽象了我在项目根目录中配置的Vagrant虚拟机(Vagrantfile)。在这个非常简单的情况下,这个类只有方法start()和方法isRunning()或者getStatus(),它没有任何区别。

测试应该是这样的:

@Test
public void daemonIsSuccessfullyInstalled()
{
    Vagrant vm = new Vagrant();
    vm.start();

    // todo: here I want to test that the Vagrant vm is actually running.

    assertTrue(vm.isRunning());
    // or
    assertEquals(vm.getStatus(), "running");
}

使用vm.start()启动VM后,我想检查虚拟机是否实际运行。为此,我可以简单地运行Runtime.getRuntime().exec("vagrant status")并使用正则表达式解析输出以提取状态。

但是,这是我计划在方法getStatus()isRunning()的实施中执行的操作。但是,在测试中使用相同的技术检查start()方法的正确性是否有意义?

换句话说,我的问题是我将使用相同的代码(或相同的逻辑,无论用于实现它的实际代码)来检查方法start()是否正常工作,如我用来实现方法isRunning()的那个。现在我应该如何检查此代码是否正确?我是否应该确信这个逻辑是正确的,也就是说我应该放弃测试一些方法,假设它们是正确的呢?

或者,我是否应该努力寻找另一种解耦的方法来检查VM是否正在运行(可能正在查看ps或其他内容),以避免在测试和实现中使用相同的代码?在我看来,这就像编写一个使用+运算符计算总和的方法,然后使用相同的+运算符检查方法的输出是否正确。如果+运算符被错误怎么办?

非常感谢。

编辑:忘记提及测试标题所指的内容。我想测试一个守护程序在系统启动时正确启动,在vm中,并且在我看来“vm已启动”测试应该只是一个小小的测试,但它产生了问题。顺便说一句,也许我应该在这个特定问题中使用不同的名称作为测试方法。另外,感谢Carl Manaster提出的建议。

2 个答案:

答案 0 :(得分:1)

使用TDD原则开始工作的人经常遇到这个问题。

当测试像你这样的东西(执行东西,特定于运行时),建立数据库连接,或者最常见的时候会发生这个问题:文件i / o。

但真正的问题不是如何测试这个,而是你测试这些方法。

单元测试意味着快速运行。非常快。应该是系统独立的,不应该执行任何i / o操作!

单元测试应测试算法,数据处理等,不应执行i / o。

但您可能想知道如何测试i / o操作呢?不是单元测试而是集成测试 - 但这本身就是一个故事。

但是你应该测试你的Vagrant课程,而不是你的 Vagrant课程,让我感到困惑,但要忍受我!

您的Vagrant课程应该像代理人一样。它处理vm和命令以发送到运行时。 Bur不应该送他们!要发送它们,您的Vagrant课程可以使用专用课程,例如CommandRunner。这个类应该是可注入的(Keyword:DependencyInjection)。这也意味着CommandRunner应该是一个接口(不是必需的,但会使事情变得更容易!)并且基本实现可以UnixCommandRunner(您看到这允许在Windows机器上运行命令!)

这允许你模拟(google,如果你之前没有听说过),这基本上是用一个交换一个真实的CommandRunner,什么都不做(除了记录对它的方法的调用等等)。 )。但您可以通过调用MockCommandRunner存储方法来检查命令是否已运行,您可以在测试中检索它!

我希望这给你一个基本的想法,关于如何在单元测试中处理i / o的东西!

答案 1 :(得分:1)

考虑一下您正在测试的内容,以及您真正想要测试的内容。测试名称非常有用。你称之为#34; daemonIsSuccessfullyInstalled",但是你试图测试它,在启动之后,它的状态是"运行"。尝试命名您的测试方法,以"应该":" shouldBeRunningWhenStarted",也许。在实现方面 - 您没有测试isRunning()的实现方式,只是它在对象启动后返回true。最简单的实施(simplest thing that could possibly work):return true;。现在,你知道它并没有真正起作用,所以你需要多练习一下。也许在致电start之前先断言,以确保它尚未运行。

您并未真正测试isRunning的作用。您可能希望作为单独的单元测试,并且该测试可能包含模拟。这个测试只是关于start和`isRunning'。

之间的互动