Re: [testng-users] Invoke Test Methods With TestNG Programmaticaly

1,720 views
Skip to first unread message

Krishnan Mahadevan

unread,
Jun 20, 2012, 11:30:04 PM6/20/12
to testng...@googlegroups.com
And why would you be looking to do this? Wouldnt adding the methods into desired groups and picking groups via TestNG not do the same for you (assuming the TestNG API has a way for this just as the TestNG xml does )

On Thursday, June 21, 2012, GUnit wrote:
Hi,
 
The TestNG documentation states that I can invoke TestNG programmatically like this.
 
TestNG testng = new TestNG();
testng.setTestClasses(new Class[] { Run2.class });

testng.run();

However, that is for test classes. I would like to do the same for test methods. I would expect to do something like this, which is similar to the code above.

testng.setTestMethods(Method[]};

I have looked around including the TestNG API and did not see anything of that sort. Does anyone know if this can be accomplished? One thing I can consider is to create a virtual XML test suite and then invoke that from TestNG. However, I'd rather not do that.

Any advice/suggestions are welcomed.

Thanks!

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/testng-users/-/VYJguFnpqRIJ.
To post to this group, send email to testng...@googlegroups.com.
To unsubscribe from this group, send email to testng-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/testng-users?hl=en.


--
Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"
My Scribblings @ http://wakened-cognition.blogspot.com/

P.Hill

unread,
Jun 21, 2012, 1:33:51 AM6/21/12
to testng...@googlegroups.com

GUnit

unread,
Jun 21, 2012, 8:25:55 AM6/21/12
to testng...@googlegroups.com

GUnit

unread,
Jun 21, 2012, 8:28:45 AM6/21/12
to testng...@googlegroups.com
I see that TestNG has a setGroups(String groups) method. However, the way I read this is that the name of the group corresponds to that in the TestNG xml. What I want to avoid here is anything that deals with XML. I do not want to create an XML. To me, this means that I have to create a TestNG XML, define the groups, and then use testNg.setGroups(xxx).
 
So if I can't do something like "testNG.setMethods(Method[])", then if I use groups, I would expect to be able to do something like this.
 
TestGroup group = new TestGroup(groupName);
group.includeTests(Method);
testNg.setGroups(group);
 
I know there's no such thing as a "TestGroup". This is just pseudocode. If TestNG provides something that I can do to achieve this w/o creating an XML that is what I am looking for.
 
The reason I want to do this, is something there's multipe test methods in 1 test class and I just want to run 1 or 2 of them.

On Wednesday, June 20, 2012 11:30:04 PM UTC-4, Krishnan wrote:
And why would you be looking to do this? Wouldnt adding the methods into desired groups and picking groups via TestNG not do the same for you (assuming the TestNG API has a way for this just as the TestNG xml does )

On Thursday, June 21, 2012, GUnit wrote:
Hi,
 
The TestNG documentation states that I can invoke TestNG programmatically like this.
 
TestNG testng = new TestNG();
testng.setTestClasses(new Class[] { Run2.class });

testng.run();

However, that is for test classes. I would like to do the same for test methods. I would expect to do something like this, which is similar to the code above.

testng.setTestMethods(Method[]};

I have looked around including the TestNG API and did not see anything of that sort. Does anyone know if this can be accomplished? One thing I can consider is to create a virtual XML test suite and then invoke that from TestNG. However, I'd rather not do that.

Any advice/suggestions are welcomed.

Thanks!

--
You received this message because you are subscribed to the Google Groups "testng-users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/testng-users/-/VYJguFnpqRIJ.
To post to this group, send email to testng...@googlegroups.com.
To unsubscribe from this group, send email to testng-users+unsubscribe@googlegroups.com.

For more options, visit this group at http://groups.google.com/group/testng-users?hl=en.

Krishnan Mahadevan

unread,
Jun 21, 2012, 11:30:19 AM6/21/12
to testng...@googlegroups.com
I dont think that setGroups() has anything to do with an XML file.

TestNG API AFAIK, provides you with two ways in which you pick and choose methods :

1. Via setGroups() wherein you decide to pick up whichever groups you want to run and thus select 1 or more methods.
2. Via XmlInclude wherein you filter out a bunch of method names which should be included and TestNG works with them.

Please find below mock examples for both the variants.


Variant #1 : using setGroups()

package raw.code;

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

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

