java—从不同的类示例化同一个类

zzoitvuj  于 2021-07-12  发布在  Java
关注(0)|答案(2)|浏览(338)

在basetest.java中,我有一个初始化appiumdriver类型的对象的方法。在logintest.java中,我创建了一个basetest类的示例并调用initializedriver方法。同样在loginpage.java中,我正在创建basetest类的另一个示例,但我没有调用initializedriver方法。因为在loginpage.java中,我只创建了basetest类的一个示例,而没有调用initializedriver方法,所以与loginpage.java的basetest示例关联的驱动程序对象不是应该为null吗?
这个程序的工作原理和我的老师解释的一样,但我只是不明白它是如何工作的,因为在loginpage.java base.getdriver()应该是空的,因为我从来没有在那里调用过initializedriver方法。
基本测试.java

package com.qa;

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

import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;

import com.utils.TestUtils;

import io.appium.java_client.AppiumDriver;
import io.appium.java_client.MobileElement;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.pagefactory.AppiumFieldDecorator;
import io.appium.java_client.remote.MobileCapabilityType;

public class BaseTest {

    public BaseTest() {

    }

    protected static AppiumDriver driver;
    protected static Properties prop;
    protected FileInputStream fis;
    protected String dir;

    public void setDriver(AppiumDriver driver) {

        this.driver=driver;
    }

    public AppiumDriver getDriver() {

        return driver;
    }

    public void initializeDriver(String platformName,String platformVersion, String deviceName) {

        try {

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

            prop=new Properties();
            prop.load(fis);

            DesiredCapabilities cap=new DesiredCapabilities(); 

            cap.setCapability(MobileCapabilityType.PLATFORM_NAME, platformName);
            cap.setCapability(MobileCapabilityType.PLATFORM_VERSION, platformVersion);
            cap.setCapability(MobileCapabilityType.DEVICE_NAME, deviceName);
            cap.setCapability(MobileCapabilityType.AUTOMATION_NAME, prop.getProperty("UIAutomator2"));
            //cap.setCapability(MobileCapabilityType.UDID, "50");

            String appURL=dir+File.separator+prop.getProperty("appLocation"); 
            cap.setCapability(MobileCapabilityType.APP, appURL); // if you want to install and launch a new app
            cap.setCapability("autoGrantPermissions", true);
            //cap.setCapability(MobileCapabilityType.BROWSER_NAME, "Chrome");
            //cap.setCapability("chromedriverExecutable", "C:\\chromedriver-mobile_browser\\chromedriver.exe");
            //cap.setCapability("newCommandTimeout", 900); //how long 
            cap.setCapability("appPackage", prop.getProperty("androidAppPackage"));
            cap.setCapability("appActivity", prop.getProperty("androidAppActivity"));
            cap.setCapability("autoAcceptAlerts", "true"); // to accept all alerts
            //cap.setCapability("avdLaunchTimeout", "300000");
            cap.setCapability("unlockType", "pin");
            cap.setCapability("unlockKey", "74159");

            URL url=new URL(prop.getProperty("appiumURL"));

             driver=new AndroidDriver(url,cap);
             String sessionID=driver.getSessionId().toString();

        }
        catch(Exception e) {

            e.printStackTrace();

        }

    }

    public void waitForVisibility(MobileElement e) {

        WebDriverWait wait=new WebDriverWait(driver,TestUtils.WAIT);
        wait.until(ExpectedConditions.visibilityOf(e));

    }

    public void click(MobileElement e) {

        waitForVisibility(e);
        e.click();
    }

    public void sendKeys(MobileElement e, String keys) {

        waitForVisibility(e);
        e.sendKeys(keys);

    }

    public String getAttribute(MobileElement e, String attribute) {

        waitForVisibility(e);
        return e.getAttribute(attribute);

    }

    public void quitDriver() {

        driver.quit();
    }

}

登录测试.java

package com.qa.test;
import org.testng.annotations.Test;
import com.qa.BaseTest;
import com.qa.pages.LoginPage;
import com.qa.pages.ProductsPage;
import io.appium.java_client.AppiumDriver;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Parameters;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import java.lang.reflect.Method;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
public class LogInTest{
    LoginPage logInPage;
    ProductsPage productsPage;
    BaseTest base;
    AppiumDriver driver;

    @Parameters({"platformName","platformVersion","deviceName"})
    @BeforeClass
    public void beforeClass(String platformName,String platformVersion,String deviceName) {

        base=new BaseTest();
        base.initializeDriver(platformName, platformVersion, deviceName);

    }

