Java 如何测试命令行界面(CLI)?
我的Java应用程序由两部分组成:Java 如何测试命令行界面(CLI)?,java,testing,command-line-interface,bats-core,Java,Testing,Command Line Interface,Bats Core,我的Java应用程序由两部分组成: 核心库(类、接口等) 命令行界面(CLI),它使用核心库 1。我使用JUnit进行单元测试,但是你会为2做什么呢 如何为命令行界面创建自动测试?使用Apache commons exec从Java程序执行命令 我遇到了完全相同的问题,在这里着陆,但没有找到好的答案,所以我想我会发布我最终找到的解决方案,作为将来在这里着陆的任何人的起点 我是在CLI之后编写测试的(我知道,这让我感到羞耻),所以首先我要确保CLI是以可测试的方式编写的。它看起来是这样的(我省略了
如何为命令行界面创建自动测试?使用Apache commons exec从Java程序执行命令
我遇到了完全相同的问题,在这里着陆,但没有找到好的答案,所以我想我会发布我最终找到的解决方案,作为将来在这里着陆的任何人的起点 我是在CLI之后编写测试的(我知道,这让我感到羞耻),所以首先我要确保CLI是以可测试的方式编写的。它看起来是这样的(我省略了异常处理并简化了很多以使其更具可读性): 继续测试
CLI
不是公共图书馆的一部分,因此应保护它不受图书馆用户的影响。如上所述,您可以使用默认的访问修饰符将其设置为包私有。这使您的测试能够完全访问该类(只要它们在同一个包中),同时仍能保护它,所以这就是问题所在
为CLI接受的每个命令编写一个方法允许JUnit测试几乎完美地模拟用户输入。因为在调用startInterface()
之前,对象不会从stdin读取,所以您可以简单地实例化它并测试各个方法
首先,最好测试原始输入是否被正确清理,这可以通过为sanitiseInput()
编写JUnit测试来实现。我编写了如下测试:
@Test
public void commandAndArgumentsSeparatedBySpaces() throws Exception {
String[] processedInput = uut.sanitiseInput("command argument1 argument2");
assertEquals("Wrong array length.", 3, processedInput.length);
assertEquals("command", processedInput[0]);
assertEquals("argument1", processedInput[1]);
assertEquals("argument2", processedInput[2]);
}
覆盖某些边缘情况也很容易:
@Test
public void leadingTrailingAndIntermediaryWhiteSpace() throws Exception {
String[] processedInput = uut.sanitiseInput(" \t this \twas \t \t a triumph \t\t ");
assertEquals("Wrong array length.", 4, processedInput.length);
assertEquals("this", processedInput[0]);
assertEquals("was", processedInput[1]);
assertEquals("a", processedInput[2]);
assertEquals("triumph", processedInput[3]);
}
接下来,我们可以通过监视stdout来测试invidual命令方法。我这样做了(我发现):
换句话说,将JVM的out
替换为您可以在练习前查询的内容,然后将旧控制台设置回测试的拆卸中
当然,CLI应用程序通常不仅仅是打印到控制台。假设您的程序将信息保存到文件中,您可以对其进行测试(从JUnit 4.7开始):
JUnit将负责创建有效文件并在测试运行结束时将其删除,让您可以自由测试CLI方法是否正确处理了该文件。对于CLI,请尝试BATS(Bash自动测试系统): 从文档中:
example.bats contains
#!/usr/bin/env bats
@test "addition using bc" {
result="$(echo 2+2 | bc)"
[ "$result" -eq 4 ]
}
@test "addition using dc" {
result="$(echo 2 2+p | dc)"
[ "$result" -eq 4 ]
}
$ bats example.bats
✓ addition using bc
✓ addition using dc
2 tests, 0 failures
是的,Apache Commons Exec确实执行程序。那么如何使用它测试CLI呢?海报上说他们的应用程序是Java的。
private CLI uut;
private ByteArrayOutputStream testOutput;
private PrintStream console = System.out;
private static final String EOL = System.getProperty("line.separator");
@Before
public void setUp() throws Exception {
uut = new CLI();
testOutput = new ByteArrayOutputStream();
}
@Test
public void helpIsPrintedToStdout() throws Exception {
try {
System.setOut(new PrintStream(testOutput));
uut.help();
} finally {
System.setOut(console);
}
assertEquals("Helpful help." + EOL, testOutput.toString());
}
@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();
@Test
public void informationIsSavedToFile() throws Exception {
File testFile = tempFolder.newFile();
String expectedContent = "This should be written to the file.";
uut.save(testFile.getAbsolutePath(), expectedContent);
try (Scanner scanner = new Scanner(testFile)) {
String actualContent = scanner.useDelimiter("\\Z").next();
assertEquals(actualContent, expectedContent);
}
}
example.bats contains
#!/usr/bin/env bats
@test "addition using bc" {
result="$(echo 2+2 | bc)"
[ "$result" -eq 4 ]
}
@test "addition using dc" {
result="$(echo 2 2+p | dc)"
[ "$result" -eq 4 ]
}
$ bats example.bats
✓ addition using bc
✓ addition using dc
2 tests, 0 failures