TestNG — запускать каждый экземпляр из фабрики TestNG как отдельный тест.

Я использую TestNG для автоматизации тестирования вместе с ReportNG для создания отчетов. Я использую фабричный класс TestNG для предоставления различных входных данных для моих тестов. Проблема, с которой я сталкиваюсь здесь, заключается в том, что все тестовые экземпляры, поставляемые фабрикой, выполняются в рамках одного и того же теста, а сгенерированный отчет отображает все сценарии в рамках одного теста.

Я хочу запускать каждый тестовый экземпляр, поставляемый фабрикой, как отдельный тест. Есть какой-либо способ сделать это? PFB моя конфигурация xml

<suite name="Default suite" parallel="classes">
<listeners>
         <listener class-name="org.uncommons.reportng.HTMLReporter" />
</listeners>
<test verbose="2" name="Default test" group-by-instances="true">
    <classes>
        <class name="com.test.factory.RAExcelFactory"/> 
    </classes>
  </test> <!-- Default test -->
</suite> <!-- Default suite -->

person Mallikarjun Pasunkili    schedule 25.05.2017    source источник


Ответы (1)


Нет, в настоящее время это невозможно в TestNG.

В качестве альтернативы вы можете рассмотреть возможность выполнения следующих действий вместо использования фабрики.

  • Обновите до последней версии TestNG
  • Создайте реализацию org.testng.IAlterSuiteListener и включите в нее логику для создания нескольких тегов <test>, используя любую логику, которая у вас есть в вашей фабрике (я предполагаю, что она использует механизм, управляемый данными).

Что-то вроде ниже

Тестовый класс

import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class StudentTest {
    private int age;
    @BeforeClass
    @Parameters("age")
    public void setup(int age) {
        this.age = age;
    }

    @Test
    public void firstTest() {
        Assert.assertTrue(age >=0);
    }

    @Test(dependsOnMethods = "firstTest")
    public void secondTest() {
        Assert.assertTrue(age <= 125);
    }
}

Реализация IAlterSuiteListener

import org.testng.IAlterSuiteListener;
import org.testng.xml.XmlClass;
import org.testng.xml.XmlSuite;
import org.testng.xml.XmlTest;

import java.util.ArrayList;
import java.util.List;

public class SuiteAlteringListener implements IAlterSuiteListener {
    @Override
    public void alter(List<XmlSuite> suites) {
        for (XmlSuite suite : suites) {
            List<XmlTest> tests = new ArrayList<>();
            Integer[] datum = getData();
            for (Integer data : datum) {
                XmlTest test = new XmlTest(suite);
                test.setName("test_" + data);
                test.addParameter("age", Integer.toString(data));
                test.getClasses().add(new XmlClass(StudentTest.class));
            }
        }
    }

    private Integer[] getData() {
        //Change this to your data provider implementation
        return new Integer[]{
                1, 2, 3
        };
    }
}

XML-файл пакета

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="my_suite" parallel="false" verbose="3">
    <listeners>
        <listener class-name="com.rationaleemotions.stackoverflow.SuiteAlteringListener"/>
    </listeners>

</suite>

и вот как выглядит testng-results.xml (другие отчеты также будут иметь аналогичные детали). Я просто решил прикрепить самое простое представление.

