在通过Saucelabs跨浏览器执行selenium java测试时,我需要一些帮助来解决这个问题。我正在Jenkins作业中选择的两个浏览器上运行一个测试。
当一个测试通过执行时,另一个测试(类似)失败,出现错误:
似乎一个测试中断了另一个测试。这两个测试都在各自的通道和线程下运行。
Aug 30, 2018 7:17:44 AM org.openqa.selenium.remote.ProtocolHandshake
createSession
INFO: Detected dialect: OSS
30-08-2018 07:17:49.235 [TestNG-PoolService-0] INFO
[com.***.tests.TestBase_Local:96] - Open a site URLDriver: RemoteWebDriver:
chrome on XP (4f5a5d685f4c44c9a5864e91cb8f11e9)
Driver: RemoteWebDriver: chrome on XP (4f5a5d685f4c44c9a5864e91cb8f11e9)
thread id:14 Timestamp :2018-08-30T07:17:49.370
30-08-2018 07:17:51.912 [TestNG-PoolService-0] INFO
[com.**.tests.TestBase_Local:35] - Select 'No thanks' on the popup
Aug 30, 2018 7:17:53 AM org.openqa.selenium.remote.ProtocolHandshake
createSession
INFO: Detected dialect: OSS
30-08-2018 07:17:58.886 [TestNG-PoolService-1] INFO
[com.**.tests.TestBase_Local:96] - Open a site URLDriver:
RemoteWebDriver: MicrosoftEdge on ANY (c6978c03531d408485588ba501ff0589)
Driver: RemoteWebDriver: MicrosoftEdge on ANY
(c6978c03531d408485588ba501ff0589)
thread id:15 Timestamp :2018-08-30T07:17:58.887
30-08-2018 07:18:03.406 [TestNG-PoolService-1] INFO
[com.**.tests.TestBase_Local:35] - Select 'No thanks' on the popup
30-08-2018 07:18:05.337 [TestNG-PoolService-1] INFO
[com.**.tests.TestBase_Local:38] - Search by input
共享代码:
public class Search extends RemoteTestBase {
@Test(dataProvider = "browsers")
public void SolrSearchTest(String browser, String version, String os, Method method) throws Exception {
this.createRemoteDriver(browser, version, os, method.getName());
System.out.println("Driver: " + driver.toString());
Application app = new Application(driver);
ConfigFileReader configRead = new ConfigFileReader();
WebDriverWait wait = new WebDriverWait(driver,100);
app.homePage().SelectNoThanks();
Log.info("Select 'No thanks' on the popup");
app.searchField().SearchBy(configRead.SearchInput());
Log.info("Search by input");
}
}
扩展的Remote teTestBase类:
public class RemoteTestBase {
public WebDriver driver;
private static String baseUrl;
RandomDataSelect randomuser;
private PropertyLoader propertyRead;
public Logger Log = Logger.getLogger(TestBase_Local.class.getName());
private static final String SAUCE_ACCESS_KEY = System.getenv("SAUCE_ACCESS_KEY");
private static final String SAUCE_USERNAME = System.getenv("SAUCE_USERNAME");
@BeforeMethod
@DataProvider(name = "browsers", parallel = true)
public static Object[][] sauceBrowserDataProvider(Method testMethod) throws JSONException {
String browsersJSONArrayString = System.getenv("SAUCE_ONDEMAND_BROWSERS");
System.out.println(browsersJSONArrayString);
JSONArray browsersJSONArrayObj = new JSONArray(browsersJSONArrayString);
Object[][] browserObjArray = new Object[browsersJSONArrayObj.length()][3];
for (int i=0; i < browsersJSONArrayObj.length(); i++) {
JSONObject browserObj = (JSONObject)browsersJSONArrayObj.getJSONObject(i);
browserObjArray[i] = new Object[]{ browserObj.getString("browser"), browserObj.getString("browser-version"), browserObj.getString("os")};
}
return browserObjArray;
}
void createRemoteDriver(String browser, String version, String os, String methodName) throws Exception {
DesiredCapabilities capabilities = new DesiredCapabilities();
Class<? extends RemoteTestBase> SLclass = this.getClass();
capabilities.setCapability("browserName", browser);
if (version != null) {
capabilities.setCapability("browser-version", version);
}
capabilities.setCapability("platform", os);
capabilities.setCapability("name", SLclass.getSimpleName());
capabilities.setCapability("tunnelIdentifier", "***");
driver = (new RemoteWebDriver(new URL("http://" + SAUCE_USERNAME + ":" + SAUCE_ACCESS_KEY + "@ondemand.saucelabs.com:80/wd/hub"), capabilities));
randomuser = new RandomDataSelect();
propertyRead = new PropertyLoader();
baseUrl = propertyRead.getProperty("site.url");
getURL();
}
private void getURL () {
driver.get(baseUrl);
driver.manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);
this.annotate("Visiting HDSupply page..." + driver.toString());
Log.info("Open a site URL" + "Driver: " + driver.toString());
}
private void printSessionId() {
String message = String.format("SauceOnDemandSessionID=%1$s job-name=%2$s",(((RemoteWebDriver) driver).getSessionId()).toString(), "some job name");
System.out.println(message);
}
@AfterMethod(description = "Throw the test execution results into saucelabs")
public void tearDown(ITestResult result) throws Exception {
((JavascriptExecutor) driver).executeScript("sauce:job-result=" + (result.isSuccess() ? "passed" : "failed"));
printSessionId();
driver.quit();
}
void annotate(String text) {
((JavascriptExecutor) driver).executeScript("sauce:context=" + text);
}
}
suite.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Tests Suite" verbose="4" parallel="tests" data-provider-thread-count="2">
<test name="AllTests" parallel="methods">
<classes>
<class name="com.***.tests.Search"/>
</classes>
</test>
</suite>
项目信息:java、selenium、testng、maven、saucelabs、jenkins
问题在于你的测试代码。它肯定与您的@Test
方法之间的竞争条件有关[您在@DataProvider
注释和并行=方法中有您的
并行="true"
]
您需要重构代码,使驱动程序
对象是线程安全的。
您可以使用以下方法来完成此任务:
ITestResult
对象下面的示例显示如何使用ThreadLocal
变量使代码线程安全
import java.net.URL;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
public class RemoteTestBase {
public static final ThreadLocal<RemoteWebDriver> driver = new ThreadLocal<>();
private static String baseUrl;
private static final String SAUCE_ACCESS_KEY = System.getenv("SAUCE_ACCESS_KEY");
private static final String SAUCE_USERNAME = System.getenv("SAUCE_USERNAME");
void createRemoteDriver(String browser, String version, String os, String methodName)
throws Exception {
DesiredCapabilities capabilities = new DesiredCapabilities();
Class<? extends RemoteTestBase> SLclass = this.getClass();
capabilities.setCapability("browserName", browser);
if (version != null) {
capabilities.setCapability("browser-version", version);
}
capabilities.setCapability("platform", os);
capabilities.setCapability("name", SLclass.getSimpleName());
capabilities.setCapability("tunnelIdentifier", "***");
URL url = new URL(
"http://" +
SAUCE_USERNAME + ":" +
SAUCE_ACCESS_KEY + "@ondemand.saucelabs.com:80/wd/hub");
RemoteWebDriver rwd = new RemoteWebDriver(url, capabilities);
driver.set(rwd);
getURL();
}
protected static RemoteWebDriver getDriver() {
return driver.get();
}
private void getURL() {
getDriver().get(baseUrl);
getDriver().manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);
this.annotate("Visiting HDSupply page..." + driver.toString());
}
private void printSessionId() {
String message = String.format("SauceOnDemandSessionID=%1$s job-name=%2$s",
getDriver().getSessionId(), "some job name");
System.out.println(message);
}
@AfterMethod(description = "Throw the test execution results into saucelabs")
public void tearDown(ITestResult result) {
String txt = "sauce:job-result=" + (result.isSuccess() ? "passed" : "failed");
getDriver().executeScript(txt);
printSessionId();
getDriver().quit();
}
void annotate(String text) {
getDriver().executeScript("sauce:context=" + text);
}
}
您的所有子类都将尝试通过getDriver()
方法访问RemoteWebDriver
对象。
需要注意的是,您的@Beforemethod
需要调用createRemteDriver()
,以便RemteWebDriver
对象被实例化并推送到线程本地
上下文中,该上下文将是有效的,并且可以在@Test中访问
方法。
规则总是@Beforemethod
(发生驱动程序实例化)
但是当我运行test时,两个浏览器实例都打开了(Chrome首先打开并开始执行,延迟后Firefox打开)。在这种情况下,驱动程序对象被Firefox驱动程序覆盖,chrome停止执行。测试继续在Firefox上执行并成功完成。 项目的结构是这样的: 创建了一个DriverBase.class来加载与浏览器对应的驱动程序,该浏览器具有my@beforeSuite. crteated页面的单个类。(
我一个类有5到6个方法,想在不同的节点上并行运行方法,我有网格2设置,里面有4个节点。 下面是我的测试。xml 我有一个测试工具,它初始化了login、common和utils类 在我的测试类中,我扩展了测试工具,在@Beforemethod中,我调用了inilze方法 如果我运行测试,我会看到以下问题 两个浏览器在每个节点中打开一个,但只有一个浏览器启动应用程序,另一个不启动。 如果我遗漏了什么
我的问题是:有什么方法可以防止这种行为(意味着bean错误冲突)?或者至少在发生这种情况时得到警告消息。 提前感谢您的回答
问题内容: 我有2个AsyncTask,一个正在创建套接字连接,另一个正在使用那些套接字传输对象。我的代码是这样的: 但是,永远不会创建或执行被调用。我试图更改顺序,但未创建或执行发送器… 怎么了 问题答案: 当HONEY COMB将多个AsyncTask执行从并发更改为顺序执行时,我讨厌它。因此,每次执行AsyncTask时,我都会执行类似的操作。 但是线程池大小为5,如果添加第六个任务,它将被
我使用页面对象模式。我在Watcher类中实现了TestWatcher接口来处理测试用例结果。为了截屏通过/失败的测试用例,我需要一个WebDriver的实例,可用的驱动程序。如果我声明驱动程序为静态,那么它在顺序模式下工作良好,但在打开并行执行时失败。看起来JUnit对单个类中的所有测试方法都使用单线程。如果我不将驱动程序声明为静态,那么来自TestWatcher方法的ExecttionCont
我如何在Sonar中发布Javascript(Jasmine Karma)测试的结果和覆盖范围。Java测试执行和覆盖范围都很好。我正在尝试添加由Karma(lcov coverageReport sonarQubeUnit记者)执行的Javascript测试。 Q1。我应该定义哪些声纳特性(例如,来源、包裹体、测试、test.inclusion、sonar.javascript.lcov.rep