ANT+JUnit+Eclipse: параллельное тестирование на разных сайтах разными браузерами

Коллеги, всем хорошего дня! :wink:
В прошлую пятницу запустили параллельное тестирование на разных сайтах.
Исходные данные:

  • два .java-файла с тестами для разных сайтов (Параллель1 и Параллель2);
  • build.xml для запуска и распараллеливания.

Все работает, логи идут. Радаст.
Встала необходимость одеть мантию кроссбраузерного тестирования :smiley:

Хочу, чтобы в каждом ПАРАЛЛЕЛЬНОМ потоке каждый тест ПОСЛЕДОВАТЕЛЬНО проходил на разных браузерах (принимается конструктивная критика по этой архитектуре). Я решил сделать так, чтобы сложный пошаговый тест, связанный с авторизацией, не шел параллельно на разных браузерах. Имхо.
Также хочу учитывать тот факт, что ШУ (IE) небыстрый.

Покорно выкладываю данные:

  • build.xml
  • java-файл (таких файлов всего 4: для работы на 4 сайтах).
  • схема распараллеливания.

Итак, билд:

<?xml version="1.0" encoding="UTF-8"?>
<project name="JUnitTesting.jar" default = "all">
    
    <!--========================================================================
                                Properties
    =========================================================================-->
    
    <property name="src.dir" location="src"/>
    <property name="bin.dir" value="bin"/>
    <property name="lib.dir" location="library"/>
    <property name="build.dir" value="build"/>
    <property name="jar.name" value="TestCalc.jar"/>
    <property name="html.report.dir" value="report"/>
        
    <!--========================================================================
                            Creating folders
    =========================================================================-->
        
    <target name = "MakeDirs" description = "Making of the auxillary dirs">
    <mkdir dir="${html.report.dir}/html"/>
    </target>
   
    <!--========================================================================
                        Compilation of the classes
    =========================================================================-->
    
    <target name = "compile" description = "Compilation of the classes">
        
        <javac includeantruntime = "false" destdir="${bin.dir}" debug="off">
            <src path="${src.dir}"/>
            <classpath id="classpath">
                <fileset dir="${lib.dir}">
                    <include name="junit.jar"/>
                    <include name="org.hamcrest.core_1.3.0.v201303031735.jar"/>
                    <include name="selenium-server-standalone-2.44.0.jar"/>
                </fileset>
            </classpath>
        </javac>

    </target>
    
    <!--========================================================================
                                   TESTING
    =========================================================================-->  
    
    <!--==========Yahoo=========================-->
    ...
    <!--==========Mail=========================-->
    ...
    <!--==========Yandex=========================-->
    <target name="MainNewYandex" description="Start TestSuite class" depends = "compile">
        <junit fork="yes" forkmode="perBatch" failureproperty="unit.test.failed" printsummary="yes" haltonerror="no" showoutput="yes">
                
                      <formatter type="xml" usefile = "true"/>
                      
                       
                       <test name="package1.MainNewYandex" todir = "${html.report.dir}"/>
                       
                
                      <classpath>
                      <pathelement location="./library/junit.jar"/>
                      <pathelement location="./library/org.hamcrest.core_1.3.0.v201303031735.jar"/>
                      <pathelement location="./library/selenium-server-standalone-2.44.0.jar"/>
                      <pathelement location="${bin.dir}"/>
                    </classpath>
                  
        </junit>
    </target>    
    <!--==========Google=========================-->
    <target name="MainSearchGoogle" description="Start TestSuite class" depends = "compile">
        <junit fork="yes" forkmode="perBatch" failureproperty="unit.test.failed" printsummary="yes" haltonerror="no" showoutput="yes">
                
                      <formatter type="xml" usefile = "true"/>

                       <test name="package1.MainSearchGoogle" todir="${html.report.dir}"/>
                
                      <classpath>
                      <pathelement location="./library/junit.jar"/>
                      <pathelement location="./library/org.hamcrest.core_1.3.0.v201303031735.jar"/>
                      <pathelement location="./library/selenium-server-standalone-2.44.0.jar"/>
                      <pathelement location="${bin.dir}"/>
                    </classpath>
                  
        </junit>
    </target>
    <!--===================================-->
    
    <!--=====================Распараллеливание=====================================-->
    <target name="WTFTest" description="Start TestSuite class">
           <parallel>
                   <antcall target = "MainSearchYandex"/>
                <antcall target = "MainSearchMail"/>
                <antcall target = "MainSearchYandex"/>        
                   <antcall target = "MainSearchGoogle"/>
           </parallel>
    </target>

    <!--========================================================================
                                    Report
    =========================================================================-->  
    
    <target name="report" description="Report..." depends = "WTFTest">
      <junitreport todir="${html.report.dir}">
        <fileset dir="${html.report.dir}">
          <include name="TEST-*.xml"/>
        </fileset>
        <report todir="${html.report.dir}/html"/>
      </junitreport>
    </target>
    
    <target name="all" description="Do the build" depends = "report"/>
        
