Question

I am testing with the wonderful TestNG-Framework. My question is if it is possible to set the annotations for @Test-annotation in the testng.xml-configuration file? I don't want to hard-code the @Test-annotation like

@Test(dataProvider = "dataFileProvider", dataProviderClass = TestDataProvider.class)

I want to configure it in the testng.xml

Was it helpful?

Solution

I have got two ideas on this case:

Workaraound 1: StaticProvider

You can easily change the Static Provider if needed

Workaraound 2: Annotation Transformer

Never tried that but should work even if have to grab the XML- data manually

Looking forward to Mr. Beust's answer... ;)

OTHER TIPS

The short answer is: no, you can't add annotations to your code from testng.xml.

You can modify existing annotations with an Annotation Transformer, as explained by Frank.

Sometimes, you just really want to do something and you can't, like accessing private variables to fix memory leaks. Figuring out how to do things like this, despite the fact that you can't are fun. In case, you really want to, I might suggest trying to run your suite using the TestNG object and before running loading the testng.xml file.

Personally, I like using 'mvn test' and unfortunately, adding the pom.xml code to run from a testng xml file will require that you supply a testng.xml file, so 'mvn test' won't work. Always make sure what 95% of programmers use works, then allow overridding.

So, I might suggest extending the testng.xml file yourself and writing some code to read the testng.xml file and configure annotations using the annotation transformer class.

Here is some code to get you started:

public class TestNGSuite {
public static void main(String[] args) {
    System.out.println("main start");
    try {
        new TestNGSuite(new Class[]{ Demo.class });
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println("main finish");
}

public TestNGSuite(Class[] classes) throws Exception {
    // Create Suite List
    List<XmlSuite> suites = new ArrayList<XmlSuite>();

    // Add Suite to Suite List
    XmlSuite suite = new XmlSuite();
    suites.add(suite);
    suite.setName("MyTestSuite");

    // Add Test to Suite
    XmlTest test = new XmlTest(suite);
    test.setName("MyTest");

    // Add Class List to Test
    List<XmlClass> xmlClasses = new ArrayList<XmlClass>();
    test.setXmlClasses(xmlClasses);

    // Add Class to Class List
    for(Class clazz: classes) {
        XmlClass xmlClass = new XmlClass(clazz);
        xmlClasses.add(xmlClass);
    }

    // Run TestNG
    TestNG testNG = new TestNG();
    testNG.setXmlSuites(suites);
    testNG.addListener(new TestNGAnnotationTransformer(methodName));
    testNG.addListener(new TestNGSuiteConsoleLogger());
    testNG.run();

    if(testNG.hasFailure()) { // Throw an exception to make mvn goal fail
        throw new Exception("Failed Tests");
    }
}

public static class TestNGSuiteConsoleLogger extends TestListenerAdapter{
      @Override
      public void onTestFailure(ITestResult tr) {
        Console.log(TestNGSuiteConsoleLogger.class, "FAILURE:"+tr.getMethod());
        tr.getThrowable().printStackTrace();
      }
}

public static class TestNGAnnotationTransformer implements IAnnotationTransformer{
      String methodToRun;
      public TestNGAnnotationTransformer(String methodName) {
              methodToRun = methodName;
      }
    public void transform(ITestAnnotation annotation, Class arg1,
            Constructor arg2, Method testMethod) {
            if (methodToRun.equals(testMethod.getName())) {
            annotation.setEnabled(true);
            }
      }
}
}

If you want to run Demo.class, make sure there is a method there with the TestNG annotation "@Test".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top