Selenium 在“中测试不同的场景;爪哇硒黄瓜&x201D;不打开新的Web浏览器

Selenium 在“中测试不同的场景;爪哇硒黄瓜&x201D;不打开新的Web浏览器,selenium,selenium-webdriver,webdriver,cucumber,cucumber-jvm,Selenium,Selenium Webdriver,Webdriver,Cucumber,Cucumber Jvm,我有一个功能文件,其中有两个场景 Feature: Login to Online Store Scenario: Login successful with valid credentials Given User is on Home Page When User navigates to Login Page And User provides username and password Then Message displays Login succes

我有一个功能文件,其中有两个场景

Feature: Login to Online Store

Scenario: Login successful with valid credentials
    Given User is on Home Page
    When User navigates to Login Page
    And User provides username and password
    Then Message displays Login successfully

Scenario: User logout successfully
    When User logouts from application
    Then Message displays Logout successfully
每次我运行RunFeatures.java文件时,在第一个场景之后,驱动程序打开新浏览器以执行下一个场景我们可以使用相同的浏览器来执行第二个场景吗? 下面是我的代码:

RunFeatures.java

package cucumbertest;

import org.junit.runner.RunWith;

import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)
@CucumberOptions(features="src/test/java/features/"
            ,glue={"steps"}
            ,dryRun=false
            ,monochrome=false)

public class RunFeatures
{
}
ClientSteps.java:

package steps;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

import cucumber.api.java.en.*;
import pages.HomePage;
import pages.LoginPage;

public class ClientSteps
{
    WebDriver driver=new FirefoxDriver();
    @Given("^User is on Home Page$")
    public void user_is_on_Home_Page() throws Throwable {
        new HomePage(driver).user_is_on_Home_Page();
    }

    @When("^User navigates to Login Page$")
    public void user_navigates_to_Login_Page() throws Throwable {
        new HomePage(driver).user_navigates_to_Login_Page();
    }

    @When("^User provides username and password$")
    public void user_provides_username_and_password() throws Throwable {
        new LoginPage(driver).user_provides_username_and_password();
    }

    @Then("^Message displays Login successfully$")
    public void message_displays_Login_successfully() throws Throwable {
        new LoginPage(driver).message_displays_Login_successfully();
    }

    @When("^User logouts from application$")
    public void user_logouts_from_application() throws Throwable {
        new LoginPage(driver).user_Logout_from_the_Application();
    }

    @Then("^Message displays Logout successfully$")
    public void message_displays_Logout_successfully() throws Throwable {
        new LoginPage(driver).message_displayed_Logout_successfully();
    }
}
Homepage.java文件

package pages;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

import cucumber.api.java.en.Given;
import cucumber.api.java.en.When;

public class HomePage
{
    WebDriver driver;


    public HomePage(WebDriver driver)
    {
        this.driver=driver;     

    }
    public void user_is_on_Home_Page() throws Throwable {

        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        driver.manage().window().maximize();
        driver.get("http://www.store.demoqa.com");

    }

    public void user_navigates_to_Login_Page() throws Throwable {
        driver.findElement(By.xpath(".//*[@id='account']/a")).click();
    }

}
LoginPage.java

package pages;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;

import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;

public class LoginPage
{
    WebDriver driver;
    public LoginPage(WebDriver driver)
    {
        this.driver=driver;
    }

    public void user_provides_username_and_password() throws Throwable {
        // This is to get the first data of the set (First Row + First Column)
        driver.findElement(By.id("log")).sendKeys("tri.nguyen");
        // This is to get the first data of the set (First Row + Second Column)
        driver.findElement(By.id("pwd")).sendKeys("Test@123");
        driver.findElement(By.id("login")).click();
    }


    public void message_displays_Login_successfully() throws Throwable {
        System.out.println("Login Successfully");
    }

    public void user_Logout_from_the_Application() throws Throwable {
        driver.findElement (By.xpath(".//*[@id='account_logout']/a")).click();
    }


    public void message_displayed_Logout_successfully() throws Throwable {
        System.out.println("Logout Successfully");
        driver.quit();
    }
}

作为一种良好的实践,测试用例应该是原子的。自动化测试用例不应该依赖于浏览器实例、数据等的另一个测试用例