</project>

Java-файл (таких файлов всего 4 - по одному на каждый сайт):

package package1;

import static org.junit.Assert.*;

import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.NoAlertPresentException;
import org.openqa.selenium.NoSuchElementException;
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.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;


    public class MainSearchGoogle {
        private WebDriver driver;
        private String baseUrl;
        private boolean acceptNextAlert = true;
        private StringBuffer verificationErrors = new StringBuffer();

        @BeforeTest
        public void setUp() throws Exception {
            driver = new FirefoxDriver();
            baseUrl = "https://www.google.ru/?gws_rd=ssl";
            driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
            driver.get(baseUrl + "");

        }
        @Parameters("browser")
        public void setup(String browser) throws Exception {
        if (browser.equalsIgnoreCase("firefox")) {
        driver = new FirefoxDriver();
        } else if (browser.equalsIgnoreCase("chrome")) {
        driver = new ChromeDriver();
        } else if (browser.equalsIgnoreCase("ie")) {
        driver = new InternetExplorerDriver();
        } else {
        throw new Exception("Browser is not correct");
        }
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        }
//===================================================================================================================================
                
        @Test
        public void OpenGoogle() throws Exception {
            System.out.println("++++++++++++Test control: open Google++++++++++++");
            //что-то там проверяет...
            System.out.println("OK");
    
        }

//====================================================================================================================================            
       
        
        @After
        public void tearDown() throws Exception {
            driver.quit();
            String verificationErrorString = verificationErrors.toString();
            if (!"".equals(verificationErrorString)) {
                fail(verificationErrorString);
            }
        }
        
        private boolean isElementPresent(By by) {
            try {
                driver.findElement(by);
                return true;
            } catch (NoSuchElementException e) {
                return false;
            }
        }

        private boolean isAlertPresent() {
            try {
                driver.switchTo().alert();
                return true;
            } catch (NoAlertPresentException e) {
                return false;
            }
        }

        private String closeAlertAndGetItsText() {
            try {
                Alert alert = driver.switchTo().alert();
                String alertText = alert.getText();
                if (acceptNextAlert) {
                    alert.accept();
                } else {
                    alert.dismiss();
                }
                return alertText;
            } finally {
                acceptNextAlert = true;
            }
        }
    }

Уважаемые коллеги, призрите на просьбу младшего о помощи :smile:
Как организовать в исходных условиях (на параллельном тестировании) последовательное исполнение каждого теста в своей параллели на разных браузерах?
Спасибо!

Маленькая поправка: в каждой паралели тесты выполняются последовательно.
Хотя, если есть возможность параллельного запуска тестов в каждой параллели (первая схема), буду признателен за подсказки!

