0

大家好:我正在使用 Cucumber、Selenium、TestNG 在 Maven 中创建一个存储库。

我正在尝试做的是从属性文件中获取值以使用 Selenium 发送这些参数,但我无法解决此处生成的问题。

这是我的项目的结构:

    .
├── pom.xml
├── selenium_cucumber.iml
├── src
│   ├── main
│   │   ├── java
│   │   │   └── utilities
│   │   │       ├── LoadProperties.java
│   │   │       └── ReportMerger.java
│   │   └── resources
│   │       ├── config.properties
│   │       └── log4j.properties
│   └── test
│       ├── java
│       │   ├── features
│       │   │   └── first.feature
│       │   ├── hooks
│       │   │   ├── ServiceHooks.java
│       │   │   ├── TakesScreenshots.java
│       │   │   └── WebDriverManager.java
│       │   ├── pages
│       │   │   ├── BasePage.java
│       │   │   └── Page_First.java
│       │   ├── runners
│       │   │   └── testNGCucumberRunner.java
│       │   └── steps
│       │       └── Step_First.java
│       └── resources
│           └── testng.xml
└── target

这是我的功能文件:

@test
Feature: Navigation Test
  This is example of using Cucumber-JVM with TestNG and Selenium


  Scenario: Search google.com to verify google search is working

    Given I go to "<Url>" Google
    When I query for "<search>" cucumber spring selenium
    And click search
    Then google page title should become the first page

继续从属性文件 ( config.properties )加载属性的页面

package utilities;

import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;


public class LoadProperties {

    Properties prop;

    public LoadProperties(){

        try{
            prop = new Properties();

            File fis = new File("src/main/resources/config.properties");

            FileInputStream input = new FileInputStream(fis);

            prop.load(input);
        }
        catch(Exception e){
            System.out.println("Error loading configuration file");
        }
    }

    public String getUrl()
    {
        return prop.getProperty("Url");
    }

    public String getNavigator(){

        return prop.getProperty("navigator");
    }

    public String searchData(){

        return prop.getProperty("search");
    }

}

config.properties文件:

navigator = "firefox"
Url = "https://www.google.com"
search = "cucumber spring selenium"

非常重要的是,我正在使用 API WebdriverManager(作者 Boni Garcia),因为这样就没有必要将每个浏览器的驱动程序放在一个文件夹中并下载它们。

package hooks;

import com.codeborne.selenide.WebDriverRunner;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.opera.OperaDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import javax.annotation.PreDestroy;

    @Component
    public class WebDriverManager {

        private WebDriver webDriver;


        public WebDriver getDriver() {
            return webDriver;
        }

        @Bean(destroyMethod = "quit")
        public WebDriver getWebDriver(){
            String currentWebDriver = System.getProperty("browser", "");
            switch(currentWebDriver) {
                case ("chrome"):
                    System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
                    webDriver = new ChromeDriver();
                    break;
                case ("firefox"):
                    System.setProperty("webdriver.gecko.driver", "geckodriver.exe");
                    FirefoxOptions firefoxOptions = new FirefoxOptions();
                    firefoxOptions.setCapability("marionette", true);
                    webDriver = new FirefoxDriver(firefoxOptions);
                    break;
                case ("chromeHeadless"):
                    System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
                    ChromeOptions chromeHeadless = new ChromeOptions();
                    chromeHeadless.setHeadless(true);
                    webDriver = new ChromeDriver(chromeHeadless);
                    break;
                case ("iexplorer"):
                    System.setProperty("webdriver.ie.driver", "IEDriverServer.exe");
                    DesiredCapabilities capabilitiesIE = DesiredCapabilities.internetExplorer();
                    capabilitiesIE.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
                    webDriver = new InternetExplorerDriver(capabilitiesIE);
                    break;
                case ("edge"):
                    System.setProperty("webdriver.edge.driver", "MicrosoftWebDriver.exe");
                    webDriver = new EdgeDriver();
                    break;
                case ("opera"):
                    System.setProperty("webdriver.opera.driver", "operadriver.exe");
                    webDriver = new OperaDriver();
                    break;
                default:
                    System.getProperty("browser", "chrome");
                    System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
                    webDriver = new ChromeDriver();
                    break;
            }

            //Using Selenide driver:
            WebDriverRunner.setWebDriver(webDriver);
            return webDriver;
        }

        @PreDestroy
        public void closeSession(){
            getDriver().manage().deleteAllCookies();
            getDriver().close();
            getDriver().quit();
        }
}