public class SampleClass {

public static void main(String[] args) {
TestNG testng = new TestNG();
List<XmlSuite> suites = new ArrayList<XmlSuite>();
XmlSuite suite = new XmlSuite();
List<XmlTest> tests = new ArrayList<XmlTest>();
XmlTest test = new XmlTest();
List<XmlClass> classes = new ArrayList<XmlClass>();
XmlClass clazz = new XmlClass(Bar.class);
classes.add(clazz);
test.setXmlClasses(classes);
test.setSuite(suite);
test.setName("Mahadevan");
tests.add(test);
suite.setTests(tests);
suite.setName("Krishnan");
suites.add(suite);
suite.setTests(tests);
testng.setXmlSuites(suites);
testng.setGroups("runMe");
testng.run();
}

public class Bar {

@Test(groups = "runMe")
public void foo() {
System.out.print("I am foo()");
}

@Test
public void bar() {
System.out.println("I am bar()");
}
}
}



Here's the output :

[TestNG] Running:
  Command line suite

I am foo()
===============================================
Krishnan
Total tests run: 1, Failures: 0, Skips: 0
===============================================

Variant #2 : using setIncludedMethods()


package raw.code;

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

import org.testng.TestNG;
import org.testng.annotations.Test;
import org.testng.xml.XmlClass;
import org.testng.xml.XmlInclude;
import org.testng.xml.XmlSuite;
import org.testng.xml.XmlTest;

public class SampleClass {

public static void main(String[] args) {
// defining which methods to execute
XmlInclude include = new XmlInclude("bar");
List<XmlInclude> includedMethods = new ArrayList<XmlInclude>();
includedMethods.add(include);

// Adding the methods to run to XmlClasses
XmlClass clazz = new XmlClass(Bar.class);
clazz.setIncludedMethods(includedMethods);
List<XmlClass> classes = new ArrayList<XmlClass>();
classes.add(clazz);

// Adding the list of classes to a test

List<XmlSuite> suites = new ArrayList<XmlSuite>();
XmlSuite suite = new XmlSuite();
List<XmlTest> tests = new ArrayList<XmlTest>();
XmlTest test = new XmlTest();

test.setXmlClasses(classes);
test.setSuite(suite);
test.setName("Mahadevan");
tests.add(test);
suite.setTests(tests);
suite.setName("Krishnan");
suites.add(suite);
suite.setTests(tests);
TestNG testng = new TestNG();
testng.setXmlSuites(suites);

testng.run();
}

public class Bar {

@Test(groups = "runMe")
public void foo() {
System.out.print("I am foo()");
}

@Test
public void bar() {
System.out.println("I am bar()");
}
}
}


Output :

[TestNG] Running:
  Command line suite

I am bar()

===============================================
Krishnan
Total tests run: 1, Failures: 0, Skips: 0
===============================================




Thanks & Regards
Krishnan Mahadevan

"All the desirable things in life are either illegal, expensive, fattening or in love with someone else!"



To view this discussion on the web visit https://groups.google.com/d/msg/testng-users/-/AxGWH-ATuz8J.

To post to this group, send email to testng...@googlegroups.com.
To unsubscribe from this group, send email to testng-users...@googlegroups.com.

GUnit

unread,
Jun 22, 2012, 4:09:25 PM6/22/12
to testng...@googlegroups.com

GUnit

unread,
Jun 22, 2012, 4:15:17 PM6/22/12
to testng...@googlegroups.com
Hi Krishnan,
 
Thanks for your help. This whole time, what I wanted to avoid was not just specifically dealing with XML files, but also virtual XMLs. So it seems like what I had initially proposed for an alternative, which is what you think I should do, is the only way to achieve this. I just thought that there would be an easier way to do this and I'm not saying what you have is not easy. The only reason I say this is that JUnit provides just a simple "setTestMethod()" method like I had mentioned and I was hoping to do the same with TestNG.
 
I really appreciate your help.
Thanks!

Mike

unread,
Feb 25, 2013, 4:53:02 PM2/25/13
to testng...@googlegroups.com
Hi Maniganda,

I basically followed what was in the documentation, but I did have to experiment a bit.  I can show you an example of what I had in one of my test suites.  Some of the routines are from a library, so I will note which come from the library.  Once it is done it ends up writing out the XML file in the report directory, but basically I believe it is all kept in memory as you build it an run it.

Here is the main routine in my test suite:

    /**
     * This is the list of classes that make up this test suite, they are in the
     * format: <package>.<classname>.
     */
    private static final String[] testClasses =
    {
        "archives_sb.ArcBatch",
        "archives_sb.ArcExp",
        "archives_sb.ArcSB",
        "archives_sb.ArcSearch",
        "archives_sb.ArcSum",
        "archives_sb.ArchivesSB"
    };

    public static void main(String[] args)
    {
        String reportDir;

        TestNG testng = new TestNG();

        testParams = new TestParameters(args);
        reportDir = testParams.getParamValue(TestParameters.reportDirMapName);
        reportDir = reportDir.substring(0, reportDir.length() - 3); // Remove "\\DD"
        testParams.setParamValue(TestParameters.reportDirMapName, reportDir);
        testParams.setupTestXmlFile(testng);
        try
        {
            testParams.setupSuite("Archives_SB");
            testParams.addTest("DOTN-ARC", testClasses);
            testParams.addSuite(); // Add the suite to the TestNG instance
            testParams.finalizeTestXmlFile(); // The TestNG XML file is complete
            testng.run();   // Kick off the selected tests for this browser
            if (passed)
                System.exit(0); // All tests passed!
            else
                System.exit(1); // Some test(s) failed...
        }   // try
        catch (Exception ex)
        {
            Logger.getLogger(ArchivesSB.class.getName()).
                    log(Level.SEVERE, null, ex);
            System.exit(1); // Our setup failed...
        }   // catch
    }   // main()

