Maven运行Selenium/TestNG/Cucumber(Pico-Container)项目报IllegalStateException
解决Maven命令行执行Cucumber+TestNG+Pico-Container测试时的容器状态异常问题
问题场景
本地IDE中运行feature文件、testng.xml或Runner.java时测试完全正常,但通过命令行执行mvn test或mvn verify时,抛出以下异常:
java.lang.IllegalStateException: Cannot stop. Current container state was: CONSTRUCTED at org.picocontainer.lifecycle.DefaultLifecycleState.stopping(DefaultLifecycleState.java:72) at org.picocontainer.DefaultPicoContainer.stop(DefaultPicoContainer.java:794) at io.cucumber.picocontainer.PicoFactory.stop(PicoFactory.java:37) at io.cucumber.core.runner.Runner.disposeBackendWorlds(Runner.java:156) at io.cucumber.core.runner.Runner.runPickle(Runner.java:78) at io.cucumber.testng.TestNGCucumberRunner.lambda$runScenario$1(TestNGCucumberRunner.java:132) at io.cucumber.core.runtime.CucumberExecutionContext.lambda$runTestCase$3(CucumberExecutionContext.java:110) at io.cucumber.core.runtime.RethrowingThrowableCollector.executeAndThrow(RethrowingThrowableCollector.java:23) at io.cucumber.core.runtime.CucumberExecutionContext.runTestCase(CucumberExecutionContext.java:110) at io.cucumber.testng.TestNGCucumberRunner.runScenario(TestNGCucumberRunner.java:129) at io.cucumber.testng.AbstractTestNGCucumberTests.runScenario(AbstractTestNGCucumberTests.java:35) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:133) at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:598) at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:173) at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46) at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:824) at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:146) at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146) at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.testng.TestRunner.privateRun(TestRunner.java:794) at org.testng.TestRunner.run(TestRunner.java:596) at org.testng.SuiteRunner.runTest(SuiteRunner.java:377) at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:371) at org.testng.SuiteRunner.privateRun(SuiteRunner.java:332) at org.testng.SuiteRunner.run(SuiteRunner.java:276) at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53) at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96) at org.testng.TestNG.runSuitesSequentially(TestNG.java:1212) at org.testng.TestNG.runSuitesLocally(TestNG.java:1134) at org.testng.TestNG.runSuites(TestNG.java:1063) at org.testng.TestNG.run(TestNG.java:1031) at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:284) at org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:75) at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:119) at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:428) at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162) at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:562) at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:548)
修复方案
1. 统一Cucumber依赖版本
确保cucumber-picocontainer、cucumber-java、cucumber-testng的版本完全一致,版本不匹配是引发容器生命周期异常的常见原因。示例Maven配置:
<dependencies> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-java</artifactId> <version>7.14.0</version> <scope>test</scope> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-testng</artifactId> <version>7.14.0</version> <scope>test</scope> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-picocontainer</artifactId> <version>7.14.0</version> <scope>test</scope> </dependency> </dependencies>
2. 调整Maven Surefire插件配置
Maven Surefire的fork模式可能干扰容器生命周期管理,尝试禁用fork或指定TestNG配置文件:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.1.2</version> <configuration> <!-- 禁用fork模式 --> <forkCount>0</forkCount> <reuseForks>false</reuseForks> <!-- 指定TestNG配置文件路径 --> <suiteXmlFiles> <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile> </suiteXmlFiles> </configuration> </plugin> </plugins> </build>
3. 自定义Hook管理容器状态
通过Cucumber Hook手动控制容器stop操作,避免在非STARTED状态下执行stop:
import io.cucumber.java.After; import org.picocontainer.DefaultPicoContainer; import org.picocontainer.lifecycle.DefaultLifecycleState; public class ContainerLifecycleHooks { private final DefaultPicoContainer container; // 构造注入获取容器实例 public ContainerLifecycleHooks(DefaultPicoContainer container) { this.container = container; } @After public void afterScenario() { // 仅当容器处于STARTED状态时执行stop if (DefaultLifecycleState.STARTED.equals(container.getLifecycleState())) { container.stop(); } } }
4. 排查并解决依赖冲突
使用Maven命令检查Pico-Container相关依赖是否存在版本冲突:
mvn dependency:tree -Dverbose -Dincludes=org.picocontainer
若发现冲突,在pom.xml中排除多余依赖并手动引入统一版本:
<dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-picocontainer</artifactId> <version>7.14.0</version> <scope>test</scope> <exclusions> <exclusion> <groupId>org.picocontainer</groupId> <artifactId>picocontainer</artifactId> </exclusion> </exclusions> </dependency> <!-- 引入统一版本的Pico-Container --> <dependency> <groupId>org.picocontainer</groupId> <artifactId>picocontainer</artifactId> <version>2.15</version> <scope>test</scope> </dependency>
内容的提问来源于stack exchange,提问作者sbguduru
相关产品推荐
相关产品推荐

