Как запустить тестовые классы TestNG параллельно с собственным WebDriver? - PullRequest
0 голосов
/ 26 марта 2020

Я создал тестовые классы для тестирования определенных c шаблонов страниц для сайтов моей компании. Например: я написал класс с именем ArticleTests, который наследуется от объекта BaseTest, который принимает URL в своем конструкторе. Моя компания владеет многими сайтами, и шаблон страницы статьи практически одинаков для всех.

Моя цель - создать ArticleTests для шаблона страницы статьи с каждого сайта, которым владеет моя компания. Я хочу, чтобы все тесты в каждом экземпляре ArticleTests выполнялись в одном потоке на его собственном WebDriver.

Примерно так:

  • ArticlePage("site1.com/someArticleUrl")
  • ArticlePage("site2.com/someArticleUrl")
  • ArticlePage("site3.com/someArticleUrl")

Каждый Вышеуказанный пункт должен выполнять свои собственные тесты на своем собственном WebDriver в своем собственном потоке.

Код

BaseTest:

public abstract class BaseTest implements ITest {

    protected ThreadLocal<String> testName = new ThreadLocal<String>();

    public WebDriver driver;
    public WebDriverWait wait;

    protected String url;
    protected Page page;


    public void driverSetup() {
        System.out.println("Setting up driver");
        //set driver path..., etc
        driver = new ChromeDriver();

        wait = new WebDriverWait(driver, 60); 
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    }

    @BeforeMethod
    public void beforeMethod(Method method) {
        System.out.println("Setting test name");

        testName.set(method.getName() + "_" + getBrand(url));

        if(driver.getCurrentUrl().equals("data:,"))
            driver.get(page.getUrl());


    }

    public void teardown () {
        driver.quit();
    }


    /**
     * A helper method for data providers. Takes a list as an argument and returns a 2D Object array.
     * @param list the list to be converted
     * @return the 2D array of list
     */
    protected <T> Object[][] to2DArray(List<T> list) {

        Object[][] result = new Object[list.size()][1];

        for(int i = 0; i < list.size(); i++) {
            result[i][0] = list.get(i);
        }

        return result;
    }

    public abstract String getTestName();

}

HeaderTests: - То же идея как ArticleTests, за исключением заголовка.

public class HeaderTests extends BaseTest {

    @Factory(dataProvider = "urls", dataProviderClass = URLUtils.class)
    public HeaderTests(String url) {
        this.url = url;
    }

    @BeforeClass
    public void beforeClass() {
        super.driverSetup();

        System.out.println("Creating header tests with URL " + url);
        System.out.println("On thread " + Thread.currentThread().getId());

        page = new Page(driver, wait, url);
        page.goToHome();
    }

    @Test(dataProvider = "header-logo-links")
    public void homeHeaderLogoClickTest(Link link) {

        assertTrue(isWorkingLink(link), "Header Logo did not lead to home on URL " + url);
    }


    @Test(dataProvider = "header-newsletter-links")
    public void newslettersignupTest(Link link) {

        assertTrue(isWorkingLink(link), "Newsletter sign up link does not work");
    }

    @Override
    public String getTestName() {
        return "Header_" + testName.get();
    }


    //Data Providers

    @DataProvider(name = "header-newsletter-links")  
    public Object[][] headerNewsletterLinks(){
        List<Link> headerSignupLinks = HeaderBrandUtils.getHeaderNewsletterSignupLinks(getBrand(url));

        return to2DArray(headerSignupLinks);
    }

    @DataProvider(name = "header-logo-links")  
    public Object[][] headerLogoLinks(){
        List<Link> headerSignupLinks = HeaderBrandUtils.getHeaderNewsletterSignupLinks(getBrand(url));

        return to2DArray(headerSignupLinks);
    }

    @AfterClass
    public void after() {
        System.out.println("Closing driver");
        super.teardown();
    }
}

Класс HeaderBrandUtils - это класс, который проверяет, с какого сайта происходит URL-адрес, и возвращает соответствующий объект. Пример: щелкнув заголовок lo go для site1, вы попадете на домашнюю страницу site1, а нажав заголовок lo go для site2, вы попадете на домашнюю страницу site2.

Класс Link - это класс, содержащий локатор By ссылки на странице и требуемый URL-адрес ссылки, расположенный по этому By.

URLUtils: - Класс для получения URL

public class URLUtils {

    @DataProvider(name = "urls")
    public static Object[][] getUrls() {

         List<String> testUrls = new LinkedList<String>();

        testUrls.add("site1.com/url");
        testUrls.add("site2.com/url");
        //..

        return to2DArray(testUrls);
    }

    /**
     * A helper method for data providers. Takes a list as an argument and returns a 2D Object array.
     * @param list the list to be converted
     * @return the 2D array of list
     */
    protected static <T> Object[][] to2DArray(List<T> list) {

        Object[][] result = new Object[list.size()][1];

        for(int i = 0; i < list.size(); i++) {
            result[i][0] = list.get(i);
        }

        return result;
    }
}

testng.xml:

<suite name="Suite" parallel="tests" thread-count="4">

    <test name="Footer tests" parallel="instances" thread-count="2">
        <classes>
            <class name="com.globalAutomation.tests.footerTests.FooterTests"/>
        </classes>
    </test> 

    <test name="Header tests" parallel="instances" thread-count="2">
        <classes>
            <class name="com.globalAutomation.tests.headerTests.HeaderTests"/>
        </classes>
    </test> 
</suite> 

Выход

Когда я запускаю это (через mvn test), вывод выглядит например:

Creating footer tests with URL on thread 13
Creating footer tests with URL on thread 15
Creating header tests with URL on thread 16
Creating header tests with URL on thread 14
Setting test name
Setting test name
Setting test name
Setting test name
...

4 браузера открываются, и я вижу вышеприведенный вывод.

Как только заканчивается только один тест (не тестовый класс, просто @Test) в any браузеров, другой драйвер открывается, затем другой тест заканчивается, а затем открывается другой браузер и так далее ...

Я не понимаю, почему открывается более 4 браузеров, когда я устанавливаю thread-count = 4 на уровне набора.

Я хочу, чтобы все тесты в каждом экземпляре каждого класса тестов работали в своем браузере, в своем собственном потоке.

Мои вопросы:

  • Почему я вижу результаты, которые вижу?
  • Как я могу изменить свой код для достижения моего желания?
  • Как ограничить общее количество открываемых браузеров?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...