Here are the library routines it uses:

    /**
     * This is the instance of TestNG that we are running under.  It is really
     * only used to set the output directory for the test results, but it might
     * have other uses later, so it is made public here.
     */
    public TestNG testNG = null;
    /**
     *
     */
    private List<XmlSuite> suites = null;
    /**
     * This is the variable we use to build up a Suite description to be added
     * to the suites list.  It is initialized by calling <i>setupSuite()</i> and
     * cleared (set to <i>null</i>) after you call <i>addSuite()</i>.
     * @see #setupSuite(java.lang.String)
     * @see #addSuite()
     */
    private XmlSuite suite = null;
    /**
     * This creates the XML file needed to run the TestNG methods.  All the
     * calling routine needs to do is set up a TestNG instance and pass that and
     * the name of the test to be run.  Afterwards you need to call one of these
     * methods at least once, to set up what tests to run:<br/>
     * &nbsp;&nbsp;&nbsp;&nbsp;<i>addSuite()</i> - Repeatable per XML file<br/>
     * &nbsp;&nbsp;&nbsp;&nbsp;<i>addTest()</i> - Repeatable per suite<br/>
     * &nbsp;&nbsp;&nbsp;&nbsp;<i>finalizeTextXmlFile()</i> - Called when done<br/><br/>
     *
     * You <b>must</b> call this routine first before all the others.<br/><br/>
     *
     * <b>NOTE: For Shift4 batch files the \\DD placed at the end of the Report
     * Directory parameter needs to be removed, because the batch files will
     * append \Current to it and copies the files into \YYYY-MM-DD</b><br/><br/>
     *
     * <b>Side effect: The passedTestNG is copied to the testNG field for this
     * class, so any previous TestNG instance that was there is lost.</b>
     * @param passedTestNG Is an instance of TestNG created for running the tests for
     *        this program.  After this comes back all you need to do is use the
     *        run() method for it to fire off the TestNG tests.
     * @see #addSuite()
     * @see #addTest(java.lang.String, java.lang.String[])
     * @see #finalizeTestXmlFile()
     */
    public void setupTestXmlFile(TestNG passedTestNG)
    {
        testNG = passedTestNG;
        suites = new ArrayList<>();
        testNG.setOutputDirectory(getParamValue(reportDirMapName));
    }   // setupTestXmlFile(TestNG passedTestNG)

    /**
     * This routine is called after <i>setupTestXmlFile()</i> has been called.
     * The current set of parameter values will be used for this suite.  You
     * then want to call <i>setupTest()</i> to setup the first test for the
     * suite, which you may do as many times as you wish.  Once the suite has
     * all the tests added to it you need to call <i>addSuite()</i> to have it
     * added to the TestNG XML file.
     * @param nameString This is the name of the Suite as it will appear in the
     *        TestNG XML file.  Typically for us this will be the name of the
     *        test tab.  It should match the Suite name listed for the Test
     *        annotation in the test code.
     * @throws Exception Throws exception if called before <i>addSuite()</i> has
     *         cleared the suite variable from a previous <i>setupSuite()</i>.
     * @see #setupTestXmlFile(org.testng.TestNG)
     * @see #addTest(java.lang.String, java.lang.String[])
     */
    public void setupSuite(String nameString) throws Exception
    {
        int i;
        Map<String, String> parameterMap = new HashMap<>();

        if (suite != null)
            throw new Exception(
                    "Call to setupSuite() before addSuite() was called.");

        suite = new XmlSuite();

        for (i = 0; i < paramStrings.length; i++)
        {   // Initialize the default parameters we want in our TestNG XML config file.
            parameterMap.put(paramStrings[i], valueStrings[i]);
        }   // for

        suite.setParameters(parameterMap);
        suite.setName(nameString);
    }   // setupSuite(String nameString)

    /**
     * This adds a new Test group to the current Suite.  The current set of
     * parameter values will be used for this test, so it can be different from
     * those of the current Suite, if you need them to be.  You <b>must</b> have
     * called <i>setupSuite()</i> before calling this method, but you may call
     * this method several times per Suite, so you can add multiple test groups.
     * @param groupNameString This is the name of the Group as it will appear in
     *        the TestNG XML file.  It can be empty, or use some name to mark it
     *        as belonging to a particular group.  You can use that group name
     *        in the Test annotation in your code, but they do not have to match.
     * @param testClasses This is the list of Java classes that are used by this
     *        test group.  Example: simplegridtestng.DOTN_LoginTest
     * @see #setupSuite(java.lang.String)
     */
    public void addTest(String groupNameString, String[] testClasses)
    {
        int i;
        List<XmlClass> classes = new ArrayList<>();
        XmlTest test;
        Map<String, String> parameterMap = new HashMap<>();

        test = new XmlTest(suite);
        test.setName(groupNameString);
        test.setPreserveOrder("true"); // This defaults to "false"

        for (i = 0; i < paramStrings.length; i++)
        {   // Initialize the parameters we want for this test group.
            parameterMap.put(paramStrings[i], valueStrings[i]);
        }   // for

        for (i = 0; i < testClasses.length; i++)
        {   // Add all the classes from the array to this test instance.
            classes.add(new XmlClass(testClasses[i]));
        }   // for

        test.setParameters(parameterMap);
        test.setXmlClasses(classes);
    }   // addTest(String nameString, String[] testClasses)

    /**
     * This will add the current Suite to the list of Suites to be written to
     * the TestNG XML file and will clear the Suite variable.  To create an
     * additional Suite you must call <i>setupSuite()</i> again.  Once all the
     * suites have been created you <b>must</b> call <i>finalizeTestXmlFile()</i>
     * to create the TestNG XML file to run the tests.  You <b>must</b> have
     * called <i>setupSuite()</i> to initialize the Suite variable and made at
     * least one call to <i>addTest()</i> to add at least one test for the suite
     * before calling this method.
     * @see #setupSuite(java.lang.String)
     * @see #addTest(java.lang.String, java.lang.String[])
     */
    public void addSuite()
    {
        suites.add(suite);
        suite = null;
    }   // addSuite()

    /**
     * This will finalize the testng.xml file that will be used to run the tests
     * with the <i>TestNG.run()</i> method.  It adds all the suites that have
     * been added by calls to <i>addSuite()</i> to the instance of testNG,
     * making it ready to have the <i>testNG.run()</i> method invoked.<br/><br/>
     * <b>Note: Do not invoke the <i>testNG.run()</i> method until you have done
     * a call to <i>setupTestXmlFile()</i> and at least one call to <i>
     * addSuite()</i>.</b>
     * @see #setupTestXmlFile(org.testng.TestNG)
     * @see #addSuite()
     */
    public void finalizeTestXmlFile()
    {
        testNG.setXmlSuites(suites);
        suites = null;
    }   // finalizeTestXmlFile()

