Вопрос по поводу многопоточной передачи данных DataProvider - PullRequest
0 голосов
/ 17 ноября 2018

Я пытаюсь достичь параллелизма в новой многопоточной тестовой среде, которую я пишу.У меня есть класс DataProviderManager.java, который содержит мой статический DataProvider

@DataProvider(parallel = true, name = Config.StaticProps.DEFAULT_WEB_DATA_PROVIDER)
public static Object[][] defaultWebDataProvider() {
    return new Object[][] {
            new Object[]{"chrome", "69", "MAC 10.12"},
            new Object[]{"safari", "11.0", "Mac 10.13"},
            new Object[]{"safari", "11.0", "Mac 10.13"}
            new Object[]{"chrome", "70", "Mac 10.13"}
            new Object[]{"firefox", "63", "MAC 10.12"},
            new Object[]{"firefox", "62", "MAC 10.12"}
    };
}

У меня есть тестовый класс, который передает 3 параметра из моего DataProvider в геттеры и сеттеры ThreadLocal для установки Selenium Capabilities для каждого потока, в котором экземпляр экземпляра драйвера создается с помощью этихвозможностей.Сам тест просто открывает определенный URL на основе некоторых параметров времени выполнения.

@Factory(dataProvider = StaticProps.DEFAULT_WEB_DATA_PROVIDER, dataProviderClass = DataProviderManager.class)
//@Factory(dataProvider = StaticProps.DEFAULT_WEB_DATA_PROVIDER)
public WebExampleTest(String browser, String browserVersion, String platform) {
    super.setRunParams(browser, browserVersion, platform);
}

@BeforeMethod(alwaysRun = true)
public void setupTest() {
    home = new Home();
}

@TestCaseId("")
@Features({GroupProps.WEB})
@Test(groups = {GroupProps.DEBUG}, dataProvider = StaticProps.DEFAULT_WEB_DATA_PROVIDER, dataProviderClass = DataProviderManager.class)
@Parameters({ ParamProps.WEB, ParamProps.MOBILE_WEB })
public void openSiteTest(String browser, String browserVersion, String platform) {
    Logger.logMessage("Current Thread ID: " +  Thread.currentThread().getId());
    new WebInteract(null, null).pause(1000).openUrl(URLBuilder.buildUrl());
}

Вот мой файл testing.xml

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Test Engineering Core Suite"
       parallel="true"
       data-provider-thread-count="6"
       thread-count="6"
       verbose="2">

    <!-- LISTENERS -->
    <listeners>
        <listener class-name="com.msg.test.core.listeners.TestListeners" />
        <listener class-name="com.msg.test.core.listeners.SuiteListeners" />
        <listener class-name="com.msg.test.core.listeners.TestAnnotationTransformer" />
    </listeners>

    <!-- TEST EXECUTION QUEUE -->
    <test verbose="1" name="All Tests" annotations="JDK">

        <!-- TEST GROUPS
            "Full" - all tests in the test suite.
            "Broken" - those tests that are broken and safe to ignore until they can be resolved.
        -->

        <!--<groups>-->
            <!--<run>-->
                <!--<include name="Debug" />-->
                <!--<exclude name="Broken" />-->
            <!--</run>-->
        <!--</groups>-->

    </test>    
</suite>

Вот часть вывода, чтобы показать вам, чтов настоящее время происходит

