如何在Arquillian中获取所有Cube列表?日志导出实现疑问
解决Arquillian Cube获取所有运行Cube并导出Docker日志的问题
我之前在做Arquillian Cube测试的时候也碰到过类似的困扰,分享几个亲测有效的方案帮你解决这个问题:
方案1:通过Arquillian核心API注入CubeRegistry
虽然@ArquillianResource没法直接注入CubeRegistry,但可以用Arquillian的Instance API来获取它的实例。注意如果用JUnit的@AfterClass静态方法的话,注入逻辑需要调整,建议把@AfterClass改成非静态(只要测试类不是单例模式就没问题):
import org.jboss.arquillian.core.api.Instance; import org.jboss.arquillian.core.api.annotation.Inject; import org.arquillian.cube.spi.Cube; import org.arquillian.cube.spi.CubeRegistry; import org.junit.AfterClass; import org.junit.Test; import org.junit.runner.RunWith; import org.jboss.arquillian.junit.Arquillian; import java.io.FileWriter; import java.io.IOException; @RunWith(Arquillian.class) public class YourIntegrationTest { @Inject private Instance<CubeRegistry> cubeRegistryInstance; @AfterClass public void exportDockerLogsToJUnitOutput() { CubeRegistry cubeRegistry = cubeRegistryInstance.get(); // 遍历所有已启动的Cube for (String cubeId : cubeRegistry.getCubeIds()) { Cube<?> cube = cubeRegistry.getCube(cubeId); if (cube.isStarted()) { // 获取Docker容器日志 String containerLogs = cube.execLog(); // 输出到JUnit控制台 System.out.printf("=== Docker Logs for Cube: %s ===%n", cubeId); System.out.println(containerLogs); System.out.println("========================================="); // 写入到指定的JUnit输出文件 try (FileWriter writer = new FileWriter("junit-docker-logs.txt", true)) { writer.write(String.format("=== Cube: %s Logs ===%n", cubeId)); writer.write(containerLogs); writer.write("=========================================%n%n"); } catch (IOException e) { e.printStackTrace(); } } } } // 你的测试方法 @Test public void testSomethingWithCubes() { // ...测试逻辑 } }
方案2:通过Cube生命周期事件记录运行中的Cube
如果觉得直接获取Registry不够灵活,可以通过订阅Arquillian Cube的启动事件,把所有启动的Cube收集起来,后续在@AfterClass里统一处理:
import org.jboss.arquillian.core.api.annotation.Observes; import org.arquillian.cube.spi.Cube; import org.arquillian.cube.spi.event.lifecycle.AfterCubeStart; import org.junit.AfterClass; import java.util.ArrayList; import java.util.List; public class CubeLogCollector { private static final List<Cube<?>> runningCubes = new ArrayList<>(); // 监听Cube启动事件,自动收集已启动的Cube public void onCubeStart(@Observes AfterCubeStart event) { runningCubes.add(event.getCube()); } @AfterClass public static void exportAllCubeLogs() { for (Cube<?> cube : runningCubes) { String logs = cube.execLog(); // 复用方案1的日志输出/写入逻辑即可 System.out.printf("=== Logs for Cube: %s ===%n", cube.getId()); System.out.println(logs); } } }
把这个收集器和测试类放在同一个包下,Arquillian会自动识别并生效;如果需要更明确的配置,可以在测试类上添加@AddExtension注解指定这个收集器。
方案3:使用CubeController获取所有Cube
另一种更直接的方式是注入CubeController,它本身就提供了获取所有Cube ID和判断启动状态的方法:
import org.arquillian.cube.spi.Cube; import org.arquillian.cube.spi.CubeController; import org.jboss.arquillian.core.api.annotation.Inject; import org.junit.AfterClass; public class YourTestClass { @Inject private CubeController cubeController; @AfterClass public void exportLogs() { for (String cubeId : cubeController.getCubeIds()) { if (cubeController.isStarted(cubeId)) { Cube<?> cube = cubeController.getCube(cubeId); String logs = cube.execLog(); // 处理日志输出或写入文件 } } } }
注意事项
- 如果一定要用静态的
@AfterClass方法,不能直接依赖@Inject的实例,这时候可以考虑用Arquillian的org.jboss.arquillian.core.api.Arquillian静态方法获取上下文,但这种方式相对繁琐,更推荐用非静态的@AfterClass。 - 确保你的Arquillian Cube扩展版本是最新的,部分旧版本可能存在注入API的兼容性问题。
内容的提问来源于stack exchange,提问作者Ivan Kelly
相关产品推荐
相关产品推荐

