【问题标题】:How to test a java console application with Maven?如何使用 Maven 测试 Java 控制台应用程序?
【发布时间】:2012-12-13 16:51:11
【问题描述】:

这些测试应该在构建 jar 文件之后运行。 他们应该测试它是否运行, 以及在给定某些输入文件的情况下是否产生正确的控制台输出。

您能否指出一些针对控制台应用程序进行此类测试的示例?这些测试是否必须用 Java 编写才能与 Maven 一起使用?

有一个类似的问题 (Testing console based applications/programs - Java) 但我需要的是黑盒测试,而不是单元测试。而且它没有提到 Maven。


更新:

事实证明,这很容易做到。我的第一个问题是在这里看到这么多定义后对集成测试的误解(What is Unit test, Integration Test, Smoke test, Regression Test?What's the difference between unit, functional, acceptance, and integration tests?What are unit testing and integration testing, and what other types of testing should I know about?What is an integration test exactly?)。第二个问题是我并没有打算用Java编写这些测试,但最终我不得不学习如何使用java.lang.Runtime

首先,我已将此添加到我的 pom.xml

<plugin>
    <artifactId>maven-failsafe-plugin</artifactId>
    <version>2.6</version>
    <executions>
        <execution>
            <goals>
                <goal>integration-test</goal>
                <goal>verify</goal>
            </goals>
        </execution>
    </executions>
</plugin>

然后我在src/test/java中创建了一个*IT.java文件:

public class MyAppIT {

    @Test
    public void test() throws IOException {
        Runtime runtime = Runtime.getRuntime();
        String cmd = "java -cp target/myapp.jar my.app.Main";
        Process process = runtime.exec(cmd);
        InputStreamReader isr = new InputStreamReader(process.getErrorStream());
        BufferedReader br = new BufferedReader(isr);
        Boolean containsUsage = false;
        String line;
        while ((line = br.readLine()) != null) {
            if (line.contains("Usage")) {
                containsUsage = true;
            }
        }
        assertTrue(containsUsage);
    }
}

现在我使用 mvn verify 而不是 mvn package

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

【问题讨论】:

    标签: java maven testing console-application


    【解决方案1】:

    您似乎想要进行集成测试。

    在许多情况下,应用程序是由持续集成 (CI) 系统构建的,例如 Hudson、Travis 等。此 CI 在每次提交源代码后编译并运行单元测试。 编译成功后,触发集成测试项目。

    集成测试驻留在单独的 Maven 源项目中。您将像在 src/test/java 中的普通单元测试一样创建集成测试类。当然,您不会孤立地测试单个类 - 即单元测试 - 您为集成测试设置系统(连接正确的组件)并执行所需的测试“冒烟测试”。

    因此,在您的情况下,您可以为集成测试创建另一个项目,并在构建应用程序后执行此项目。您可以创建一个 maven parent-pom 并使用子模块来避免手动集成测试构建。

    测试类需要是 java 并且位于 src/test/java,它们看起来像普通的单元测试并且由 maven 运行。 当然,您可以在该测试中启动一个非 java 程序并断言结果。

    控制台应用程序有一个“ma​​in”方法,所以我会在测试中调用 main 方法。否则你必须运行一个shell命令或其他东西。 (通过 java.lang.Runtime)

    测试控制台应用程序没有专长。除非您想测试用户界面 - 用户界面的自动化测试并不容易而且更加困难,请说明这是否是您的重点。

    【讨论】:

    • 是的,我想要测试程序是否真正运行,而不是“main”方法是否有效。我不会称它为我的程序的接口测试不允许任何用户交互。它只是处理输入文件并输出结果。
    • 命令行调用发出对 main 方法的调用。您可以使用运行时执行“java my.app.Main”命令,您在测试项目中拥有完整的 java 可能性。
    【解决方案2】:

    我建议将maven-invoker-pluginexec-maven-plugin 结合使用。 Invoker 创建一个子项目并运行它,其中 exec 插件启动您的 JAR。然后调用者验证其输出。

    例如,看看s3auth-relay 项目中的这个pom.xml。该模块本身生成一个 JAR 控制台应用程序,它是一个 HTTP 守护程序。 pom.xmlmaven-invoker-plugin 配置的一部分。它启动控制台应用程序并检查它是否正常关闭。为了防止 JAR 作为守护进程启动,我们使用了可选的 -d 标志。

    该示例没有显示测试 JAR 输出的能力,但可以使用 maven-invoker-pluginpost build script 机制进行测试。

    【讨论】:

    • 不幸的是,maven-invoker-plugin 旨在运行 Maven,作为特别是 maven-plugins 集成测试的一部分,而不是控制台应用程序。
    • 只要您的控制台应用程序不需要用户输入,maven-invoker-plugin 就是完美的选择
    • 你有一些使用例子吗?
    • 据我了解,这种方法只能测试应用程序是否真正运行并正常关闭,仅此而已。无法以这种方式分析其输出。我说的对吗?
    • 是的,只有当它正常关闭时。我更新了我的答案以显示分析其输出的能力。
    猜你喜欢
    • 2011-05-12
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    • 1970-01-01
    • 2013-02-11
    • 2019-08-17
    • 2016-01-30
    • 1970-01-01
    相关资源
    最近更新 更多