2018-11-18 12:49:37.633 ========NEW TEST SESSION========
2018-11-18 12:49:37.633 Desktop OS: Mac 10.13
2018-11-18 12:49:37.633 Browser: chrome
2018-11-18 12:49:37.633 Browser Version: 70
2018-11-18 12:49:37.634 Current Thread ID: 66
2018-11-18 12:49:37.635 Pause for '1000' milliseconds.
Nov 18, 2018 12:49:37 AM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: OSS
2018-11-18 12:49:37.846 Session ID: 622fda273344469ab98aef0d06f90315
2018-11-18 12:49:37.847 ========NEW TEST SESSION========
2018-11-18 12:49:37.847 Desktop OS: Mac 10.13
2018-11-18 12:49:37.847 Browser: chrome
2018-11-18 12:49:37.848 Browser Version: 70
2018-11-18 12:49:37.849 Current Thread ID: 68
2018-11-18 12:49:37.849 Pause for '1000' milliseconds.
2018-11-18 12:49:37.950 Open url 'https://www.example.com'.
2018-11-18 12:49:38.571 Open url 'https://www.example.com'.
2018-11-18 12:49:38.571 Open url 'https://www.example.com'.
2018-11-18 12:49:38.576 ======SUCCESS======
2018-11-18 12:49:38.577 Desktop OS: Mac 10.13
2018-11-18 12:49:38.577 Browser: chrome
2018-11-18 12:49:38.577 Browser Version: 70
2018-11-18 12:49:38.640 Open url 'https://www.example.com'.
2018-11-18 12:49:38.854 Open url 'https://www.example.com'.
2018-11-18 12:49:39.059 ======SUCCESS======
2018-11-18 12:49:39.060 Desktop OS: Mac 10.13
2018-11-18 12:49:39.060 Browser: chrome
2018-11-18 12:49:39.060 Browser Version: 70
2018-11-18 12:49:39.083 ======SUCCESS======
2018-11-18 12:49:39.084 Desktop OS: Mac 10.13
2018-11-18 12:49:39.084 Browser: chrome
2018-11-18 12:49:39.084 Browser Version: 70
2018-11-18 12:49:39.126 ======SUCCESS======
2018-11-18 12:49:39.126 Browser: chrome
2018-11-18 12:49:39.126 Browser Version: 70
2018-11-18 12:49:39.393 ======SUCCESS======

, как вы можете видеть, я могу параллельно выполнять один и тот же тест в разных потоках, но каждый поток выполняется в одном браузере, версии и платформе из моего DataProvider.

У меня вопрос, вместо того, чтобы запускать несколько потоков, каждый из которых выполняет одинаковые данные (браузер, платформа версий - chrome, 70, Mac 10.13) из DataProvider одновременно, как запустить каждый из них (браузер, версия,платформа)

  new Object[]{"chrome", "69", "MAC 10.12"}, **This should be thread 1**
            new Object[]{"safari", "11.0", "Mac 10.13"}, **This should be thread 2**
            new Object[]{"safari", "11.0", "Mac 10.13"} **This should be thread 3**
            new Object[]{"chrome", "70", "Mac 10.13"} **This should be thread 4**
            new Object[]{"firefox", "63", "MAC 10.12"}, **This should be thread 5**
            new Object[]{"firefox", "62", "MAC 10.12"} **This should be thread 6**

от DataProvider на разных потоках одновременно?

1 Ответ

0 голосов
/ 19 ноября 2018

Вот как работает TestNG

Обычный @Test метод в сочетании с поставщиком данных

Когда нормальный @Test аннотированный метод тестирования необходимо выполнить несколько разраз, но с разными наборами данных, вы соединяете его с поставщиком данных.Чтобы запустить его параллельно, вы в основном включаете атрибут параллели в аннотации @DataProvider и указываете атрибут parallel=methods на уровне тега <suite>.

Ниже приведен пример, который показывает все это в действии,Он использует интерфейс org.testng.IHookable, так что можно в основном извлечь параметры, которые отправляются методу @Test через поставщика данных, и использовать их для выполнения любой настройки, необходимой для каждой итерации.

Вы также можете использовать аннотацию @BeforeMethod, но невозможно извлечь параметры, отправляемые в метод @Test поставщиком данных, из @BeforeMethod.

