java.lang.StackOverflowerError在selenium中作为testng测试运行类时

xzv2uavs  于 2021-08-20  发布在  Java
关注(0)|答案(4)|浏览(430)

这是一个演示项目,使用页面对象模式和数据驱动框架实现。
在继承下面,使用构造函数概念。
这个 config.prpoerties 文件包含用户名、密码、url和浏览器。

基类

package com.crm.qa.base;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.TimeUnit;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

import com.crm.qa.utilities.TestUtil;

public class TestBase {

    public static Properties prop;
    public static WebDriver driver;

    public TestBase() {

        //import variables from Config.properties file
        try {
            prop=new Properties();

            FileInputStream fis=new FileInputStream(System.getProperty("user.dir")+"/src/main/java/com/crm/qa/configuration/config.properties");

                prop.load(fis);         
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }   

    public static void  initialization()
    {
        String browser= prop.getProperty("browser");

        if(browser.equalsIgnoreCase("firefox"))
        {
            System.setProperty("webdriver.gecko.driver", "./Drivers/geckodriver.exe");
            FirefoxOptions firefoxOptions = new FirefoxOptions();
            firefoxOptions.setCapability("marionette", true);
            driver = new FirefoxDriver(firefoxOptions);     
        }

        if(browser.equalsIgnoreCase("chrome"))
        {
            System.setProperty("webdriver.chrome.driver", "./Drivers/chromedriver.exe");
            driver=new ChromeDriver();
        }

        driver.manage().window().maximize();
        driver.manage().deleteAllCookies();
        driver.manage().timeouts().pageLoadTimeout(TestUtil.PAGE_LOAD_TIMEOUT, TimeUnit.SECONDS); 
        driver.manage().timeouts().pageLoadTimeout(TestUtil.IMPLICIT_WAIT, TimeUnit.SECONDS); 
        driver.get(prop.getProperty("baseURL"));
    }               
}

登录页对象类

package com.crm.qa.pages;

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

import com.crm.qa.base.TestBase;

public class LoginPageCRM extends TestBase {

    //PageFactory
    @FindBy(name="username")
    WebElement username;

    @FindBy(name="password")
    WebElement password;

    @FindBy(xpath = "//input[@type='submit']")
    WebElement loginBtn;    

    @FindBy(xpath= "//a[contains(text(),'Sign Up')]")
    WebElement signUP;

    @FindBy(xpath="//img[contains(@class,'img-responsive')]")
    WebElement crmLogo;

    //to initialize page objects

    public LoginPageCRM()
    {
        PageFactory.initElements(driver, LoginPageCRM.class );
    }

    //Actions
    //1. verify title of page
    public String validateLoginPageTitle()
    {
        return driver.getTitle();

    }

    //2. Validate crm image
    public boolean validateCRMLogo()
    {
        return crmLogo.isDisplayed();
    }

    //3. Login
    public HomePageCRM login(String uname, String pwd)  
    {
        username.sendKeys(uname);
        password.sendKeys(pwd);
        loginBtn.click();

        return new HomePageCRM();
    }

}

<

ep6jt1vc

ep6jt1vc1#

我曾经遇到过这个错误。如何修复它,改变它

PageFactory.initElements(driver, LoginPageCRM.class );

PageFactory.initElements(driver, this);
brccelvz

brccelvz2#

PageFactory.initElements(driver, LoginPageCRM.class) 导致了 StackOverflowError 因为 initElements 尝试创建的对象 LoginPageCRM 通过调用它的构造函数。作为 LoginPageCRM 包含 PageFactory.initElements(driver, LoginPageCRM.class) ,这个过程会无限次重复,导致 StackOverflowError . 这是问题的根本原因。
由于我对 selenium 不太熟悉,我认为@lucasnguyen17的答案解释了如何修复它。但在通过考试之前,我建议做一些修改 this 到构造函数中的该方法。
注意:在您的情况下,以下提到的问题可能不会导致问题,因为没有其他与 this 在构造函数内部。但以下内容可作为一般指南/最佳实践
如果 this 施工期间参考“逃逸”。i、 e只有当构造函数完全执行时,对象才被称为正确构造。如果按照以下方式修复代码,则将一个未正确构造的对象传递给 initElements 方法。这可以被认为是类似于在建筑完工之前把房子租给别人。因此,这是一种错误的做法,不应该这样做,因为它可能会导致意外的结果,因为您可能不知道您正在调用的方法将如何处理您传递的对象。

public LoginPageCRM()
{
    // The object is not fully constructed at this point
    PageFactory.initElements(driver, this);
}

因此,我建议进行以下重构:
在里面 LoginPageCRM 只需创建一个默认构造函数,其中没有任何代码(如果类中没有其他构造函数,java实际上会创建一个构造函数)。然后创建一个方法来完成 PageFactory.initElements(driver, this) :

public LoginPageCRM()
{
}

public void init() {
    PageFactory.initElements(driver, this);
}

然后在 LoginTest 类,在构造 LoginPageCRM 对象,调用新的 init 方法,以便可以确保传递的是正确构造的对象。

@BeforeTest
public void setUP() {
    initialization();
    loginPage = new LoginPageCRM();
    loginPage.init();
}
xcitsw88

xcitsw884#

->

package com.crm.qa.testcases;

import org.testng.Assert;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import com.crm.qa.base.TestBase;
import com.crm.qa.pages.HomePageCRM;
import com.crm.qa.pages.LoginPageCRM;

public class LoginTest extends TestBase{