另一方面,我正在使用Page Factory,这是用于使用的通用基本页面:

package pages;

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

public abstract class BasePage {

    private WebDriver driver ;
    private static final Logger log = Logger.getLogger(BasePage.class.getName());

    //Constructor
    public BasePage(WebDriver driver){

        this.driver = driver;
        this.driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        this.driver.manage().window().maximize();
        this.driver.getTitle();

        log.info("______________________Starting tests______________________");
    }

    public String getPageTitle(){
        return driver.getTitle();
    }

    public Logger getLOG() {
        return log;
    }


    public void navigate(String Url){
        driver.get(Url);
    }

/*
    public abstract boolean isAt();
*/

    //Methods

    protected void waitForElementClickable(WebElement element){
        WebDriverWait wait = new WebDriverWait(driver, 30);
        wait.until(ExpectedConditions.elementToBeClickable(element));
    }

    protected void waitForElementVisible(WebElement element){
        WebDriverWait wait = new WebDriverWait(driver, 15);
        wait.until(ExpectedConditions.visibilityOf(element));
    }

    protected void setTextAs(WebElement element, String text) throws IOException {
        waitForElementClickable(element);
        element.sendKeys((text));
    }

    protected void clearElement(WebElement element){
        waitForElementClickable(element);
        element.clear();
    }

    protected void clickElement(WebElement element){
        waitForElementClickable(element);
        element.click();
    }

    protected void clickElementByJavascriptExecutor(String xpath){
        WebElement element=driver.findElement(By.xpath(xpath));
        JavascriptExecutor ex=(JavascriptExecutor)driver;
        ex.executeScript("arguments[0].click()", element);
    }

    protected void clickLink(WebElement element){
        waitForElementVisible(element);
        element.click();
    }

    protected String getText(WebElement element){
        waitForElementVisible(element);
        return element.getText();
    }


