我正试图摆脱在编写测试时经常发生在我身上的情况。
示例场景是这样的:我有这个类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提出的建议。答案 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'。