    public LoginTest()
    {
        super(); 
    }

    LoginPageCRM loginPage;
    public HomePageCRM homePageCRM;

    @BeforeTest
    public void setUP()
    {
    initialization();
    loginPage=new LoginPageCRM();
    }

    @Test(priority=1)
    public void LoginPageTitleTest()
    {
        String pageTitle= loginPage.validateLoginPageTitle();
        Assert.assertEquals(pageTitle,"CRMPRO  - CRM software for customer relationship management, sales, and support.");

    }

    @Test(priority=2)
    public void CRMLogoTest()
    {
        Assert.assertEquals(loginPage.validateCRMLogo(), true);
    }

    @Test(priority=3)
    public  void loginPageTest()
    {
        homePageCRM= loginPage.login(prop.getProperty("username"), prop.getProperty("password"));
    }

    @AfterTest
    public void tearDown()
    {
    driver.quit();      
    }

}

现在,当我以testng测试的形式运行logintest类时,控制台中出现如下错误-->

com.crm.qa.testcases.LoginTest#setUP

Exception

java.lang.StackOverflowError
    at java.base/java.util.stream.StreamOpFlag.fromCharacteristics(StreamOpFlag.java:733)
    at java.base/java.util.stream.StreamSupport.stream(StreamSupport.java:70)
    at java.base/java.util.Arrays.stream(Arrays.java:5446)
    at java.base/java.util.Arrays.stream(Arrays.java:5427)
    at java.base/java.lang.Class.methodToString(Class.java:3579)
    at java.base/java.lang.Class.getConstructor0(Class.java:3508)
    at java.base/java.lang.Class.getConstructor(Class.java:2244)
    at org.openqa.selenium.support.PageFactory.instantiatePage(PageFactory.java:128)
    at org.openqa.selenium.support.PageFactory.initElements(PageFactory.java:64)
    at com.crm.qa.pages.LoginPageCRM.<init>(LoginPageCRM.java:33)
    at jdk.internal.reflect.GeneratedConstructorAccessor9.newInstance(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
    at java.base/java.lang.reflect.ReflectAccess.newInstance(ReflectAccess.java:128)
    at java.base/jdk.internal.reflect.ReflectionFactory.newInstance(ReflectionFactory.java:350)
    at java.base/java.lang.Class.newInstance(Class.java:645)
    at org.openqa.selenium.support.PageFactory.instantiatePage(PageFactory.java:131)
    at org.openqa.selenium.support.PageFactory.initElements(PageFactory.java:64)
    at com.crm.qa.pages.LoginPageCRM.<init>(LoginPageCRM.java:33)
    at jdk.internal.reflect.GeneratedConstructorAccessor9.newInstance(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
    at java.base/java.lang.reflect.ReflectAccess.newInstance(ReflectAccess.java:128)
    at java.base/jdk.internal.reflect.ReflectionFactory.newInstance(ReflectionFactory.java:350)
    at java.base/java.lang.Class.newInstance(Class.java:645)
    at org.openqa.selenium.support.PageFactory.instantiatePage(PageFactory.java:131)
    at org.openqa.selenium.support.PageFactory.initElements(PageFactory.java:64)
    at com.crm.qa.pages.LoginPageCRM.<init>(LoginPageCRM.java:33)
    at jdk.internal.reflect.GeneratedConstructorAccessor9.newInstance(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)

 ........

我的eclipse版本:版本:2021-03(4.19.0)构建id:20210312-0638
eclipse.ini文件

-startup
plugins/org.eclipse.equinox.launcher_1.6.100.v20201223-0822.jar
--launcher.library
C:\Users\JACOB\.p2\pool\plugins\org.eclipse.equinox.launcher.win32.win32.x86_64_1.2.100.v20210209-1541
-product
org.eclipse.epp.package.java.product
-showsplash
C:\Users\JACOB\.p2\pool\plugins\org.eclipse.epp.package.common_4.19.0.20210311-1200
--launcher.defaultAction
openFile
--launcher.appendVmargs
-vm
C:/Program Files/Java/jdk-15.0.1/bin/javaw.exe
-vmargs
-Dosgi.requiredJavaVersion=11
-Dosgi.instance.area.default=@user.home/eclipse-workspace
-Dsun.java.command=Eclipse
-XX:+UseG1GC
-XX:+UseStringDeduplication
--add-modules=ALL-SYSTEM
-Dosgi.requiredJavaVersion=11
-Dosgi.dataAreaRequiresExplicitInit=true
-Dorg.eclipse.swt.graphics.Resource.reportNonDisposed=true
-Xms256m
-Xmx2048m
--add-modules=ALL-SYSTEM
-Declipse.p2.max.threads=10
-Doomph.update.url=http://download.eclipse.org/oomph/updates/milestone/latest
-Doomph.redirection.index.redirection=index:/->http://git.eclipse.org/c/oomph/org.eclipse.oomph.git/plain/setups/

相关问题