在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();
}
}
2条答案
按热度按时间7uzetpgm1#
有几件事你需要明白。第一件事与关键字有关
static
. 我只想谈谈与这个问题有关的信息。然后一个类的字段标记为
static
,这意味着该类的每个示例都共享一个确切的变量。让我们看看你的BaseTest
班级:如果类a和类b都创建
BaseTest
还有一套AppiumDriver
,如果第二个类也创建自己的示例,则不必设置驱动程序BaseTest
. 同样,如果类b更改AppiumDriver
,它也改变了AppiumDriver
物品由BaseTest
类创建的对象。这是将字段(变量)标记为静态的效果。第二件事与执行顺序有关。记住,如果类a和类b都创建
BaseTest
一次一套AppiumDriver
这两种情况都有。但是,如果没有设置驱动程序的类尝试先使用它呢?那样的话,你会得到NullPointerException
毫无疑问。也就是说,正如@rzwitserloot在他或她的帖子中提到的,执行的顺序是由注解控制的@BeforeClass
. 所以你的教授是对的,因为,示例化的类
BaseTest
有一个在执行任何测试之前被调用的方法,此方法设置AppiumDriver
对象,以及这个
AppiumDriver
对象是静态的,这意味着BaseTest
共享同一驱动程序对象。dgenwo3n2#
原因是
@BeforeClass
注解。