I am not sure if this meets your needs, but at least you can get an idea of how I have been doing it and maybe it will help you figure out what you need to do.  You were trying to set some things up that I didn't need to for my tests, like threading.

I hope it helps you.

Mike

On Wednesday, February 20, 2013 2:34:25 AM UTC-8, Maniganda perumal wrote:
Krishnan,

I am struggling in this issue for more than a  3 hours. My task is to create a virtually testng.xml file and run that from the command prompt. I goggled and i read many forums i am not getting solution. Please help me to resolve this issue.

My code to create a virtual xml file:



        XmlSuite suite = new XmlSuite();
        suite.setName("Testing");
        suite.setVerbose(1);
        suite.setPreserveOrder("true");
        suite.setThreadCount(4);
        suite.setParallel("tests");
        suite.setTimeOut("5000");

        // Test
        XmlTest test = new XmlTest(suite);
        test.setName("Browser One");
        test.addParameter("Browser", Brow);

        XmlTest testOne = new XmlTest(suite);
        testOne.setName("Browser Two");
        testOne.addParameter("Browser", Brows);


        List<XmlTest> tests = new ArrayList<XmlTest>();
        tests.add(test);
        tests.add(testOne);

        // Class

        List<XmlClass> classes = new ArrayList<XmlClass>();
        classes.add(new XmlClass("test.TestngCheck"));
        test.setXmlClasses(classes);
        testOne.setXmlClasses(classes);

        suite.setTests(tests);

        // Suite

        List<XmlSuite> suites = new ArrayList<XmlSuite>();
        suites.add(suite);
        TestNG tng = new TestNG();
        tng.setXmlSuites(suites);
        try {
            // Running the Suite file.
            tng.run();
        } catch (Exception e) {
            log.error("Creating XML Suite " + e.getLocalizedMessage());
        }

Regards,
Mani.
Reply all
Reply to author
Forward
0 new messages