- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当 DataProvider 上的 parallel=true 时,并行执行测试会引发以下异常。两个浏览器实例将打开并在单独的线程上运行,但只有一个浏览器实例会成功执行,而另一个浏览器实例会陷入尝试查找元素并引发异常的情况。请问,当 dataprovider 中的parallel=true 时,如何使测试成功执行。我缺少一些东西,可能是 BasePage 中的 WebDriver 实例。请帮忙。谢谢。
[PoolService-1] 15:44:06,447 INFO [Default test] Close driver
PASSED: loginTest("unresticteduser@gmail.com", "123456")
FAILED: loginTest("resticteduser@gmail.com", "123456")
WARNING: WebDriverException thrown by findElement(By.xpath: //button[contains(text(), 'NO THANKS')])
org.openqa.selenium.WebDriverException: org.apache.http.conn.HttpHostConnectException: Connect to
localhost:8478 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect
当 dataprovider 上的parallel=false 时,测试将在数据输入到测试并成功执行时一次打开一个浏览器实例。
PASSED: loginTest("unresticteduser@gmail.com", "123456")
PASSED: loginTest("resticteduser@gmail.com", "123456")
这是我编写的代码:
1) 浏览器工厂
public class BrowserDriverFactory {
private ThreadLocal<WebDriver> driver = new ThreadLocal<WebDriver>();
private String browser;
private Logger log;
public BrowserDriverFactory(String browser, Logger log) {
this.browser = browser.toLowerCase();
this.log = log;
}
public WebDriver createDriver() {
// Create driver
log.info("Create driver: " + browser);
if(browser.equals("chrome")) {
System.setProperty("webdriver.chrome.driver", "src/main/resources/chromedriver.exe");
driver.set(new ChromeDriver());
}
else if(browser.equals("firefox")) {
System.setProperty("webdriver.gecko.driver", "src/main/resources/geckodriver.exe");
driver.set(new FirefoxDriver());
}
else {
System.out.println("Do not know how to start: " + browser + ", starting chrome.");
System.setProperty("webdriver.chrome.driver", "src/main/resources/chromedriver.exe");
driver.set(new ChromeDriver());
}
return driver.get();
}
}
2)基础测试
public class BaseTest {
protected WebDriver driver;
public WebDriverWait wait;
protected Logger log;
protected FirefoxProfile profile;
protected String url = "http://www.qaclickacademy.com/";
protected String testSuiteName;
protected String testName;
protected String testMethodName;
@BeforeMethod(alwaysRun = false)
public void setUp(Method method, ITestContext ctx) {
String testName = ctx.getCurrentXmlTest().getName();
log = LogManager.getLogger(testName);
BrowserDriverFactory factory = new BrowserDriverFactory(config.getBrowser(), log);
driver = factory.createDriver();
driver.get(url);
profile=new FirefoxProfile();
// Set preferences for file type
profile.setPreference("browser.helperApps.neverAsk.openFile", "application/octet-stream");
driver.manage().window().maximize();
wait = new WebDriverWait(driver, 5);
this.testSuiteName = ctx.getSuite().getName();
this.testName = testName;
this.testMethodName = method.getName();
}
@AfterMethod(alwaysRun = true)
public void tearDown(ITestResult result) {
if(result.getStatus()==ITestResult.FAILURE) {
//capture screenshot
}
log.info("Close driver");
// Close browser
driver.quit();
}
}
3)数据提供者
@DataProvider(name="SearchProvider", parallel=true)
public Object[][] getDataFromDataprovider(){
return new Object[][]
{
{ "unresticteduser@gmail.com", "123456" },
{ "resticteduser@gmail.com", "123456" }
};
}
4)基本页面
public class BasePage {
protected WebDriver driver;
public WebDriverWait wait;
protected Logger log;
public BasePage(WebDriver driver, Logger log) {
this.driver = driver;
this.log = log;
wait = new WebDriverWait(driver, 5);
}
protected void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
protected void clickStallElement(By locator) {
try {
waitForVisibilityOf(locator, 30);
findElement(locator).click();
}
catch(org.openqa.selenium.StaleElementReferenceException ex)
{
waitForVisibilityOf(locator, 30);
findElement(locator).click();
}
}
/** Open page with given URL */
protected void openUrl(String url) {
driver.get(url);
}
/** Find element using given locator */
protected WebElement findElement(By locator) {
return driver.findElement(locator);
}
/** Find all elements using given locator */
protected List<WebElement> findAllElements(By locator) {
return driver.findElements(locator);
}
/** Click on element with given locator when its visible */
protected void click(By locator) {
waitForVisibilityOf(locator, 30);
findElement(locator).click();
log.info("Clicked WebElement");
}
...
}
5) 基础测试
public class SignInPageTest extends BaseTest {
@Test(dataProvider = "SearchProvider", dataProviderClass = DBDataProvider.class)
public void loginTest(String username, String password) {
System.err.println("Running Test=> " + this + " -> on thread [" + Thread.currentThread().getId() + "]");
log.info("Starting LogInTest # for " + username);
ClickAcadamyLandingPage home = new ClickAcadamyLandingPage(driver, log);
home.openPage();
home.closeNewsLetterPopup();
// click login
ClickAcadamyLoginPage loginPage = new ClickAcadamyLoginPage(driver, log);
loginPage = home.clickLoginBtn();
loginPage.enterEmailAddress(username);
loginPage.enterPassword(password);
ClickAcadamyDashboard dashboard = loginPage.clickLogin();
dashboard.clickLogout();
}
}
6)testng.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" data-provider-thread-count = "2" thread-count="2" verbose="1" parallel="tests">
<listeners>
<listener class-name="com.paralleltest.basetest.TestListener"/>
</listeners>
<test name="loginTest">
<classes>
<class name="com.paralleltest.SignInPageTest"/>
</classes>
</test>
</suite>
最佳答案
问题出在你的测试代码上。当您并行运行测试并由数据提供程序提供支持时,您的 Webdriver 实例将在测试方法之间共享。
这是 BaseTest
和 BrowserDriverFactory
的修复版本,包含线程安全性。
import java.lang.reflect.Method;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
public class BaseTest {
private static final ThreadLocal<WebDriver> drivers = new ThreadLocal<>();
public WebDriverWait wait;
protected FirefoxProfile profile;
protected String url = "http://www.qaclickacademy.com/";
protected String testSuiteName;
protected String testName;
protected String testMethodName;
public WebDriver getDriver() {
return drivers.get();
}
@BeforeMethod()
public void setUp(Method method, ITestContext ctx) {
String testName = ctx.getCurrentXmlTest().getName();
WebDriver driver = BrowserDriverFactory.createDriver("firefox");
drivers.set(driver);
driver.get(url);
driver.manage().window().maximize();
wait = new WebDriverWait(driver, 5);
this.testSuiteName = ctx.getSuite().getName();
this.testName = testName;
this.testMethodName = method.getName();
}
@AfterMethod(alwaysRun = true)
public void tearDown(ITestResult result) {
getDriver().quit();
drivers.remove();
}
}
BrowserDriverFactory.java
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.firefox.FirefoxProfile;
public class BrowserDriverFactory {
public static WebDriver createDriver(String browser) {
System.err.println("Create driver: " + browser);
if (browser.equals("chrome")) {
System.setProperty("webdriver.chrome.driver", "src/main/resources/chromedriver.exe");
return new ChromeDriver();
} else if (browser.equals("firefox")) {
System.setProperty("webdriver.gecko.driver", "src/main/resources/geckodriver.exe");
FirefoxOptions options = new FirefoxOptions();
FirefoxProfile profile = new FirefoxProfile();
profile.setPreference("browser.helperApps.neverAsk.openFile", "application/octet-stream");
options.setProfile(profile);
return new FirefoxDriver(options);
}
System.out.println("Do not know how to start: " + browser + ", starting chrome.");
System.setProperty("webdriver.chrome.driver", "src/main/resources/chromedriver.exe");
return new ChromeDriver();
}
}
现在,在扩展 BaseTest
的测试类的所有测试方法中,每当您需要访问驱动程序对象时,您都可以通过调用 getDriver()
方法来获取它。
您可以在我的博客中找到完整的解释和更多相关解释:https://rationaleemotions.com/parallel_webdriver_executions_using_testng/
我还创建了一个库,它可以抽象出 webdriver 生命周期管理,并通过自定义注释使您的管理变得更加简单。
关于java - 当 DataProvider 上的并行设置为 true 时,并行执行测试会引发异常 - TestNG,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59827491/
问题很简单:我正在寻找一种优雅的使用方式 CompletableFuture#exceptionally与 CompletableFuture#supplyAsync 一起.这是行不通的: priva
对于 Web 服务,我们通常使用 maven-jaxb2-plugin 生成 java bean,并在 Spring 中使用 JAXB2 编码。我想知道如何处理 WSDL/XSD 中声明的(SOAP-
这个问题已经有答案了: Array index out of bound behavior (10 个回答) 已关闭 8 年前。 我对下面的 C 代码感到好奇 int main(){
当在类的开头使用上下文和资源初始化 MediaPlayer 对象时,它会抛出 NullPointer 异常,但是当在类的开头声明它时(因此它是 null),然后以相同的方式初始化它在onCreate方
嘿 我尝试将 java 程序连接到 REST API。 使用相同的代码部分,我在 Java 6 中遇到了 Java 异常,并且在 Java 8 中运行良好。 环境相同: 信任 机器 unix 用户 代
我正在尝试使用 Flume 和 Hive 进行 Twitter 分析。为了从 twitter 获取推文,我在 flume.conf 文件中设置了所有必需的参数(consumerKey、consumer
我在 JavaFX 异常方面遇到一些问题。我的项目在我的 Eclipse 中运行,但现在我的 friend 也尝试访问该项目。我们已共享并直接保存到保管箱文件夹中。但他根本无法让它发挥作用。他在控制台
假设我使用 blur() 事件验证了电子邮件 ID,我正在这样做: $('#email').blur(function(){ //make ajax call , check if dupli
我这样做是为了从 C 代码调用非托管函数。 pCallback 是一个函数指针,因此在托管端是一个委托(delegate)。 [DllImport("MyDLL.dll")] public stati
为什么这段代码是正确的: try { } catch(ArrayOutOfBoundsException e) {} 这是错误的: try { } catch(IOException e) {} 这段
我遇到了以下问题:有导出函数的DLL。 代码示例如下:[动态链接库] __declspec(dllexport) int openDevice(int,void**) [应用] 开发者.h: __de
从其他线程,我知道我们不应该在析构函数中抛出异常!但是对于下面的例子,它确实有效。这是否意味着我们只能在一个实例的析构函数中抛出异常?我们应该如何理解这个代码示例! #include using n
为什么需要异常 引出 public static void main(String[
1. Java的异常机制 Throwable类是Java异常类型的顶层父类,一个对象只有是 Throwable 类的(直接或者间接)实例,他才是一个异常对象,才能被异常处理机制识别。JDK中内
我是 Python 的新手,我对某种异常方法的实现有疑问。这是代码(缩写): class OurException(Exception): """User defined Exception"
我已经创建了以下模式来表示用户和一组线程之间的关联,这些线程按他们的最后一条消息排序(用户已经阅读了哪些线程,哪些没有): CREATE TABLE table(user_id bigint, mes
我正在使用 Python 编写一个简单的自动化脚本,它可能会在多个位置引发异常。在他们每个人中,我都想记录一条特定的消息并退出程序。为此,我在捕获异常并处理它(执行特定的日志记录操作等)后引发 Sys
谁能解释一下为什么这会导致错误: let xs = [| "Mary"; "Mungo"; "Midge" |] Array.iter printfn xs 虽然不是这样: Array.iter pr
在我使用 Play! 的网站上,我有一个管理部分。所有 Admin Controller 都有一个 @With 和一个 @Check 注释。 断开连接后,一切正常。连接后,每次加载页面(任何页面,无论
我尝试连接到 azure 表存储并添加一个对象。它在本地主机上工作得很好,但是在我使用的服务器上我得到以下异常及其内部异常: Exception of type 'Microsoft.Wind
我是一名优秀的程序员,十分优秀!