您应该在每个测试用例之后关闭所有浏览器窗口,并作为下一个测试用例的新实例再次打开浏览器


在stefdef文件中使用@Before和@After可以实现这一点

由于文字限制,我无法添加评论,请再次将其作为答案写在这里!这是我上一篇文章的延续。你可以试试这个。将@替换为以下内容

WebDriver driver;
    @Before
    public void setUp(){
        driver=new FirefoxDriver();
    }

    @After
    public void cleanUp(){
        driver.quit();
    }
    @Given("^User is on Home Page$")
    public void user_is_on_Home_Page() throws Throwable {
        new HomePage(driver).user_is_on_Home_Page();
    }  
确保只导入以下文件,而不导入junit*

import cucumber.api.java.After;
import cucumber.api.java.Before;

我试图按照您的指示修改代码,但出现NullPointer异常:

WebDriver driver;
    @Before
    public void setUp(){
        WebDriver driver=new FirefoxDriver();
    }

    @After
    public void cleanUp(){
        driver.quit();
    }

    @Given("^User is on Home Page$")
    public void user_is_on_Home_Page() throws Throwable {
        new HomePage(driver).user_is_on_Home_Page();
    }
例外情况:

java.lang.NullPointerException
    at pages.HomePage.user_is_on_Home_Page(HomePage.java:24)
    at steps.ClientSteps.user_is_on_Home_Page(ClientSteps.java:30)
    at ✽.Given User is on Home Page(Login.feature:4)

java.lang.NullPointerException
    at steps.ClientSteps.cleanUp(ClientSteps.java:25)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)

我再次无法将其添加为注释:(。 您已经在setup方法中声明并实例化了驱动程序变量,这使得它仅在setup方法中是本地的。请在类级别声明驱动程序

WebDriver driver;
    @Before
    public void setUp(){
        driver=new FirefoxDriver();
    }

这应该行得通。如果您遇到任何问题,请告诉我,我们可能会出去解决它。

这是因为您在steps类中实例化了WebDriver。您应该研究如何使用钩子。我做了一些研究,发现cucumber jvm默认不支持全局钩子,但您可以尝试一些解决方法。谢谢@RemcoW。你能告诉我更多关于钩子的细节吗?我对Selenium是新手。你有什么文档/资料我可以参考吗?这本书读得很好。(。我在这个博客上有作者写的书,我可能会在我自己的博客上发布一些例子来简化()。我可能只同意这一理论的一部分。我们应该尽可能多地模仿我们的测试用例,作为一个用户,我不会在每次交易后关闭浏览器。我希望随机将驱动程序实例传递给我的测试用例。如果您的浏览器窗口因某种原因关闭,您可能不希望下一个测试用例失败。T出现这种情况可能有多种原因。考虑到在网格/服务器上运行每日/夜间套件以及数千个其他selenium测试,浏览器故障可能是非常常见的事情。以下摘录自[Cucumber for Java书籍]().这本书是由cucumber的发明者撰写的。在编写场景时,有一个非常重要的概念需要掌握:每个场景必须有意义,并且能够独立于任何其他场景执行。第3章第38页感谢Abhijeet,它仍然不起作用。org.openqa.selenium.NoSuchElementException:无法定位元素:{“方法”:“xpath”,“选择器”:“/*[@id='account\u logout']]/a”}命令持续时间或超时:28毫秒。在第一个方案运行结束后,浏览器将关闭。我希望第二个方案在第一个方案后继续,而不关闭浏览器并实例一个新的。是否可能?现在是一个差异问题。对我而言,这似乎是一个同步问题。添加隐式等待。如果xpath正确且在然后,该页面将解决此问题。在driver=new FirefoxDriver()之后将其添加到安装方法中。
driver.manage().timeouts()。隐式等待(30,TimeUnit.SECONDS)
谢谢Abhijeet,正如我之前所说的。第二个场景将基于第一个场景,因此第一个场景之后的浏览器无法关闭,这样驱动程序就可以在第二个场景中找到元素。有可能吗?无论如何,我的挂起点是Quangtringuyen2005。您可以通过在@BeforeClass或d中声明驱动程序变量,在普通junit测试用例中实现这一点使用cucumber,我甚至不认为这是可能的,因为在调用stefdef类的每个场景中,它都被视为一个新实例。