    @AfterClass
    public void afterClass() {

        base.quitDriver();
    }

  @BeforeMethod
  public void beforeMethod(Method m) {

      logInPage=new LoginPage();
      productsPage=new ProductsPage();
      System.out.println("Current test being executed "+m.getName());
  }

  @Test
  public void invalidUserName() {
      logInPage.enterUsername("Incorrect user");
      logInPage.enterPassword("secret_sauce");
      logInPage.clickLoginBtn();

      String expectedMsg="Username and password do not match any user in this service.";
      String errMsg=logInPage.getErrTxt();
      System.out.println("Error message is "+ errMsg);
      Assert.assertEquals(expectedMsg, errMsg);
  }

  @Test
  public void invalidPassword() {
      logInPage.enterUsername("standard_user");
      logInPage.enterPassword("Incorrect Password");
      logInPage.clickLoginBtn();

      String expectedMsg="Username and password do not match any user in this service.";
      String errMsg=logInPage.getErrTxt();
      System.out.println("Error message is "+ errMsg);
      Assert.assertEquals(expectedMsg, errMsg);
  }

  @Test
  public void validCredentials() {
      logInPage.enterUsername("problem_user");
      logInPage.enterPassword("secret_sauce");
      logInPage.clickLoginBtn();

      String title="PRODUCTS";
      String actTitle=productsPage.getTitle();
      System.out.println("Actual title is "+ actTitle);
      Assert.assertEquals(actTitle, title);
  }
}

登录页.java

package com.qa.pages;

import org.openqa.selenium.support.PageFactory;

import com.qa.BaseTest;

import io.appium.java_client.AppiumDriver;
import io.appium.java_client.MobileElement;
import io.appium.java_client.pagefactory.AndroidFindBy;
import io.appium.java_client.pagefactory.AppiumFieldDecorator;

public class LoginPage {
    BaseTest base;

    public LoginPage() {
        base=new BaseTest();
        PageFactory.initElements(new AppiumFieldDecorator(base.getDriver()), this);
    }

    @AndroidFindBy(accessibility="test-Username")
    private MobileElement userNameTxtFld;

    @AndroidFindBy(accessibility="test-Password")
    private MobileElement passWordTxtFld;

    @AndroidFindBy(accessibility="test-LOGIN")
    private MobileElement logInBtn;

    @AndroidFindBy(xpath="//android.view.ViewGroup[@content-desc=\"test-Error message\"]/android.widget.TextView")
    private MobileElement errMsg;

    public LoginPage enterUsername(String userName) {

        base.sendKeys(userNameTxtFld,userName);

        return this;
    }

public LoginPage enterPassword(String passWord) {

        base.sendKeys(passWordTxtFld,passWord);

        return this;
    }

public String getErrTxt() {

    return base.getAttribute(errMsg,"text");

}

public ProductsPage clickLoginBtn() {

    base.click(logInBtn);

    return new ProductsPage();

}
}
7uzetpgm

7uzetpgm1#

有几件事你需要明白。第一件事与关键字有关 static . 我只想谈谈与这个问题有关的信息。
然后一个类的字段标记为 static ,这意味着该类的每个示例都共享一个确切的变量。让我们看看你的 BaseTest 班级:

public class BaseTest {
    public BaseTest() {} 

    protected static AppiumDriver driver; // shared variable
    ...
    protected String dir; // not shared

    public void setDriver(AppiumDriver driver) {
        this.driver=driver;
    }

... // more stuff in the class
}

如果类a和类b都创建 BaseTest 还有一套 AppiumDriver ,如果第二个类也创建自己的示例,则不必设置驱动程序 BaseTest . 同样,如果类b更改 AppiumDriver ,它也改变了 AppiumDriver 物品由 BaseTest 类创建的对象。这是将字段(变量)标记为静态的效果。
第二件事与执行顺序有关。记住,如果类a和类b都创建 BaseTest 一次一套 AppiumDriver 这两种情况都有。但是,如果没有设置驱动程序的类尝试先使用它呢?那样的话,你会得到 NullPointerException 毫无疑问。也就是说,正如@rzwitserloot在他或她的帖子中提到的,执行的顺序是由注解控制的 @BeforeClass . 所以你的教授是对的,因为,
示例化的类 BaseTest 有一个在执行任何测试之前被调用的方法,此方法设置 AppiumDriver 对象,以及
这个 AppiumDriver 对象是静态的,这意味着 BaseTest 共享同一驱动程序对象。

dgenwo3n

dgenwo3n2#

原因是 @BeforeClass 注解。

相关问题