【问题标题】:TestNG - Run each instance from TestNG factory as separate testTestNG - 从 TestNG 工厂运行每个实例作为单独的测试
【发布时间】:2017-05-25 07:00:20
【问题描述】:

我使用 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 -->

【问题讨论】:

    标签: testing automated-tests testng reportng


    【解决方案1】:

    不,目前在 TestNG 中这是不可能的。

    或者,您可以考虑执行以下操作而不是使用工厂。

    • 升级到最新的TestNG版本
    • 构建org.testng.IAlterSuiteListener 的实现,并在其中包含使用您工厂中的任何逻辑构造多个&lt;test&gt; 标签的逻辑(我猜它利用了数据驱动机制)

    类似下面的东西

    测试类

    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>
    

    这对你有用吗?

    【讨论】:

    • 感谢您的详细回复,我不知道 IAlterSuiteListener 因此我通过修改 ReportNG 中的 HTMLReporter 创建了一个新报告器,以根据测试名称为每个实例创建一个新的测试结果(getTestName 方法来自ITest 接口)并将其作为测试套件的侦听器包含在内。我使用 java8 group by 和反射来实现相同的效果!
    • Mallikarjun Pasunkili:我也有同样的问题。您能否提供有关您如何使用 HTML Reporter 的详细信息。谢谢。
    • Krishnan,我怎样才能为@factory 做同样的事情,这是一个二维对象(来自 .xls 表)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-01
    • 1970-01-01
    • 2016-09-12
    • 2017-04-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多