测试前在 Cucumber-JVM 中初始化 WebDriver 作为依赖注入
Initialise WebDriver as dependency injection in Cucumber-JVM before test
我是 Cucumber-JVM 的新手,之前我曾经创建一个 BaseTest class,在某些 @BeforeMethod 中初始化 WebDriver,然后从 BaseTest class 扩展所有其他测试 类 ],因此 WebDriver 初始化在代码库中被管理一次,并且 WebDriver 初始化发生在每次测试之前,这是应该的。使用 Cucumber-JVM,我知道这个想法是在一些 class 中初始化 WebDriver,用 @ScenarioScoped 注释标记这个 class,然后在带有 @Inject 注释的 StepDefinitions 中使用这个 class 的实例 -这样我就可以访问创建的 WebDriver。我尝试了不同的选择,但没有成功。我按照这些指南中的步骤操作,但每次都会遇到类似的错误:
http://www.thinkcode.se/blog/2017/08/16/sharing-state-between-steps-in-cucumberjvm-using-guice
https://codoid.com/automation-testing/an-all-inclusive-guide-to-achieve-cucumber-dependency-injection-using-guice/
我在下面附上我的文件和当前状态,希望有人能指导我正确的方法。
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 1.813 s <<< FAILURE! - in TestSuite
[ERROR] wiki.runners.MainPageRunnerTest.runScenario["Open main page from home page in English locale", "Optional[Open main page]"](1) Time elapsed: 0.643 s <<< FAILURE!
com.google.inject.ProvisionException:
Unable to provision, see the following errors:
1) [Guice/ErrorInjectingConstructor]: NoSuchMethodError: 'ImmutableMap ImmutableMap.of(Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object)'
at wiki.World.<init>(World.java:10)
at wiki.World.class(World.java:10)
at OpenMainPageDefinitions.world(OpenMainPageDefinitions.java:15)
\_ for field world
while locating OpenMainPageDefinitions
Learn more:
https://github.com/google/guice/wiki/ERROR_INJECTING_CONSTRUCTOR
1 error
======================
Full classname legend:
======================
ImmutableMap: "com.google.common.collect.ImmutableMap"
OpenMainPageDefinitions: "wiki.definitions.OpenMainPageDefinitions"
========================
End of classname legend:
========================
at com.google.inject.internal.InternalProvisionException.toProvisionException(InternalProvisionException.java:251)
at com.google.inject.internal.InjectorImpl.get(InjectorImpl.java:1104)
at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1139)
at io.cucumber.guice.GuiceFactory.getInstance(GuiceFactory.java:83)
at io.cucumber.java.AbstractGlueDefinition.invokeMethod(AbstractGlueDefinition.java:47)
at io.cucumber.java.JavaStepDefinition.execute(JavaStepDefinition.java:29)
at io.cucumber.core.runner.CoreStepDefinition.execute(CoreStepDefinition.java:66)
at io.cucumber.core.runner.PickleStepDefinitionMatch.runStep(PickleStepDefinitionMatch.java:63)
at io.cucumber.core.runner.ExecutionMode.execute(ExecutionMode.java:10)
at io.cucumber.core.runner.TestStep.executeStep(TestStep.java:86)
at io.cucumber.core.runner.TestStep.run(TestStep.java:57)
at io.cucumber.core.runner.PickleStepTestStep.run(PickleStepTestStep.java:51)
at io.cucumber.core.runner.TestCase.run(TestCase.java:95)
at io.cucumber.core.runner.Runner.runPickle(Runner.java:75)
at io.cucumber.testng.TestNGCucumberRunner.lambda$runScenario(TestNGCucumberRunner.java:132)
at io.cucumber.core.runtime.CucumberExecutionContext.lambda$runTestCase(CucumberExecutionContext.java:151)
at io.cucumber.core.runtime.RethrowingThrowableCollector.executeAndThrow(RethrowingThrowableCollector.java:23)
at io.cucumber.core.runtime.CucumberExecutionContext.runTestCase(CucumberExecutionContext.java:151)
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.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:135)
at org.testng.internal.invokers.TestInvoker.invokeMethod(TestInvoker.java:673)
at org.testng.internal.invokers.TestInvoker.invokeTestMethod(TestInvoker.java:220)
at org.testng.internal.invokers.MethodRunner.runInSequence(MethodRunner.java:50)
at org.testng.internal.invokers.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:945)
at org.testng.internal.invokers.TestInvoker.invokeTestMethods(TestInvoker.java:193)
at org.testng.internal.invokers.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
at org.testng.internal.invokers.TestMethodWorker.run(TestMethodWorker.java:128)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.testng.TestRunner.privateRun(TestRunner.java:808)
at org.testng.TestRunner.run(TestRunner.java:603)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:429)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:423)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:383)
at org.testng.SuiteRunner.run(SuiteRunner.java:326)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1249)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1169)
at org.testng.TestNG.runSuites(TestNG.java:1092)
at org.testng.TestNG.run(TestNG.java:1060)
at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:324)
at org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:74)
at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:123)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:456)
at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:169)
at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:595)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:581)
Caused by: java.lang.NoSuchMethodError: 'com.google.common.collect.ImmutableMap com.google.common.collect.ImmutableMap.of(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object)'
at org.openqa.selenium.chrome.AddHasCasting.getAdditionalCommands(AddHasCasting.java:38)
at org.openqa.selenium.chrome.ChromeDriver$ChromeDriverCommandExecutor.getExtraCommands(ChromeDriver.java:123)
at org.openqa.selenium.chrome.ChromeDriver$ChromeDriverCommandExecutor.<init>(ChromeDriver.java:118)
at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:106)
at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:93)
at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:82)
at wiki.WebDriverManager.<init>(WebDriverManager.java:16)
at wiki.World.<init>(World.java:11)
at wiki.World$$FastClassByGuice$467.GUICE$TRAMPOLINE(<generated>)
at wiki.World$$FastClassByGuice$467.apply(<generated>)
at com.google.inject.internal.DefaultConstructionProxyFactory$FastClassProxy.newInstance(DefaultConstructionProxyFactory.java:82)
at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:114)
at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:91)
at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:300)
at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
at io.cucumber.guice.SequentialScenarioScope.lambda$scope[=10=](SequentialScenarioScope.java:40)
at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:45)
at com.google.inject.internal.SingleFieldInjector.inject(SingleFieldInjector.java:50)
at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:146)
at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:124)
at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:91)
at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:300)
at com.google.inject.internal.InjectorImpl.get(InjectorImpl.java:1101)
... 50 more
[INFO]
[INFO] Results:
[INFO]
[ERROR] Failures:
[ERROR] MainPageRunnerTest>AbstractTestNGCucumberTests.runScenario:35 » Provision Unable to provision, see the following errors:
1) [Guice/ErrorInjectingConstructor]: NoSuchMethodError: 'ImmutableMap ImmutableMap.of(Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object)'
at wiki.World.<init>(World.java:10)
at wiki.World.class(World.java:10)
at OpenMainPageDefinitions.world(OpenMainPageDefinitions.java:15)
\_ for field world
while locating OpenMainPageDefinitions
Learn more:
https://github.com/google/guice/wiki/ERROR_INJECTING_CONSTRUCTOR
1 error
======================
Full classname legend:
======================
ImmutableMap: "com.google.common.collect.ImmutableMap"
OpenMainPageDefinitions: "wiki.definitions.OpenMainPageDefinitions"
========================
End of classname legend:
========================
[INFO]
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
OpenMainPageDefinitions.java:
package wiki.definitions;
import com.google.inject.Inject;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import wiki.World;
import wiki.pages.EnMainPage;
import wiki.pages.HomePage;
public class OpenMainPageDefinitions {
@Inject World world;
public HomePage homePage;
public EnMainPage enMainPage;
@Given("Home page is opened")
public void homePageIsOpened() {
homePage = new HomePage(world.manager.get());
homePage.open().assertCentralFeaturedLogoIsDisplayed();
}
@When("User clicks on Main Page Link")
public void userClicksOnMainPageLink() {
homePage.clickEnMainPageLink();
enMainPage = new EnMainPage(world.manager.get());
}
@Then("Welcome block is displayed")
public void welcomeBlockIsDisplayed() {
enMainPage.assertWelcomeBlockIsDisplayed();
}
}
World.java
package wiki;
import io.cucumber.guice.ScenarioScoped;
@ScenarioScoped
public class World {
public WebDriverManager manager;
public World() {
manager = new WebDriverManager();
}
}
WebDriverManager.java
package wiki;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class WebDriverManager {
public String env;
public ChromeOptions options;
public WebDriver driver;
public WebDriverManager() {
env = getEnv();
options = getChromeOptions();
driver = new ChromeDriver(options);
}
public ChromeOptions getChromeOptions() {
if(env.equals("CIRCLE_CI")) {
return new ChromeOptions()
.addArguments("--disable-dev-shm-usage")
.addArguments("--headless")
.addArguments("--no-sandbox");
}
return new ChromeOptions();
}
public String getEnv() {
String env = System.getenv("WIKI_ENV");
return env == null ? "LOCAL" : env;
}
public WebDriver get() {
return driver;
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>cucumber-selenium-tests</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven-surefire-plugin.version>3.0.0-M6</maven-surefire-plugin.version>
<maven-compiler-plugin.version>3.10.1</maven-compiler-plugin.version>
<testng.version>7.5</testng.version>
<selenium-java.version>4.1.3</selenium-java.version>
<cucumber.version>7.2.3</cucumber.version>
<google-inject.version>5.1.0</google-inject.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>${selenium-java.version}</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-testng</artifactId>
<version>${cucumber.version}</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>${cucumber.version}</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-guice</artifactId>
<version>${cucumber.version}</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>${google-inject.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<webdriver.chrome.driver>/tmp/chromedriver/chromedriver</webdriver.chrome.driver>
</systemPropertyVariables>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
</project>
如果您 运行 mvn dependency:tree -Dverbose
在项目根目录中,您将能够分析项目的依赖关系层次结构。
包 com.google.common.collect.ImmutableMap
在 guava
库中分发。依赖分析表明,Selenium 使用版本 31.1
而 Guice 使用版本 30.1
.
Guice 下的 Guava 更靠近树根,因此 Maven 考虑到 lib 越靠近根,在发生冲突时它的优先级越高。
一共有三种解法:
- 将 Selenium 版本降低到使用较低版本 Guava 的版本(最好是 30.1,但也可以接受主要版本匹配)
- 将 Guice 版本增加到使用更高版本 Guava 的版本(最好是 31.1,但也可以接受主要版本匹配)
- 隐式指定 guava 依赖项。将 31.1 版本依赖项添加到您的
pom.xml
。它将绝对优先于其他人。并希望它向后兼容30.1,这样Guice逻辑就不会受到影响。
我是 Cucumber-JVM 的新手,之前我曾经创建一个 BaseTest class,在某些 @BeforeMethod 中初始化 WebDriver,然后从 BaseTest class 扩展所有其他测试 类 ],因此 WebDriver 初始化在代码库中被管理一次,并且 WebDriver 初始化发生在每次测试之前,这是应该的。使用 Cucumber-JVM,我知道这个想法是在一些 class 中初始化 WebDriver,用 @ScenarioScoped 注释标记这个 class,然后在带有 @Inject 注释的 StepDefinitions 中使用这个 class 的实例 -这样我就可以访问创建的 WebDriver。我尝试了不同的选择,但没有成功。我按照这些指南中的步骤操作,但每次都会遇到类似的错误: http://www.thinkcode.se/blog/2017/08/16/sharing-state-between-steps-in-cucumberjvm-using-guice https://codoid.com/automation-testing/an-all-inclusive-guide-to-achieve-cucumber-dependency-injection-using-guice/
我在下面附上我的文件和当前状态,希望有人能指导我正确的方法。
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 1.813 s <<< FAILURE! - in TestSuite
[ERROR] wiki.runners.MainPageRunnerTest.runScenario["Open main page from home page in English locale", "Optional[Open main page]"](1) Time elapsed: 0.643 s <<< FAILURE!
com.google.inject.ProvisionException:
Unable to provision, see the following errors:
1) [Guice/ErrorInjectingConstructor]: NoSuchMethodError: 'ImmutableMap ImmutableMap.of(Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object)'
at wiki.World.<init>(World.java:10)
at wiki.World.class(World.java:10)
at OpenMainPageDefinitions.world(OpenMainPageDefinitions.java:15)
\_ for field world
while locating OpenMainPageDefinitions
Learn more:
https://github.com/google/guice/wiki/ERROR_INJECTING_CONSTRUCTOR
1 error
======================
Full classname legend:
======================
ImmutableMap: "com.google.common.collect.ImmutableMap"
OpenMainPageDefinitions: "wiki.definitions.OpenMainPageDefinitions"
========================
End of classname legend:
========================
at com.google.inject.internal.InternalProvisionException.toProvisionException(InternalProvisionException.java:251)
at com.google.inject.internal.InjectorImpl.get(InjectorImpl.java:1104)
at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1139)
at io.cucumber.guice.GuiceFactory.getInstance(GuiceFactory.java:83)
at io.cucumber.java.AbstractGlueDefinition.invokeMethod(AbstractGlueDefinition.java:47)
at io.cucumber.java.JavaStepDefinition.execute(JavaStepDefinition.java:29)
at io.cucumber.core.runner.CoreStepDefinition.execute(CoreStepDefinition.java:66)
at io.cucumber.core.runner.PickleStepDefinitionMatch.runStep(PickleStepDefinitionMatch.java:63)
at io.cucumber.core.runner.ExecutionMode.execute(ExecutionMode.java:10)
at io.cucumber.core.runner.TestStep.executeStep(TestStep.java:86)
at io.cucumber.core.runner.TestStep.run(TestStep.java:57)
at io.cucumber.core.runner.PickleStepTestStep.run(PickleStepTestStep.java:51)
at io.cucumber.core.runner.TestCase.run(TestCase.java:95)
at io.cucumber.core.runner.Runner.runPickle(Runner.java:75)
at io.cucumber.testng.TestNGCucumberRunner.lambda$runScenario(TestNGCucumberRunner.java:132)
at io.cucumber.core.runtime.CucumberExecutionContext.lambda$runTestCase(CucumberExecutionContext.java:151)
at io.cucumber.core.runtime.RethrowingThrowableCollector.executeAndThrow(RethrowingThrowableCollector.java:23)
at io.cucumber.core.runtime.CucumberExecutionContext.runTestCase(CucumberExecutionContext.java:151)
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.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:135)
at org.testng.internal.invokers.TestInvoker.invokeMethod(TestInvoker.java:673)
at org.testng.internal.invokers.TestInvoker.invokeTestMethod(TestInvoker.java:220)
at org.testng.internal.invokers.MethodRunner.runInSequence(MethodRunner.java:50)
at org.testng.internal.invokers.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:945)
at org.testng.internal.invokers.TestInvoker.invokeTestMethods(TestInvoker.java:193)
at org.testng.internal.invokers.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
at org.testng.internal.invokers.TestMethodWorker.run(TestMethodWorker.java:128)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.testng.TestRunner.privateRun(TestRunner.java:808)
at org.testng.TestRunner.run(TestRunner.java:603)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:429)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:423)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:383)
at org.testng.SuiteRunner.run(SuiteRunner.java:326)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1249)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1169)
at org.testng.TestNG.runSuites(TestNG.java:1092)
at org.testng.TestNG.run(TestNG.java:1060)
at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:324)
at org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:74)
at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:123)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:456)
at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:169)
at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:595)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:581)
Caused by: java.lang.NoSuchMethodError: 'com.google.common.collect.ImmutableMap com.google.common.collect.ImmutableMap.of(java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object, java.lang.Object)'
at org.openqa.selenium.chrome.AddHasCasting.getAdditionalCommands(AddHasCasting.java:38)
at org.openqa.selenium.chrome.ChromeDriver$ChromeDriverCommandExecutor.getExtraCommands(ChromeDriver.java:123)
at org.openqa.selenium.chrome.ChromeDriver$ChromeDriverCommandExecutor.<init>(ChromeDriver.java:118)
at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:106)
at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:93)
at org.openqa.selenium.chrome.ChromeDriver.<init>(ChromeDriver.java:82)
at wiki.WebDriverManager.<init>(WebDriverManager.java:16)
at wiki.World.<init>(World.java:11)
at wiki.World$$FastClassByGuice$467.GUICE$TRAMPOLINE(<generated>)
at wiki.World$$FastClassByGuice$467.apply(<generated>)
at com.google.inject.internal.DefaultConstructionProxyFactory$FastClassProxy.newInstance(DefaultConstructionProxyFactory.java:82)
at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:114)
at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:91)
at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:300)
at com.google.inject.internal.ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
at io.cucumber.guice.SequentialScenarioScope.lambda$scope[=10=](SequentialScenarioScope.java:40)
at com.google.inject.internal.InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:45)
at com.google.inject.internal.SingleFieldInjector.inject(SingleFieldInjector.java:50)
at com.google.inject.internal.MembersInjectorImpl.injectMembers(MembersInjectorImpl.java:146)
at com.google.inject.internal.ConstructorInjector.provision(ConstructorInjector.java:124)
at com.google.inject.internal.ConstructorInjector.construct(ConstructorInjector.java:91)
at com.google.inject.internal.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:300)
at com.google.inject.internal.InjectorImpl.get(InjectorImpl.java:1101)
... 50 more
[INFO]
[INFO] Results:
[INFO]
[ERROR] Failures:
[ERROR] MainPageRunnerTest>AbstractTestNGCucumberTests.runScenario:35 » Provision Unable to provision, see the following errors:
1) [Guice/ErrorInjectingConstructor]: NoSuchMethodError: 'ImmutableMap ImmutableMap.of(Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, Object)'
at wiki.World.<init>(World.java:10)
at wiki.World.class(World.java:10)
at OpenMainPageDefinitions.world(OpenMainPageDefinitions.java:15)
\_ for field world
while locating OpenMainPageDefinitions
Learn more:
https://github.com/google/guice/wiki/ERROR_INJECTING_CONSTRUCTOR
1 error
======================
Full classname legend:
======================
ImmutableMap: "com.google.common.collect.ImmutableMap"
OpenMainPageDefinitions: "wiki.definitions.OpenMainPageDefinitions"
========================
End of classname legend:
========================
[INFO]
[ERROR] Tests run: 1, Failures: 1, Errors: 0, Skipped: 0
OpenMainPageDefinitions.java:
package wiki.definitions;
import com.google.inject.Inject;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import wiki.World;
import wiki.pages.EnMainPage;
import wiki.pages.HomePage;
public class OpenMainPageDefinitions {
@Inject World world;
public HomePage homePage;
public EnMainPage enMainPage;
@Given("Home page is opened")
public void homePageIsOpened() {
homePage = new HomePage(world.manager.get());
homePage.open().assertCentralFeaturedLogoIsDisplayed();
}
@When("User clicks on Main Page Link")
public void userClicksOnMainPageLink() {
homePage.clickEnMainPageLink();
enMainPage = new EnMainPage(world.manager.get());
}
@Then("Welcome block is displayed")
public void welcomeBlockIsDisplayed() {
enMainPage.assertWelcomeBlockIsDisplayed();
}
}
World.java
package wiki;
import io.cucumber.guice.ScenarioScoped;
@ScenarioScoped
public class World {
public WebDriverManager manager;
public World() {
manager = new WebDriverManager();
}
}
WebDriverManager.java
package wiki;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class WebDriverManager {
public String env;
public ChromeOptions options;
public WebDriver driver;
public WebDriverManager() {
env = getEnv();
options = getChromeOptions();
driver = new ChromeDriver(options);
}
public ChromeOptions getChromeOptions() {
if(env.equals("CIRCLE_CI")) {
return new ChromeOptions()
.addArguments("--disable-dev-shm-usage")
.addArguments("--headless")
.addArguments("--no-sandbox");
}
return new ChromeOptions();
}
public String getEnv() {
String env = System.getenv("WIKI_ENV");
return env == null ? "LOCAL" : env;
}
public WebDriver get() {
return driver;
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>cucumber-selenium-tests</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<maven-surefire-plugin.version>3.0.0-M6</maven-surefire-plugin.version>
<maven-compiler-plugin.version>3.10.1</maven-compiler-plugin.version>
<testng.version>7.5</testng.version>
<selenium-java.version>4.1.3</selenium-java.version>
<cucumber.version>7.2.3</cucumber.version>
<google-inject.version>5.1.0</google-inject.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>${selenium-java.version}</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-testng</artifactId>
<version>${cucumber.version}</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>${cucumber.version}</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-guice</artifactId>
<version>${cucumber.version}</version>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>${google-inject.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
<configuration>
<systemPropertyVariables>
<webdriver.chrome.driver>/tmp/chromedriver/chromedriver</webdriver.chrome.driver>
</systemPropertyVariables>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
</project>
如果您 运行 mvn dependency:tree -Dverbose
在项目根目录中,您将能够分析项目的依赖关系层次结构。
包 com.google.common.collect.ImmutableMap
在 guava
库中分发。依赖分析表明,Selenium 使用版本 31.1
而 Guice 使用版本 30.1
.
Guice 下的 Guava 更靠近树根,因此 Maven 考虑到 lib 越靠近根,在发生冲突时它的优先级越高。
一共有三种解法:
- 将 Selenium 版本降低到使用较低版本 Guava 的版本(最好是 30.1,但也可以接受主要版本匹配)
- 将 Guice 版本增加到使用更高版本 Guava 的版本(最好是 31.1,但也可以接受主要版本匹配)
- 隐式指定 guava 依赖项。将 31.1 版本依赖项添加到您的
pom.xml
。它将绝对优先于其他人。并希望它向后兼容30.1,这样Guice逻辑就不会受到影响。