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.exe
和mvn.cmd
。使用前者会引发 IOException,而与 "mvn.cmd", "-version"
' 对应的子进程以代码 1 退出。我什至尝试在输入流上调用 read
,它返回 -1,这意味着流中没有字节。以上是关于Junit5 无法在测试中执行 shell 命令的主要内容,如果未能解决你的问题,请参考以下文章
带有 @Suite 注释的 Junit5 测试套件不使用 mvn test 命令执行测试