import org.testng.IHookCallBack;
import org.testng.IHookable;
import org.testng.ITestResult;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class TestClassWithDataDrivenTest implements IHookable {

  @Override
  public void run(IHookCallBack callBack, ITestResult result) {
    beforeMethod(callBack.getParameters());
    callBack.runTestMethod(result);
  }

  public void beforeMethod(Object[] parameters) {
    String browser = parameters[0].toString();
    String browserVersion = parameters[1].toString();
    String platform = parameters[2].toString();
    String msg =
        String.format(
            "[beforeMethod()-Thread Id : %d] [%s] flavor version [%s] on platform [%s]",
            Thread.currentThread().getId(), browser, browserVersion, platform);
    System.err.println(msg);
  }

  @Test(dataProvider = "dp")
  public void testMethod(String browser, String browserVersion, String platform) {
    String msg =
        String.format(
            "[testMethod()-Thread Id : %d] [%s] flavor version [%s] on platform [%s]",
            Thread.currentThread().getId(), browser, browserVersion, platform);
    System.err.println(msg);
  }

  @DataProvider(parallel = true, name = "dp")
  public static Object[][] defaultWebDataProvider() {
    return new Object[][] {
      new Object[] {"chrome", "69", "MAC 10.12"},
      new Object[] {"safari", "11.0", "Mac 10.13"},
      new Object[] {"safari", "11.0", "Mac 10.13"},
      new Object[] {"chrome", "70", "Mac 10.13"},
      new Object[] {"firefox", "63", "MAC 10.12"},
      new Object[] {"firefox", "62", "MAC 10.12"}
    };
  }
}

Соответствующий вывод при запуске этого теста выглядит следующим образом:

[beforeMethod()-Thread Id : 11] [chrome] flavor version [69] on platform [MAC 10.12]
[beforeMethod()-Thread Id : 12] [safari] flavor version [11.0] on platform [Mac 10.13]
[beforeMethod()-Thread Id : 14] [chrome] flavor version [70] on platform [Mac 10.13]
[beforeMethod()-Thread Id : 13] [safari] flavor version [11.0] on platform [Mac 10.13]
[beforeMethod()-Thread Id : 15] [firefox] flavor version [63] on platform [MAC 10.12]
[testMethod()-Thread Id : 12] [safari] flavor version [11.0] on platform [Mac 10.13]
[beforeMethod()-Thread Id : 16] [firefox] flavor version [62] on platform [MAC 10.12]
[testMethod()-Thread Id : 13] [safari] flavor version [11.0] on platform [Mac 10.13]
[testMethod()-Thread Id : 14] [chrome] flavor version [70] on platform [Mac 10.13]
[testMethod()-Thread Id : 11] [chrome] flavor version [69] on platform [MAC 10.12]
[testMethod()-Thread Id : 16] [firefox] flavor version [62] on platform [MAC 10.12]
[testMethod()-Thread Id : 15] [firefox] flavor version [63] on platform [MAC 10.12]

===============================================
Default Suite
Total tests run: 6, Passes: 6, Failures: 0, Skips: 0
===============================================

A @Factory в сочетании с поставщиком данных

Каждый использует метод @Factory (эту аннотацию можно добавить поверх конструктора или статического метода, который возвращает Object[]), когда нужно создать экземпляры класса теста.

ТестЭкземпляр класса определяется как обычный класс, в котором содержится один или несколько @Test методов.Фабрика в сочетании с поставщиком данных использует данные, предоставленные поставщиком данных, для создания экземпляров каждого класса тестирования.

Если вы хотите, чтобы TestNG запускал методы @Test во всех случаях вПараллельно в одном кадре (TestNG по-прежнему будет запускать все методы @Test в каждом классе тестирования в последовательном порядке), затем вы можете указать его с помощью атрибута parallel=instances в теге <suite>.

Обратите внимание, что вы не можете запустить все методы @Test в каждом из экземпляров тестового класса параллельно.TestNG AFAIK не имеет возможности включить параллелизм на этом уровне.

Ниже приведен пример, демонстрирующий это в действии

