Junit5 无法在测试中执行 shell 命令

Posted

技术标签:

【中文标题】Junit5 无法在测试中执行 shell 命令【英文标题】:Junit5 is unable to execute shell commands within tests 【发布时间】:2021-12-22 10:44:00 【问题描述】:

我对使用 Junit 5 运行脚本有疑问。我有以下代码:

public class RunMvnSubprocess 
    @Test
    public void main() throws IOException, InterruptedException 
        String[] cmd = new String[]"mvn.cmd", "-version"; // command to be executed on command prompt.
        Process p = Runtime.getRuntime().exec(cmd);
        try (BufferedReader output = new BufferedReader(new InputStreamReader(p.getInputStream()))) 
            String line;
            while ((line = output.readLine()) != null) 
                System.out.println(line);
            
        
        p.waitFor();
    

当我使用 Junit 5.7.0 运行它时,没有输出。但是,在 Junit 4.13.2 上运行它可以正常工作。

请注意,我在 Windows 10 Pro 版本 21H1 中运行此测试。

编辑:

修改

new String[]"mvn.cmd", "-version"

new String[]"cmd", "/c", "\"mvn -version\""

对我有用,但启动子外壳是一种不好的做法,因此我将这种解决方法作为最后的手段。

【问题讨论】:

【参考方案1】:

请注意,当调用 Windows 命令 CMD.EXE 来解释 mvn.cmd 的内容时,您正在隐式运行子 shell,因此您的 cmd 的值相当于:

cmd = new String[] "cmd", "/c", "call mvn.cmd -version";

如果您没有收到来自waitFor 的错误代码或没有输出或没有异常,则该问题将在 STDERR 流中报告。改为使用 ProcessBuilder,您可以将 STDERR 合并到 STDOUT,如下所示:

ProcessBuilder pb = new ProcessBuilder(cmd);
// No STDERR => merge to STDOUT
pb.redirectErrorStream(true);

Process p = pb.start();

另外,不需要编写太多代码来消耗 STDOUT:

try(var stdo = p.getInputStream()) 
    stdo.transferTo(System.out);


int rc = p.waitFor();
if (rc != 0) throw new RuntimeException("test failed");

希望这能解释您使用 mvn 命令的问题。

【讨论】:

感谢@DuncG 的回答。我仍然没有得到任何输出,但是 rc 的值是 1 所以我得到了一个 RuntimeException 引发。 所以我的子进程以非零代码退出(测试套件以0退出),我不知道为什么,因为没有消息。 你已经像上面那样切换到 ProcessBuilder 了?您应该澄清“mvn.cmd”包含的内容,因为您的命令列表"cmd", "/c", "\"mvn -version\"":这意味着您的修复可以运行MVN.EXE或MVN.CMD,具体取决于当前目录的内容,以及环境变量@987654329 @ 和 PATHEXT 所以与第一个 cmd 不同。 是的,我切换到上面的流程构建器并尝试使用mvn.exemvn.cmd。使用前者会引发 IOException,而与 "mvn.cmd", "-version"' 对应的子进程以代码 1 退出。我什至尝试在输入流上调用 read,它返回 -1,这意味着流中没有字节。

以上是关于Junit5 无法在测试中执行 shell 命令的主要内容,如果未能解决你的问题,请参考以下文章

带有 @Suite 注释的 Junit5 测试套件不使用 mvn test 命令执行测试

运行测试套件无法通过 maven 在 junit5 中运行

使用 spring boot gradle 插件无法使用依赖管理执行 junit5 测试

在 Junit5 中记录每个测试用例的执行时间的注释

junit5常用注解

带有硒测试容器的junit5无法正常工作