简体   繁体   English

如何让TestNG- @ Factory以特定顺序实例化测试类?

[英]how to get TestNG-@Factory to instantiate test classes in a particular order?

I am using TestNG for my selenium tests. 我正在用TestNG进行硒测试。 There is a test called "Create Firm" which needs to be run multiple times on my laptop. 有一个名为“ Create Firm”的测试,该测试需要在我的笔记本电脑上运行多次。

So I have written a class called "CreateFirm" for this, and the data for various firms reside in an excel spreadsheet. 因此,我为此编写了一个名为“ CreateFirm”的类,各个公司的数据都存储在excel电子表格中。

At various times, I need to create various sets of firms, which I control using a column in Excel spreadsheet , which holds my computer name. 在不同的时间,我需要创建各种公司集,这些公司可以使用Excel电子表格中的一列进行控制,该列包含我的计算机名。

I use the @Factory to create my "CreateFirm" classes, which has one @Test method to create a Firm. 我使用@Factory创建我的“ CreateFirm”类,该类具有一个@Test方法来创建“公司”。

In excel spreadsheet If i have assigned Firm1,Firm2,Firm3,Firm4 in the same order to my laptop, @Factory creates them in a random order like Firm4,Firm3,Firm1,Firm2 在excel电子表格中如果我以相同的顺序将Firm1,Firm2,Firm3,Firm4分配给我的笔记本电脑,则@Factory会以随机顺序(如Firm4,Firm3,Firm1,Firm2)创建它们

My question is how to get @Factory to create test instances in the order that I want ? 我的问题是如何让@Factory以我想要的顺序创建测试实例?

My @Factory method is 我的@Factory方法是

      @Factory
  public Object[] runCreateFirm()
  {

        //This is where I get the list of test cases assigned to my laptop
        this.test_id_list=get_test_ids_for_test_run("Create Firm (class approach).xls", "Global");      

        Object[] result = new Object[this.test_id_list.size()];


        int index=0 ;
        for (String firm_id: this.test_id_list)
        {
            //This is where I get all the test data from the Excel spreadsheet
            HashMap<String,String> test_data_row=this.get_row_from_excel("Create Firm (class approach).xls", "Global", "test_case_id", firm_id);

            System.out.println("Inside Firm Factory ,index="+index +", test case id="+ test_data_row.get("test_case_id"));

            //CreateFirm is the class which will use the data and do all the UI actions to create a Firm
            result[index]=new CreateFirm(test_data_row);
            index++;
        }
        return result;
  }

XML is XML是

    <?xml version="1.0" encoding="UTF-8"?>
<suite name="CreateFirm Suite">
  <test name="Create Firm Test"  order-by-instances="false">
    <classes>
      <class name="regressionTests.factory.CreateFirmFactory"/>
    </classes>
  </test>
</suite>

Managed to write the interceptor method for my requirement. 设法根据我的要求编写拦截器方法。 To start with I introduced a new field in my class called "priority" . 首先,我在课堂上引入了一个名为“ priority”的新字段。 I couldnt use @Priority because, my test class had only one test method, in which case all my instantiations will have the same priority. 我不能使用@Priority,因为我的测试类只有一个测试方法,在这种情况下,我所有的实例化都将具有相同的优先级。 So I introduced a new field called priority which will have the order in which which the class should be instantiated. 因此,我引入了一个称为优先级的新字段,该字段将具有实例化该类的顺序。 I use that field in the interceptor method to set the order of instantiation 我在拦截器方法中使用该字段来设置实例化顺序

public List<IMethodInstance> intercept(List<IMethodInstance> methods,ITestContext context) 
{

    List<IMethodInstance> result = new ArrayList<IMethodInstance>();
    int array_index=0;

    for (IMethodInstance m : methods)
    {
        result.add(m);
    }
    //Now iterate through each of these test methods
    for (IMethodInstance m : methods)
    {
        try {               
            //Get the FIELD object from - Methodobj->method->class->field
            Field f = m.getMethod().getRealClass().getField("priority");
            //Get the object instance of the method object              
            array_index=f.getInt(m.getInstance());
        } 
         catch (Exception e) {
            e.printStackTrace();
        }           
        result.set(array_index-1, m);           
    }

    return result;
}

The factory instantiates test classes, it doesn't run them. 工厂实例化测试类,但不会运行它们。 If you need a specific order for your tests, you have a lot of choices between dependencies (groups and methods), priorities and method interceptors. 如果您需要特定的测试顺序,则可以在依赖项(组和方法),优先级和方法拦截器之间进行很多选择。

Referred https://github.com/cbeust/testng/issues/1410 for the solution and got a hint from example given by krmahadevan. 解决方案参阅https://github.com/cbeust/testng/issues/1410 ,并从krmahadevan给出的示例中得到了提示。 Thanks a bunch KR. 多谢KR。 I am using TestNG plugin version 6.14.0.201802161500 in Eclipse. 我正在Eclipse中使用TestNG插件版本6.14.0.201802161500。

Just overriding toString method in the Test Class does the trick. 只需在Test Class中重写toString方法即可。 In this toString method return the key parameter eg Firm1, Firm2 etc. Please refer following code for a clear understanding. 在此toString方法中,返回关键参数,例如Firm1,Firm2等。请参考以下代码以清楚了解。

TestClass.java TestClass.java

import org.testng.annotations.Test;

public class TestClass {

    String testcaseName;

    public TestClass(String testcaseName) {
        this.testcaseName = testcaseName;
    }

    @Test
    public void sendCmd() {
        System.out.println("Testcase received "+this.testcaseName);
    }

    @Override 
    public String toString() { 
        return this.testcaseName; 
    }
}

FactoryClass.java FactoryClass.java

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

public class FactoryClass {

    @DataProvider
    public static String[][] createTestCmds() {
       String[][] testData = new String[6][1];
        for (int i = 0, j= 6; i < 6 ; i++,j--) {
            testData[i][0]="Firm "+i;
        }
       return testData;
    }

    @Factory(dataProvider = "createTestCmds")
    public Object[] Factory(String testcaseName) {
        return new Object[] {new TestClass(testcaseName)};
    }
}

Test.java Test.java

import java.util.Collections;

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

public class Test {
    public static void main(String[] args) {
        TestNG testng = new TestNG();
        XmlSuite xmlSuite = new XmlSuite();
        xmlSuite.setGroupByInstances(true);
        xmlSuite.setName("Sample_Test_Suite");
        XmlTest xmlTest = new XmlTest(xmlSuite);
        xmlTest.setName("Sample_Test");
        xmlTest.setClasses(Collections.singletonList(new XmlClass(FactoryClass.class)));
        testng.setXmlSuites(Collections.singletonList(xmlSuite));
        testng.setVerbose(2);
        System.err.println("Printing the suite xml file that would be used.");
        System.err.println(xmlSuite.toXml());
        testng.run();
    }
}

Result 结果

Testcase received Firm 0
Testcase received Firm 1
Testcase received Firm 2
Testcase received Firm 3
Testcase received Firm 4
Testcase received Firm 5
PASSED: sendCmd on Firm 0
PASSED: sendCmd on Firm 1
PASSED: sendCmd on Firm 2
PASSED: sendCmd on Firm 3
PASSED: sendCmd on Firm 4
PASSED: sendCmd on Firm 5

===============================================
    Sample_Test
    Tests run: 6, Failures: 0, Skips: 0
===============================================


===============================================
Sample_Test_Suite
Total tests run: 6, Failures: 0, Skips: 0
===============================================

This problem I faced. 我遇到的这个问题。 I got a solution as mentioned above. 我得到了如上所述的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM