我使用Selenium WebDriver(PageObject Pattern)和TestNG开发了一个测试框架。我的页面对象是使用pageFactory初始化的。
在运行单个实例时,一切正常。但是,当我增加实例(并行运行)时,只有一个实例检测到Web元素。
我不明白这个框架有什么问题。
我的框架如下:
DifferentBrowsers.java(用于安装驱动程序)
package com.tcs.rsf.utilities;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;
import jxl.read.biff.BiffException;
import org.apache.log4j.Logger;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import com.opera.core.systems.OperaDriver;
import com.tcs.rsf.excel2bean.ExcelToBeanRepoAddressedOffer;
public class DifferentBrowsers {
private WebDriver driver;
static Properties path = new Properties();
private static Logger log = Logger.getLogger(CrossBrowser.class);
public WebDriver getBrowser(String browserName, String browserType) throws MalformedURLException {
try {
path.load(new FileInputStream("path.properties"));
if (browserName.equalsIgnoreCase("firefox") && browserType.equalsIgnoreCase("local")) {
System.out
.println("---------------: Inside firefox profile :--------------");
DesiredCapabilities ff = DesiredCapabilities.firefox();
ff.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR,
UnexpectedAlertBehaviour.ACCEPT);
ff.setCapability(CapabilityType.SUPPORTS_JAVASCRIPT, true);
ff.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
ff.setCapability(CapabilityType.ENABLE_PERSISTENT_HOVERING, true);
ff.setCapability(CapabilityType.HAS_NATIVE_EVENTS, true);
driver = new FirefoxDriver(ff);
System.out
.println("==========:::: got firefox driver ::::===========");
} else if (browserName.equalsIgnoreCase("chrome") && browserType.equalsIgnoreCase("local")) {
System.out
.println("---------------: Inside chrome profile :--------------");
DesiredCapabilities chro = DesiredCapabilities.chrome();
chro.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR,
UnexpectedAlertBehaviour.ACCEPT);
chro.setCapability(CapabilityType.ACCEPT_SSL_CERTS,true);
chro.setCapability(CapabilityType.HAS_NATIVE_EVENTS,true);
chro.setCapability(CapabilityType.SUPPORTS_FINDING_BY_CSS,true);
chro.setCapability(CapabilityType.SUPPORTS_JAVASCRIPT,true);
chro.setCapability(CapabilityType.SUPPORTS_ALERTS,true);
chro.setCapability(CapabilityType.ENABLE_PERSISTENT_HOVERING, true);
System.setProperty("webdriver.chrome.driver",path.getProperty("chromeDriver2.6"));
driver = new ChromeDriver(chro);
System.out
.println("==========:::: got Chrome driver ::::===========");
} else if (browserName.equalsIgnoreCase("opera") && browserType.equalsIgnoreCase("local")) {
System.out
.println("---------------: Inside opera profile :--------------");
DesiredCapabilities opera = DesiredCapabilities.chrome();
opera.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR,
UnexpectedAlertBehaviour.IGNORE);
opera.setCapability("opera.binary","C:\\Program Files\\Opera\\launcher.exe");
driver = new OperaDriver(opera);
System.out
.println("==========:::: got opera driver ::::===========");
} else if (browserName.equalsIgnoreCase("firefox") && browserType.equalsIgnoreCase("remote")) {
System.out.println("---------------: Inside remote firefox profile :--------------");
DesiredCapabilities ff = DesiredCapabilities.firefox();
ff.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR,
UnexpectedAlertBehaviour.ACCEPT);
ff.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
ff.setCapability(CapabilityType.ENABLE_PERSISTENT_HOVERING, true);
ff.setCapability(CapabilityType.HAS_NATIVE_EVENTS, true);
ff.setCapability(CapabilityType.SUPPORTS_JAVASCRIPT, true);
driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), ff);
System.out.println("==========:::: got remote firefox driver ::::===========");
}
else if (browserName.equalsIgnoreCase("chrome") && browserType.equalsIgnoreCase("remote")) {
System.out.println("---------------: Inside remote chrome profile :--------------");
DesiredCapabilities chro = DesiredCapabilities.chrome();
chro.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR,
UnexpectedAlertBehaviour.ACCEPT);
chro.setCapability(CapabilityType.ACCEPT_SSL_CERTS,true);
chro.setCapability(CapabilityType.HAS_NATIVE_EVENTS,true);
chro.setCapability(CapabilityType.SUPPORTS_FINDING_BY_CSS,true);
chro.setCapability(CapabilityType.SUPPORTS_JAVASCRIPT,true);
chro.setCapability(CapabilityType.SUPPORTS_ALERTS,true);
chro.setCapability(CapabilityType.ENABLE_PERSISTENT_HOVERING, true);
System.setProperty("webdriver.chrome.driver",path.getProperty("chromeDriver2.6"));
chro.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), chro);
System.out.println("==========:::: got remote Chrome driver ::::===========");
} else if (browserName.equalsIgnoreCase("opera") && browserType.equalsIgnoreCase("remote")) {
System.out
.println("---------------: Inside remote opera profile :--------------");
DesiredCapabilities opera = DesiredCapabilities.opera();
opera.setCapability(CapabilityType.UNEXPECTED_ALERT_BEHAVIOUR,
UnexpectedAlertBehaviour.IGNORE);
opera.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), opera);
System.out.println("==========:::: got remote opera driver ::::===========");
}
else {
System.out.println("default firefox driver called");
driver = new FirefoxDriver();
}
} catch (IOException e) {
log.error("An error occured while instantiating driver.");
e.printStackTrace();
}
return driver;
}
}
PageBase.java(所有页面对象的父类…所有实用方法都在这里)
package com.tcs.rsf.pages;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.Point;
import org.openqa.selenium.StaleElementReferenceException;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import com.opera.core.systems.OperaDriver;
import com.tcs.rsf.exception.ElementNotVisibleException;
import com.tcs.rsf.utilities.CrossBrowser;
import com.tcs.rsf.utilities.Utility;
import com.tcs.rsf.utilities.Verification;
public class PageBase {
Utility util = new Utility();
protected WebDriver driver;
protected WebElement element;
private static Logger log = Logger.getLogger(PageBase.class);
public static final int IMPLICIT_TIMEOUT_VALUE = 30; // seconds
public static final int EXPLICIT_TIMEOUT_VALUE = 30; // seconds
public static final int PAGELOAD_TIMEOUT_VALUE = 10; // seconds
static Properties path = new Properties();
Verification verification=new Verification();
public void sleeper(int timeInMilliSeconds) {
try {
Thread.sleep(timeInMilliSeconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void open(String url) {
Assert.assertNotNull(this.driver);
this.driver.get(url);
}
public void close() {
this.driver.quit();
}
public String getTitle() {
return this.driver.getTitle();
}
public void implicitTimeout() {
this.driver.manage().timeouts()
.implicitlyWait(IMPLICIT_TIMEOUT_VALUE, TimeUnit.SECONDS);
}
public void logOut() {
this.driver.findElement(By.id("forLogout")).click();
}
PageObject.java(我的页面对象…扩展PageBase)
package com.tcs.rsf.pages;
import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import com.tcs.rsf.dao.SeclendOverlayDao;
import com.tcs.rsf.dao.SeclendTradingDAO;
import com.tcs.rsf.dao.SeclendVerificationDAO;
import com.tcs.rsf.utilities.Utility;
public class PageObject extends PageBase {
public PageObject(WebDriver driver) {
super(driver);
super.driver = driver; //gets driver from parent class
}
WebDriverWait wait = new WebDriverWait(driver, EXPLICIT_TIMEOUT_VALUE);
Utility utilities = new Utility();
@FindBy(id = "abc")
private WebElement findAbc;
@FindBy(xpath= "//input[@id='xyz']")
private WebElement findXyz;
@FindBy(id = "sample")
private WebElement findSample;
public void clickABCButton() {
findAbc.click();
}
public void isXyzLabelPresent() {
Assert.assertEquals(findXyz.getText(), "");
}
TestBase.java(测试脚本的父类……所有之前,之后etc方法都在这里……页面对象在这里通过页面工厂实现)
package com.tcs.rsf.testbases;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Properties;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.PageFactory;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Parameters;
import com.tcs.rsf.pages.MarketWatchPage;
import com.tcs.rsf.utilities.CrossBrowser;
import com.tcs.rsf.utilities.Zip;
public class TestBase {
protected PageObject page;
@Parameters(value={"browser","browserType"})
@BeforeClass
public void startUp(String browser,String browserType) {
try {
page = PageFactory.initElements(DifferentBrowsers.getBrowser(browser,browserType), PageObject.class); //driver is obtained from DifferentBrowsers.java
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
@BeforeMethod
public void callBrowser() {
try {
path.load(new FileInputStream("path.properties"));
} catch (IOException e) {
e.printStackTrace();
}
page.open(//URL to navigate)); //open() is defined in PageBase.java
}
@AfterClass
public void closeBrowser() {
page.close(); // close() is defined in PageBase.java
}
TestScript.java(将执行的脚本…TestBase.java的孩子)
import com.tcs.rsf.exception.CustomSeleniumException;
import com.tcs.rsf.exception.PageLoadException;
import com.tcs.rsf.testbases.TestBase;
import com.tcs.rsf.utilities.Utility;
import java.io.PrintWriter;
import java.io.StringWriter;
import org.apache.log4j.Logger;
import org.testng.annotations.Test;
public class TestScript extends TestBase{
private static Logger log = Logger.getLogger(TestScript.class);
CustomSeleniumException customSeleniumException=new CustomSeleniumException();
PageLoadException pageLoadExceptionCheck =new PageLoadException();
Utility utilities =new Utility();
@Test
public void testCase() throws Exception {
try{
page.maximizeBrowser(); //defined in PageBase.java
page.implicitTimeout(); //defined in PageBase.java
pageLoadExceptionCheck.validatePageLoad(super.getBaseURL(),super.getTestDriver());
//**********Step 1**********//
//User logs into system with valid credentials.
page.login("username","password");
log.info("step 1 complete");
//**********Step 2**********//
//User check label Xyz
page.isXyzLabelPresent();
log.info("step 2 completed");
//**********Step 3**********//
//User clicks on Abc button
page.clickAbcButton();
log.info("step 3 complete");
}
catch(Exception e)
{
customSeleniumException.seleniumThrownException(e,super.getTestDriver());
log.error("An exception occured in test case");
}
}
}
testNG. xml(这控制执行流程以及实例和浏览器的数量)
<?xml version="1.0" encoding="UTF-8"?>
<suite name="TestSuite" parallel="tests" thread-count="3">
<parameter name="browser" value="firefox"></parameter>
<parameter name="browserType" value="local"></parameter>
<test name="Script_1">
<classes>
<class name="com.test.sample.testcases.TestScript"></class>
</classes>
</test>
<test name="Script_2">
<classes>
<class name="com.test.sample.testcases.TestScript2"></class>
</classes>
</test>
<test name="Script_3">
<classes>
<class name="com.test.sample.testcases.TestScript3"></class>
</classes>
</test>
<test name="Script_4">
<classes>
<class name="com.test.sample.testcases.TestScript4"></class>
</classes>
</test>
<test name="Script_5">
<classes>
<class name="com.test.sample.testcases.TestScript5"></class>
</classes>
</test>
</suite>
作为上面的测试脚本,我有500个这样的脚本要并行执行。但是,当并行执行时,脚本被实例化,但一次只有一个脚本正确执行,其他脚本不接收元素。
快速浏览后,您至少应该在第一类中摆脱静态WebDriver字段。