import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Factory;
import org.testng.annotations.Test;

public class TestClassWithFactory {

  private String browser, browserVersion, platform;

  @Factory(dataProvider = "dp")
  public TestClassWithFactory(String browser, String browserVersion, String platform) {
    this.browser = browser;
    this.browserVersion = browserVersion;
    this.platform = platform;
  }

  @BeforeMethod
  public void beforeMethod() {
    String msg =
        String.format(
            "[Instance id %d][beforeMethod()-Thread Id : %d] [%s] flavor version [%s] on platform [%s]",
            this.hashCode(), Thread.currentThread().getId(), browser, browserVersion, platform);
    System.err.println(msg);
  }

  @Test
  public void testMethod() {
    String msg =
        String.format(
            "[Instance id %d][testMethod()-Thread Id : %d] [%s] flavor version [%s] on platform [%s]",
            this.hashCode(), Thread.currentThread().getId(), browser, browserVersion, platform);
    System.err.println(msg);
  }

  @DataProvider(parallel = true, name = "dp")
  public static Object[][] defaultWebDataProvider() {
    return new Object[][] {
      new Object[] {"chrome", "69", "MAC 10.12"},
      new Object[] {"safari", "11.0", "Mac 10.13"},
      new Object[] {"safari", "11.0", "Mac 10.13"},
      new Object[] {"chrome", "70", "Mac 10.13"},
      new Object[] {"firefox", "63", "MAC 10.12"},
      new Object[] {"firefox", "62", "MAC 10.12"}
    };
  }
}

XML-файл комплекта testng, как показано ниже

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="53345934_suite" parallel="instances" verbose="2">
  <test name="53345934_test">
    <classes>
      <class name="com.rationaleemotions.stackoverflow.qn53345934.TestClassWithFactory"/>
    </classes>
  </test>
</suite>

Вывод на выполнение выглядит следующим образом:

...
... TestNG 7.0.0-beta1 by Cédric Beust (cedric@beust.com)
...
[Instance id 1627821297][beforeMethod()-Thread Id : 15] [safari] flavor version [11.0] on platform [Mac 10.13]
[Instance id 1549409129][beforeMethod()-Thread Id : 14] [chrome] flavor version [70] on platform [Mac 10.13]
[Instance id 922872566][beforeMethod()-Thread Id : 11] [firefox] flavor version [63] on platform [MAC 10.12]
[Instance id 1132547352][beforeMethod()-Thread Id : 12] [safari] flavor version [11.0] on platform [Mac 10.13]
[Instance id 1525037790][beforeMethod()-Thread Id : 13] [chrome] flavor version [69] on platform [MAC 10.12]
[Instance id 1132547352][testMethod()-Thread Id : 12] [safari] flavor version [11.0] on platform [Mac 10.13]
[Instance id 1549409129][testMethod()-Thread Id : 14] [chrome] flavor version [70] on platform [Mac 10.13]
[Instance id 1525037790][testMethod()-Thread Id : 13] [chrome] flavor version [69] on platform [MAC 10.12]
[Instance id 922872566][testMethod()-Thread Id : 11] [firefox] flavor version [63] on platform [MAC 10.12]
[Instance id 1627821297][testMethod()-Thread Id : 15] [safari] flavor version [11.0] on platform [Mac 10.13]
[Instance id 1651855867][beforeMethod()-Thread Id : 12] [firefox] flavor version [62] on platform [MAC 10.12]
[Instance id 1651855867][testMethod()-Thread Id : 12] [firefox] flavor version [62] on platform [MAC 10.12]
PASSED: testMethod
PASSED: testMethod
PASSED: testMethod
PASSED: testMethod
PASSED: testMethod
PASSED: testMethod

===============================================
    53345934_test
    Tests run: 6, Failures: 0, Skips: 0
===============================================

===============================================
53345934_suite
Total tests run: 6, Passes: 6, Failures: 0, Skips: 0
===============================================
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...