<?xml version="1.0" encoding="UTF-8"?>
<testng-results skipped="0" failed="0" ignored="0" total="6" passed="6">
  <reporter-output>
  </reporter-output>
  <suite name="my_suite" duration-ms="10077" started-at="2017-05-27T07:49:36Z" finished-at="2017-05-27T07:49:46Z">
    <groups>
    </groups>
    <test name="test_1" duration-ms="24" started-at="2017-05-27T07:49:36Z" finished-at="2017-05-27T07:49:36Z">
      <class name="com.rationaleemotions.stackoverflow.StudentTest">
        <test-method status="PASS" signature="setup(int)[pri:0, instance:com.rationaleemotions.stackoverflow.StudentTest@61dc03ce]" name="setup" is-config="true" duration-ms="8" started-at="2017-05-27T13:19:36Z" finished-at="2017-05-27T13:19:36Z">
          <params>
            <param index="0">
              <value>
                <![CDATA[1]]>
              </value>
            </param>
          </params>
          <reporter-output>
          </reporter-output>
        </test-method> <!-- setup -->
        <test-method status="PASS" signature="firstTest()[pri:0, instance:com.rationaleemotions.stackoverflow.StudentTest@61dc03ce]" name="firstTest" duration-ms="2" started-at="2017-05-27T13:19:36Z" finished-at="2017-05-27T13:19:36Z">
          <reporter-output>
          </reporter-output>
        </test-method> <!-- firstTest -->
        <test-method status="PASS" signature="secondTest()[pri:0, instance:com.rationaleemotions.stackoverflow.StudentTest@61dc03ce]" name="secondTest" duration-ms="1" started-at="2017-05-27T13:19:36Z" depends-on-methods="com.rationaleemotions.stackoverflow.StudentTest.firstTest" finished-at="2017-05-27T13:19:36Z">
          <reporter-output>
          </reporter-output>
        </test-method> <!-- secondTest -->
      </class> <!-- com.rationaleemotions.stackoverflow.StudentTest -->
    </test> <!-- test_1 -->
    <test name="test_2" duration-ms="2" started-at="2017-05-27T07:49:41Z" finished-at="2017-05-27T07:49:41Z">
      <class name="com.rationaleemotions.stackoverflow.StudentTest">
        <test-method status="PASS" signature="setup(int)[pri:0, instance:com.rationaleemotions.stackoverflow.StudentTest@458ad742]" name="setup" is-config="true" duration-ms="0" started-at="2017-05-27T13:19:41Z" finished-at="2017-05-27T13:19:41Z">
          <params>
            <param index="0">
              <value>
                <![CDATA[2]]>
              </value>
            </param>
          </params>
          <reporter-output>
          </reporter-output>
        </test-method> <!-- setup -->
        <test-method status="PASS" signature="firstTest()[pri:0, instance:com.rationaleemotions.stackoverflow.StudentTest@458ad742]" name="firstTest" duration-ms="0" started-at="2017-05-27T13:19:41Z" finished-at="2017-05-27T13:19:41Z">
          <reporter-output>
          </reporter-output>
        </test-method> <!-- firstTest -->
        <test-method status="PASS" signature="secondTest()[pri:0, instance:com.rationaleemotions.stackoverflow.StudentTest@458ad742]" name="secondTest" duration-ms="0" started-at="2017-05-27T13:19:41Z" depends-on-methods="com.rationaleemotions.stackoverflow.StudentTest.firstTest" finished-at="2017-05-27T13:19:41Z">
          <reporter-output>
          </reporter-output>
        </test-method> <!-- secondTest -->
      </class> <!-- com.rationaleemotions.stackoverflow.StudentTest -->
    </test> <!-- test_2 -->
    <test name="test_3" duration-ms="2" started-at="2017-05-27T07:49:46Z" finished-at="2017-05-27T07:49:46Z">
      <class name="com.rationaleemotions.stackoverflow.StudentTest">
        <test-method status="PASS" signature="setup(int)[pri:0, instance:com.rationaleemotions.stackoverflow.StudentTest@66d2e7d9]" name="setup" is-config="true" duration-ms="0" started-at="2017-05-27T13:19:46Z" finished-at="2017-05-27T13:19:46Z">
          <params>
            <param index="0">
              <value>
                <![CDATA[3]]>
              </value>
            </param>
          </params>
          <reporter-output>
          </reporter-output>
        </test-method> <!-- setup -->
        <test-method status="PASS" signature="firstTest()[pri:0, instance:com.rationaleemotions.stackoverflow.StudentTest@66d2e7d9]" name="firstTest" duration-ms="0" started-at="2017-05-27T13:19:46Z" finished-at="2017-05-27T13:19:46Z">
          <reporter-output>
          </reporter-output>
        </test-method> <!-- firstTest -->
        <test-method status="PASS" signature="secondTest()[pri:0, instance:com.rationaleemotions.stackoverflow.StudentTest@66d2e7d9]" name="secondTest" duration-ms="0" started-at="2017-05-27T13:19:46Z" depends-on-methods="com.rationaleemotions.stackoverflow.StudentTest.firstTest" finished-at="2017-05-27T13:19:46Z">
          <reporter-output>
          </reporter-output>
        </test-method> <!-- secondTest -->
      </class> <!-- com.rationaleemotions.stackoverflow.StudentTest -->
    </test> <!-- test_3 -->
  </suite> <!-- my_suite -->
</testng-results>

Будет ли это работать для вас?

person Krishnan Mahadevan    schedule 27.05.2017
comment
Спасибо за подробный ответ, я не знал об IAlterSuiteListener, поэтому я создал новый репортер, изменив HTMLReporter в ReportNG, чтобы создать новый результат теста для каждого экземпляра на основе имени теста (метод getTestName из интерфейса ITest) и включил его как слушатель набора тестов. Я использовал группу java8 и отражение, чтобы добиться того же, и это работает! - person Mallikarjun Pasunkili; 27.05.2017
comment
Малликарджун Пасункили: У меня такая же проблема. Можете ли вы предоставить мне подробную информацию о том, как вы работали с HTML Reporter. Спасибо. - person bvr; 17.03.2018
comment
Кришнан, как я могу сделать то же самое для @factory, который представляет собой двумерный объект (из листа .xls). - person bvr; 17.03.2018