Как поместить общие методы, такие как получение конфигурации Webdriver и закрытие ресурсов в общий класс в Cucumber? - PullRequest
0 голосов
/ 11 апреля 2019

У меня есть Selenium тест, основанный на Cucumber и Spring Boot, который выдает исключение (ошибка, показанную ниже), когда я пытался упростить тест, перемещая методы setup() и closeBrowser() в родительский класс.

Если я обрежу и вставлю оба этих метода в файл GoogleCalcStepDefinition.java, все будет работать нормально, и тесты также пройдут без проблем.

Не уверен, как переместить эти общие методы в другой класс, чтобыупростить тесты и поддерживать сопровождение и расширяемость.

Я гуглил и нашел эту ссылку SO ( Определения шагов класса Cucumber и перехватчики ), но он не имеет никакого фрагмента кода и не предоставляетбольшая помощь.

Пожалуйста, руководство.

DemoApplicationTests.java

@RunWith(SpringRunner.class)
@SpringBootTest
public abstract class DemoApplicationTests {

    private static final String CHROME_DRIVER_EXE = "drivers/chromedriver.exe";
    private static final String WEBDRIVER_CHROME_DRIVER = "webdriver.chrome.driver";
    private WebDriver driver;
    private GoogleSearchPage googleSearchPage;

    @Before //this uses cucumber.api.Before (equivalent of JUnit @BeforeClass)
    public void setup() {
        String filePath = ClassLoader.getSystemClassLoader().getResource(CHROME_DRIVER_EXE).getFile();
        System.setProperty(WEBDRIVER_CHROME_DRIVER, filePath);
        ChromeOptions options = new ChromeOptions();
        options.setExperimentalOption("useAutomationExtension", false);
        driver = new ChromeDriver(options);
        googleSearchPage = PageFactory.initElements(driver, GoogleSearchPage.class);
    }

    @After //this uses cucumber.api.After (equivalent of JUnit @AfterClass)
    public void closeBrowser() {
        if (null != driver) {
            driver.close();
            driver.quit();
        }
    }

}

GoogleCalcStepDefinition.java

@Ignore
public class GoogleCalcStepDefinition extends DemoApplicationTests {

    @Given("^I open Google$")
    public void I_open_google() {
        //Set implicit wait of 5 seconds and launch google
        driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
        driver.get("https://www.google.co.in");
    }

    @When("^I enter \"([^\"]*)\" in search textbox$")
    public void I_enter_in_search_textbox(String additionTerms) {
        googleSearchPage.searchBox.sendKeys(additionTerms); //passing 2+2 here
        googleSearchPage.searchBtn.click();
    }

    @Then("^I should get result as \"([^\"]*)\"$")
    public void I_should_get_correct_result(String expectedResult) {
        String result = googleSearchPage.calculatorTextBox.getText();
        assertEquals(result, expectedResult); //Verify that result of 2+2 is 4
    }

}

TestRunner.java

@RunWith(Cucumber.class)
@CucumberOptions(
        plugin = {"pretty", "json:target/cucumber-reports/cucumber.json"},
        features = {"src/test/resources/features"})
public class TestRunner {

}

GoogleSearchPage.java

public class GoogleSearchPage {

    @FindBy(name = "q")
    WebElement searchBox;
    @FindBy(name = "btnK")
    WebElement searchBtn;
    @FindBy(id = "cwos")
    WebElement calculatorTextBox;

}

calc.feature (источник / тест / ресурсы / функции)

Feature: Check addition in Google calculatorcontent
  In order to verify that Google calculator work correctly
  As a user of Google
  I should be able to get correct addition result

  Scenario: Addition
    Given I open Google
    When I enter "2+2" in search textbox
    Then I should get result as "4"

pom.xml

<dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-java</artifactId>
        <version>4.2.3</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-junit</artifactId>
        <version>4.2.3</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.cucumber</groupId>
        <artifactId>cucumber-spring</artifactId>
        <version>4.2.3</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.seleniumhq.selenium</groupId>
                <artifactId>selenium-chrome-driver</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-chrome-driver</artifactId>
        <version>2.45.0</version>
        <scope>test</scope>
    </dependency>

Ошибка (при выполнении TestRunner):

cucumber.runtime.CucumberException: You're not allowed to extend classes that define Step Definitions or hooks. class com.example.GoogleCalcStepDefinition extends class com.example.DemoApplicationTests

    at cucumber.runtime.java.MethodScanner.validateMethod(MethodScanner.java:76)
    at cucumber.runtime.java.MethodScanner.scan(MethodScanner.java:62)
    at cucumber.runtime.java.MethodScanner.scan(MethodScanner.java:43)
    at cucumber.runtime.java.JavaBackend.loadGlue(JavaBackend.java:83)
    at cucumber.runner.Runner.<init>(Runner.java:28)
    at cucumber.runner.ThreadLocalRunnerSupplier.createRunner(ThreadLocalRunnerSupplier.java:42)
    at cucumber.runner.ThreadLocalRunnerSupplier.access$000(ThreadLocalRunnerSupplier.java:13)
    at cucumber.runner.ThreadLocalRunnerSupplier$1.initialValue(ThreadLocalRunnerSupplier.java:22)
    at cucumber.runner.ThreadLocalRunnerSupplier$1.initialValue(ThreadLocalRunnerSupplier.java:19)
    at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:180)
    at java.lang.ThreadLocal.get(ThreadLocal.java:170)
    at cucumber.runner.ThreadLocalRunnerSupplier.get(ThreadLocalRunnerSupplier.java:38)
    at cucumber.api.junit.Cucumber.<init>(Cucumber.java:106)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
    at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
    at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:33)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:49)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)


Process finished with exit code -1

Ответы [ 2 ]

0 голосов
/ 12 апреля 2019

Вы можете использовать среду с открытым исходным кодом QAF , которая отвечает за управление драйверами, управление ресурсами и другие потребности автоматизации функциональных тестов. Как только вы используете qaf, вы обнаружите, что весь код, связанный с настройкой и разборкой, является излишним, так как qaf позаботился об этом. Вы можете больше сосредоточиться на автоматизации функций AUT. См. ответ на аналогичный вопрос .

0 голосов
/ 12 апреля 2019

Если вы хотите совместно использовать WebDriver среди различных классов определения шагов, рассмотрите возможность использования шаблона Singleton Holder для вашего веб-драйвера.

Ваше определение шага не должно инициализировать веб-драйвер и ваш набор тестов, в идеале оно должно включать в себя только код, связанный с фактическим тестированием / утверждением, лучше было бы создать некоторый класс Test Manager (singleton), который инициализирует веб-драйвер и все, что нужно для запуска ваших тестов, загрузки свойств, настройки тестовых данных и т. д., а в ваших определениях шагов просто обратитесь к диспетчеру тестов.

Cucumber будет искать определение шага во всех классах, указанных в каталоге 'glue' из вашего класса бегуна. Итак, предположим, что у вас есть несколько тестовых сценариев, которые тестируют страницу входа и страницу магазина, вы можете иметь:

  • LoginSteps.java -> удерживать определения шагов для сценариев страницы входа
  • ShopSteps.java -> удерживать определения шагов для сценариев страницы магазина
  • CommonSteps.java -> содержит шаги, которые вы используете как при входе в систему, так и в магазине. (и другие)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...