По JUnit не подскажу. В TestNG это легко достигается через xml. Предложу чуть модифицированный вариант.

  • Создаем global suite, который будет содержать ссылки на FF / CH / … / IE sub-suites.
  • В каждом sub-suite будет параллельное разбиение, к примеру, по tests.
  • Исходя из схемы, внутри каждого sub-suite будет 2 test tag со списками классов / методов для тестирования.

Т.е. идея такова, что глобальный suite будет последовательно запускать sub-suite для каждого браузера. При этом, sub-suite будет в параллельном режиме запускать test блоки на 2 разных окружениях. Итого, вначале все тесты прогонятся на FF в параллели на VM1/2, затем то же самое на хроме и т.п.

Идея думаю понятна. Но не уверен, что такие схемы легко реализуемы в JUnit.

Благодарю, вектор понятен )

Может поможет
http://internetka.in.ua/junit-tests-parallel/

Благодарю участников, все решилось.
Не совсем тривиально, правда.
Было решено создать под каждый сайт и браузер отдельный файл. Условно - GoogleFF, GoogleChr.
В итоге go-block файла build.xml стал выглядеть так:

<!--=====================Распараллеливание=====================================-->
    <target name="WTFTest" description="Start TestSuite class">
           <parallel>
                <antcall target = "MainSearchYandexFF"/>
                <antcall target = "MainSearchYandexChr"/>
                <antcall target = "MainSearchMailFF"/>
                <antcall target = "MainSearchYandexChr"/>
                <antcall target = "MainSearchYandexFF"/>
                <antcall target = "MainSearchYandexChr"/>       
                <antcall target = "MainSearchGoogleFF"/>
                <antcall target = "MainSearchYandexChr"/>
           </parallel>
    </target>

… а блоки целей, относящихся к самим тестам в файле build.xml пополнились новыми участниками:

<!--==========YandexFF=========================-->
    <target name="MainSearchYandexFF" description="Start TestSuite class" depends = "compile">
        <junit fork="yes" forkmode="perBatch" failureproperty="unit.test.failed" printsummary="yes" haltonerror="no" showoutput="yes">
                      ...
        </junit>
    </target> 
<!--==========YandexChr=========================-->
    <target name="MainSearchYandexChr" description="Start TestSuite class" depends = "compile">
        <junit fork="yes" forkmode="perBatch" failureproperty="unit.test.failed" printsummary="yes" haltonerror="no" showoutput="yes">
                      ...
        </junit>
    </target> 

Запуск пошел, но хромовские тесты стали активно валиться на старте. Было непросто разобраться, отчего.
Оказалось, что дело в аннотациях @BeforeClass и @AfterClass.
Итак, предтестовые настройки:

package package1;

import static org.junit.Assert.*;

import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.NoAlertPresentException;
import org.openqa.selenium.NoSuchElementException;
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.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Parameters;
public class MainSearchChr {
        private WebDriver driver;
        private String baseUrl;
        private boolean acceptNextAlert = true;
        private StringBuffer verificationErrors = new StringBuffer();
        private static ChromeDriverService service2;
        
        @BeforeClass
           
        public static void createAndStartServiceNew() throws IOException {
             service2 = new ChromeDriverService.Builder()
                 .usingDriverExecutable(new File("C:/chromedriver_win32/chromedriver.exe"))
                 .usingAnyFreePort()
                 .build();
             service2.start();             
        }
        
        @Before

        public void crateDriver() throws Exception {
            driver = new RemoteWebDriver(service2.getUrl(),DesiredCapabilities.chrome());
            baseUrl = "http://www.yandex.ru";
            driver.manage().timeouts().implicitlyWait(8, TimeUnit.SECONDS);
            driver.get(baseUrl + "");
        }

Постдействия, относящиеся к сути:

@AfterClass
        public static void createAndStopServiceNew() {
            service2.stop();
        }
        
        @After                
        public void quitDriver() {
            driver.quit();
        } 

Сейчас имею 4 параллели:

  • GoogleFF
  • GoogleChr
  • YandexFF
  • YandexChr,
    которые работают при участии AntApache.
1 лайк