selenium和并行JUnit-WebDriver实例

selenium和并行JUnit-WebDriver实例,第1张

selenium和并行JUnit-WebDriver实例

总的来说,我同意:

如果已经使用了像JUnit这样的框架,手动处理线程可能是一个坏主意

但是,看看

Parallelized
您提到的运行器以及
@Parametrized
junit 4.12的内部实现,这是可能的。

每个测试用例都计划执行。默认情况下,junit在单线程中执行测试用例。

Parallelized
扩展
Parametrized
方式是用多线程调度程序代替了单线程测试调度程序,因此,要了解这如何影响
Parametrized
测试用例的运行方式,我们必须查看JUnit
Parametrized
源代码:

https://github.com/junit-
team/junit/blob/r4.12/src/main/java/org/junit/runners/Parameterized.java#L303

好像:

  1. @Parametrized
    测试用例
    TestWithParameters
    针对每个测试参数分为一组
  2. 为的每个
    TestWithParameters
    实例
    Runner
    创建并计划执行(在这种情况下,
    Runner
    实例是专门的
    BlockJUnit4ClassRunnerWithParameters

实际上, 每个@Parametrized测试用例都会生成一组要运行的测试实例(每个参数一个实例),并且每个实例都是独立安排的,
因此在我们的案例中(

Parallelized
@Parametrized
WebDriver
实例作为参数进行测试),将在专用线程中执行多个独立测试,以用于每种
WebDriver
类型。这很重要,因为它允许我们
WebDriver
在当前线程的范围内存储特定实例。

记住,此行为依赖于junit 4.12的内部实现细节,并且可能会发生变化 (例如,参见中的注释

RunnerScheduler
)。

让我看下面的例子。它依靠提到的JUnit行为,并用于

ThreadLocal
存储
WebDriver
相同案例组中测试之间共享的实例。唯一的招数
ThreadLocal
是只初始化一次(在@Before中)并销毁每个创建的实例(在@AfterClass中)。

package example.junit;import java.util.ArrayList;import java.util.Arrays;import java.util.Collection;import java.util.Collections;import java.util.Iterator;import java.util.List;import org.apache.commons.lang3.StringUtils;import org.junit.AfterClass;import org.junit.Before;import org.junit.BeforeClass;import org.junit.Test;import org.junit.runner.RunWith;import org.junit.runners.Parameterized;import org.openqa.selenium.By;import org.openqa.selenium.WebDriver;import org.openqa.selenium.WebElement;import org.openqa.selenium.chrome.ChromeDriver;import org.openqa.selenium.firefox.FirefoxDriver;@RunWith(Parallelized.class)public class ParallelSeleniumTest {        enum WebDriverType {        CHROME,        FIREFOX    }        static class WebDriverFactory {        static WebDriver create(WebDriverType type) { WebDriver driver; switch (type) { case FIREFOX:     driver = new FirefoxDriver();     break; case CHROME:     driver = new ChromeDriver();     break; default:     throw new IllegalStateException(); } log(driver, "created"); return driver;        }    }    // for description how to user Parametrized    // see: https://github.com/junit-team/junit/wiki/Parameterized-tests    @Parameterized.Parameter    public WebDriverType currentDriverType;    // test case naming requires junit 4.11    @Parameterized.Parameters(name= "{0}")    public static Collection<Object[]> driverTypes() {        return Arrays.asList(new Object[][] {     { WebDriverType.CHROME },     { WebDriverType.FIREFOX } });    }    private static ThreadLocal<WebDriver> currentDriver = new ThreadLocal<WebDriver>();    private static List<WebDriver> driversToCleanup = Collections.synchronizedList(new ArrayList<WebDriver>());    @BeforeClass    public static void initChromeVariables() {        System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");    }    @Before    public void driverInit() {        if (currentDriver.get()==null) { WebDriver driver = WebDriverFactory.create(currentDriverType); driversToCleanup.add(driver); currentDriver.set(driver);        }    }    private WebDriver getDriver() {        return currentDriver.get();    }    @Test    public void searchForChromeDriver() throws InterruptedException {        openAndSearch(getDriver(), "chromedriver");    }    @Test    public void searchForJunit() throws InterruptedException {        openAndSearch(getDriver(), "junit");    }    @Test    public void searchForStackoverflow() throws InterruptedException {        openAndSearch(getDriver(), "stackoverflow");    }    private void openAndSearch(WebDriver driver, String phraseToSearch) throws InterruptedException {        log(driver, "search for: "+phraseToSearch);        driver.get("http://www.google.com");        WebElement searchBox = driver.findElement(By.name("q"));        searchBox.sendKeys(phraseToSearch);        searchBox.submit();        Thread.sleep(3000);    }    @AfterClass    public static void driverCleanup() {        Iterator<WebDriver> iterator = driversToCleanup.iterator();        while (iterator.hasNext()) { WebDriver driver = iterator.next(); log(driver, "about to quit"); driver.quit(); iterator.remove();        }    }    private static void log(WebDriver driver, String message) {        String driverShortName = StringUtils.substringAfterLast(driver.getClass().getName(), ".");        System.out.println(String.format("%15s, %15s: %s", Thread.currentThread().getName(), driverShortName, message));    }}

它将打开两个浏览器并在每个浏览器窗口中同时执行三个测试用例

控制台将打印如下内容:

pool-1-thread-1,    ChromeDriver: createdpool-1-thread-1,    ChromeDriver: search for: stackoverflowpool-1-thread-2,   FirefoxDriver: createdpool-1-thread-2,   FirefoxDriver: search for: stackoverflowpool-1-thread-1,    ChromeDriver: search for: junitpool-1-thread-2,   FirefoxDriver: search for: junitpool-1-thread-1,    ChromeDriver: search for: chromedriverpool-1-thread-2,   FirefoxDriver: search for: chromedrivermain,    ChromeDriver: about to quitmain,   FirefoxDriver: about to quit

您可以看到驱动程序为每个辅助线程创建一次,并在最后销毁。

总而言之,我们需要类似的东西,

@BeforeParameter
并且
@AfterParameter
在执行线程的上下文中,快速搜索表明该想法已在Junit中注册为问题。



欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5639001.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存