    protected void freeze(int seconds) {
        try {
            Thread.sleep(seconds * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

我们不要忘记测试运行器类(testNGCucumberRunner

package runners;

import cucumber.api.CucumberOptions;
import cucumber.api.testng.CucumberFeatureWrapper;
import cucumber.api.testng.PickleEventWrapper;
import cucumber.api.testng.TestNGCucumberRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

@CucumberOptions(
        plugin = {"pretty","json:target/report/cucumber2.json", "html:target/cucumber-reports"},
        strict = true,
        features = {"src/test/java/features"},
        tags = {"@test"},
        glue = {"steps"}
)
    public class testNGCucumberRunner {
    private static final Logger LOG = LoggerFactory.getLogger(runners.testNGCucumberRunner.class);
    private TestNGCucumberRunner testNGCucumberRunner;

    @BeforeClass(alwaysRun = true)
    public void setUpClass() throws Exception {
        testNGCucumberRunner = new TestNGCucumberRunner(this.getClass());
    }

    @Test(groups = "Cucumber", description = "Runs Cucumber Feature", dataProvider = "scenarios")
    public void scenario(PickleEventWrapper pickleEvent, CucumberFeatureWrapper cucumberFeature) throws Throwable {
        LOG.info("STARTING THIS FEATURE >>>>>" + cucumberFeature + "<<<<<<<<<<<<<<<<<<<<<<<<<<");
        testNGCucumberRunner.runScenario(pickleEvent.getPickleEvent());
    }

    @DataProvider
    public Object[][] scenarios() {
        return testNGCucumberRunner.provideScenarios();
    }

    @AfterClass(alwaysRun = true)
    public void tearDownClass() throws Exception {
        testNGCucumberRunner.finish();
    }
}

这里还有 Hooks 类(ServiceHooks

package hooks;

import cucumber.api.Scenario;
import cucumber.api.java.After;
import cucumber.api.java.Before;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebDriverException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import static com.codeborne.selenide.WebDriverRunner.getWebDriver;

public class ServiceHooks {

    private static final Logger log = LoggerFactory.getLogger(ServiceHooks.class);
    private WebDriver webDriver;

    @Before
    public void setUpBrowser(Scenario scenario) throws Exception {

        log.info("****************************************************************************************");
        log.info("$$$$$$$$$$$$$$$$$$$$$ Start of execution of scenario with name: " + scenario.getName() + "    $$$$$$$$$$$$$$$$$$$$$$$");
        log.info("****************************************************************************************");

        if (webDriver == null) {
            log.error("WebDriver did not initialize correctly");
        }
    }

    @After
    public void tearDown(Scenario scenario) throws Exception {
        WebDriver driver = getWebDriver();
        log.info("****************************************************************************************");
        log.info("$$$$$$$$$$$$$$$$$$$$$ Completion of execution of scenario with name: " + scenario.getName() + "    $$$$$$$$$$$$$$$$$$$$$$$");
        log.info("****************************************************************************************");
        if (scenario.isFailed()) {
            log.info("****************************************************************************************");
            log.info("$$$$$$$$$$$$$$$$$$$$$ Failing scenario with name: " + scenario.getName() + "    $$$$$$$$$$$$$$$$$$$$$$$");
            log.info("****************************************************************************************");
            try {
                byte[] screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);
                scenario.embed(screenshot, "image/png");
            } catch (WebDriverException somePlatformsDontSupportScreenshots) {
                System.err.println(somePlatformsDontSupportScreenshots.getMessage());
            }
        }
        driver.quit();
        log.info("Driver closed");
    }
}

我的 POM 不能在这里忘记:

<?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>automation</groupId>
    <artifactId>selenium_cucumber</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <java.version>1.8</java.version>
        <maven.compiler.version>3.7.0</maven.compiler.version>
        <cucumber.version>3.0.2</cucumber.version>
        <selenium.version>3.12.0</selenium.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-java</artifactId>
            <version>${cucumber.version}</version>
        </dependency>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-core</artifactId>
            <version>${cucumber.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-java8 -->
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-java8</artifactId>
            <version>${cucumber.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-picocontainer -->
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-picocontainer</artifactId>
            <version>${cucumber.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-testng -->
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-testng</artifactId>
            <version>${cucumber.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <dependency>
            <groupId>io.github.bonigarcia</groupId>
            <artifactId>webdrivermanager</artifactId>
            <version>3.8.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.codeborne/selenide -->
        <dependency>
            <groupId>com.codeborne</groupId>
            <artifactId>selenide</artifactId>
            <version>5.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.5</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.5</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.version}</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

我的 testng.xml 文件是下一个:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Google Suite" verbose="1" thread-count="1" parallel="tests" configfailurepolicy="continue">
    <test name="Google UI automation">
        <classes>
            <class name="runners.testNGCucumberRunner">
                <methods>
                    <include name="scenario"/>
                </methods>
            </class>
        </classes>
    </test>
</suite>

与之前命名的功能相关的页面是下一个:

package pages;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

import java.io.IOException;

public class Page_First extends BasePage{

    /////////////Constructor/////////////

    public Page_First(WebDriver driver) {
        super(driver);
    }

    //////////////////////////////////////////////WEB ELEMENTS//////////////////////////////////////////////////////////

    @FindBy(name = "q")
    private WebElement searchText;

    @FindBy(name="btnK")
    private WebElement searchButton;

    //////////////////////////////////////////////BASE METHODS//////////////////////////////////////////////////////////

    public void search(String search) throws IOException {
        setTextAs(searchText, search);
    }

    public void enterButton (){
        clickElement(searchButton);
    }
}

与此相关的步骤定义类是下一个:

package steps;

import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.PageFactory;
import pages.BasePage;
import pages.Page_First;
import utilities.LoadProperties;

import java.io.IOException;
import java.util.logging.Logger;

public class Step_First {

    private WebDriver driver;
    private BasePage basepage;


    private Page_First page_first = PageFactory.initElements(driver, Page_First.class);


    private static final java.util.logging.Logger log = Logger.getLogger(Page_First.class.getName());
    LoadProperties load = new LoadProperties();


    public Step_First(WebDriver driver){

        this.driver = driver;
    }


    @Given("I go to {string} Google")
    public void I_go_to_Google (String Url) {

        load.getUrl();
    //    basepage.navigate(Url);
    }

    @When("I query for {string} cucumber spring selenium")
    public void I_query_for_cucumber_spring_selenium (String search) throws IOException {

        page_first.search(search);
    }

    @When("click search")
    public void click_search(){

        page_first.enterButton();
    }

    @Then("google page title should become the first page")
    public void google_page_title_should_become_the_first_page() {

        log.info("All OK");

    }
}

在所有这些信息和类以及更多类之后,我真的不知道我在哪里失败了,因为当我从 IDE (IntelliJ IDEA)运行testNGCucumberRunner类时,我在控制台中遇到了下一个错误:

    @test
  Scenario: Search google.com to verify google search is working # src/test/java/features/first.feature:6
    Given I go to "<Url>" Google                                 # Step_First.I_go_to_Google(String)
      org.picocontainer.injectors.AbstractInjector$UnsatisfiableDependenciesException: steps.Step_First has unsatisfied dependency 'interface org.openqa.selenium.WebDriver' for constructor 'public steps.Step_First(org.openqa.selenium.WebDriver)' from org.picocontainer.DefaultPicoContainer@4c12331b:1<|
    at org.picocontainer.injectors.ConstructorInjector.getGreediestSatisfiableConstructor(ConstructorInjector.java:191)
    at org.picocontainer.injectors.ConstructorInjector.getGreediestSatisfiableConstructor(ConstructorInjector.java:110)
    at org.picocontainer.injectors.ConstructorInjector.access$100(ConstructorInjector.java:51)
    at org.picocontainer.injectors.ConstructorInjector$1.run(ConstructorInjector.java:331)
    at org.picocontainer.injectors.AbstractInjector$ThreadLocalCyclicDependencyGuard.observe(AbstractInjector.java:270)
    at org.picocontainer.injectors.ConstructorInjector.getComponentInstance(ConstructorInjector.java:364)
    at org.picocontainer.injectors.AbstractInjectionFactory$LifecycleAdapter.getComponentInstance(AbstractInjectionFactory.java:56)
    at org.picocontainer.behaviors.AbstractBehavior.getComponentInstance(AbstractBehavior.java:64)
    at org.picocontainer.behaviors.Stored.getComponentInstance(Stored.java:91)
    at org.picocontainer.DefaultPicoContainer.getInstance(DefaultPicoContainer.java:699)
    at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:647)
    at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:678)
    at cucumber.runtime.java.picocontainer.PicoFactory.getInstance(PicoFactory.java:40)
    at cucumber.runtime.java.JavaStepDefinition.execute(JavaStepDefinition.java:48)
    at cucumber.runtime.PickleStepDefinitionMatch.runStep(PickleStepDefinitionMatch.java:50)
    at cucumber.runner.TestStep.executeStep(TestStep.java:55)
    at cucumber.runner.TestStep.run(TestStep.java:42)
    at cucumber.runner.PickleStepTestStep.run(PickleStepTestStep.java:53)
    at cucumber.runner.TestCase.run(TestCase.java:47)
    at cucumber.runner.Runner.runPickle(Runner.java:44)
    at cucumber.api.testng.TestNGCucumberRunner.runScenario(TestNGCucumberRunner.java:56)
    at runners.testNGCucumberRunner.scenario(testNGCucumberRunner.java:33)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
    at org.testng.TestRunner.privateRun(TestRunner.java:648)
    at org.testng.TestRunner.run(TestRunner.java:505)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
    at org.testng.SuiteRunner.run(SuiteRunner.java:364)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
    ...
    at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
    at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:110)
    at ✽.I go to "<Url>" Google (src/test/java/features/first.feature:8)

我认为与picocontainer依赖相关(包含在我的 POM 中),但我无法解决失败的问题。

Failed scenarios:
src/test/java/features/first.feature:6 # Search google.com to verify google search is working

1 Scenarios (1 failed)
4 Steps (1 failed, 3 skipped)
0m0.071s

org.picocontainer.injectors.AbstractInjector$UnsatisfiableDependenciesException: steps.Step_First has unsatisfied dependency 'interface org.openqa.selenium.WebDriver' for constructor 'public steps.Step_First(org.openqa.selenium.WebDriver)' from org.picocontainer.DefaultPicoContainer@4c12331b:1<|
    at org.picocontainer.injectors.ConstructorInjector.getGreediestSatisfiableConstructor(ConstructorInjector.java:191)
    at org.picocontainer.injectors.ConstructorInjector.getGreediestSatisfiableConstructor(ConstructorInjector.java:110)
    at org.picocontainer.injectors.ConstructorInjector.access$100(ConstructorInjector.java:51)
    at org.picocontainer.injectors.ConstructorInjector$1.run(ConstructorInjector.java:331)
    at org.picocontainer.injectors.AbstractInjector$ThreadLocalCyclicDependencyGuard.observe(AbstractInjector.java:270)
    at org.picocontainer.injectors.ConstructorInjector.getComponentInstance(ConstructorInjector.java:364)
    at org.picocontainer.injectors.AbstractInjectionFactory$LifecycleAdapter.getComponentInstance(AbstractInjectionFactory.java:56)
    at org.picocontainer.behaviors.AbstractBehavior.getComponentInstance(AbstractBehavior.java:64)
    at org.picocontainer.behaviors.Stored.getComponentInstance(Stored.java:91)
    at org.picocontainer.DefaultPicoContainer.getInstance(DefaultPicoContainer.java:699)
    at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:647)
    at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:678)
    at cucumber.runtime.java.picocontainer.PicoFactory.getInstance(PicoFactory.java:40)
    at cucumber.runtime.java.JavaStepDefinition.execute(JavaStepDefinition.java:48)
    at cucumber.runtime.PickleStepDefinitionMatch.runStep(PickleStepDefinitionMatch.java:50)
    ...
    at cucumber.api.testng.TestNGCucumberRunner.runScenario(TestNGCucumberRunner.java:56)
    at runners.testNGCucumberRunner.scenario(testNGCucumberRunner.java:33)
    ...
    at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:110)
    at ✽.I go to "<Url>" Google (src/test/java/features/first.feature:8)



===============================================
Default Suite
Total tests run: 1, Failures: 0, Skips: 1
===============================================

有人可以帮我吗?提前致谢。

4

2 回答 2

2

我同意楼上的回答。作为一个更好的解决方案,使用“测试上下文”类来存储所有需要的对象,同时交换多个步骤类。

测试上下文类可以存储:

  • WebDriver 对象,
  • 页面对象,
  • DataReader 对象等

使用页面对象管理器来保存页面类。下面是页面对象管理器类中的代码段。

private HomePage;  
public HomePage getHomePage(){
      return (homePage == null) ? homePage = new HomePage(driver) : homePage;
      }

请也参考这个。 https://cucumber.io/blog/bdd/polymorphic-step-definitions/

于 2020-04-19T19:13:03.317 回答
1

仔细阅读异常消息很重要。该异常与 pico 容器无关。而是 pico 容器告诉您步骤定义存在问题。

org.picocontainer.injectors.AbstractInjector$UnsatisfiableDependenciesException:
steps.Step_First has unsatisfied dependency 'interface org.openqa.selenium.WebDriver'
for constructor 'public steps.Step_First(org.openqa.selenium.WebDriver)'
from org.picocontainer.DefaultPicoContainer@4c12331b:1<|

所以 . 的构造函数有问题First_Step。它有一个不满足的依赖关系。这意味着 pico 容器无法弄清楚如何创建它的实例First_Step

    public Step_First(WebDriver driver){

        this.driver = driver;
    }

如果您查看构造函数,您可以看到它声明了对WebDriver. 因此,您必须先拥有 的实例,WebDriver然后才能创建Step_First. 通常 pico 容器会尝试为您创建 Web 驱动程序。但是因为WebDriver是一个接口,所以它不能创建它的实例。

因此,您可能希望改为注入ServiceHooks,因为在该类中您正在创建WebDriver.

于 2020-02-19T23:16:26.770 回答