We have a team that uses method selectors and the IDEA plugin for
TestNG. Since the plugin creates a temporary xml file for running the
tests, there's no way to specify the method selectors. The plugin
does however allow you to specify command line options to TestNG.
We've been using the following patch for some time now that allows
specifying method selectors as a command line option. I figured I
should submit it in case anyone else found it useful.
This new argument has the format
-methodselector classname:priority
Multiple selectors can be specified like
-methodselector com.company.MySelector:5,com.company.AnotherSelector:
7
Index: src/org/testng/TestNGCommandLineArgs.java
===================================================================
--- src/org/testng/TestNGCommandLineArgs.java (revision 922)
+++ src/org/testng/TestNGCommandLineArgs.java (working copy)
@@ -12,7 +12,7 @@
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
-import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -47,6 +47,8 @@
public static final String GROUPS_COMMAND_OPT = "-groups";
public static final String JUNIT_DEF_OPT = "-junit";
public static final String LISTENER_COMMAND_OPT = "-listener";
+ /** Value is a Map<String classname, Integer priority> */
+ public static final String METHOD_SELECTOR_OPT = "-methodselector";
public static final String MASTER_OPT = "-master";
public static final String OBJECT_FACTORY_COMMAND_OPT = "-
objectfactory";
/**
@@ -212,6 +214,30 @@
+ LISTENER_COMMAND_OPT);
}
}
+ else if (METHOD_SELECTOR_OPT.equalsIgnoreCase(argv[i])) {
+ if ((i + 1) < argv.length) {
+ String strClass = argv[++i];
+ Map<String,Integer> methodSelectors = new
HashMap<String,Integer>();
+ String[] strs = Utils.split(strClass, ",");
+ for (String cls : strs) {
+ String[] sel = Utils.split(cls, ":");
+ try {
+ if (sel.length == 2) {
+ methodSelectors.put(sel[0],
Integer.valueOf(sel[1]));
+ } else {
+ LOGGER.error("WARNING: method selector " +
cls + " has the wrong number of values");
+ }
+ }catch (NumberFormatException nfe) {
+ LOGGER.error("WARNING: MethodSelector priority
was not an integer for " + cls);
+ }
+ }
+ arguments.put(METHOD_SELECTOR_OPT, methodSelectors);
+ }
+ else {
+ LOGGER.error("WARNING: missing IMethodSelector class/file
list argument after "
+ + METHOD_SELECTOR_OPT);
+ }
+ }
else if (TESTCLASS_COMMAND_OPT.equalsIgnoreCase(argv[i])) {
if ((i + 1) < argv.length) {
while ((i + 1) < argv.length) {
@@ -742,11 +768,17 @@
+ " and/or "
+ ISuiteListener.class.getName()
+ "]");
+ System.out.println("[" + METHOD_SELECTOR_OPT
+ + " list of .class files or list of class names implementing
"
+ + IMethodSelector.class.getName()
+ + " with a priority value "
+ + "]");
System.out.println("[" + PARALLEL_MODE
+ " methods|tests]");
System.out.println("\t\trun tests in parallel using the specified
mode");
System.out.println("[" + THREAD_COUNT
+ " number of threads to use when running tests in
parallel]");
+ System.out.println("\t\twhether to ever invoke a config method
again after is has failed once");
System.out.println("[" + SUITE_NAME_OPT + " name]");
System.out.println("\t\tDefault name of test suite, if not
specified in suite definition file or source code");
System.out.println("[" + TEST_NAME_OPT + " Name]");
Index: src/org/testng/TestNG.java
===================================================================
--- src/org/testng/TestNG.java (revision 922)
+++ src/org/testng/TestNG.java (working copy)
@@ -516,14 +516,6 @@
xmlTest.setName(testName);
}
- List<XmlMethodSelector> selectors =
xmlTest.getMethodSelectors();
- for (String name : m_methodDescriptors.keySet()) {
- XmlMethodSelector xms = new XmlMethodSelector();
- xms.setName(name);
- xms.setPriority(m_methodDescriptors.get(name));
- selectors.add(xms);
- }
-
xmlTest.getXmlClasses().add(xmlClasses[i]);
}
@@ -876,6 +868,15 @@
xmlSuite.setVerbose(m_verbose);
}
+ for (XmlTest t : xmlSuite.getTests()) {
+ for (Map.Entry<String, Integer> ms :
m_methodDescriptors.entrySet()) {
+ XmlMethodSelector xms = new XmlMethodSelector();
+ xms.setName(ms.getKey());
+ xms.setPriority(ms.getValue());
+ t.getMethodSelectors().add(xms);
+ }
+ }
+
PoolService.initialize(xmlSuite.getDataProviderThreadCount());
result.add(createAndRunSuiteRunners(xmlSuite));
PoolService.getInstance().shutdown();
@@ -1045,6 +1046,13 @@
setListenerClasses(listenerClasses);
}
+ Map<String,Integer> methodSelectors = (Map<String, Integer>)
cmdLineArgs.get(TestNGCommandLineArgs.METHOD_SELECTOR_OPT);
+ if (null != methodSelectors) {
+ for (Map.Entry<String, Integer> e :
methodSelectors.entrySet()) {
+ addMethodSelector(e.getKey(), e.getValue());
+ }
+ }
+
Class objectFactory = (Class)
cmdLineArgs.get(TestNGCommandLineArgs.OBJECT_FACTORY_COMMAND_OPT);
if(null != objectFactory) {
setObjectFactory(objectFactory);
Index: test/src/test/methodselectors/NoTest1MethodSelector.java
===================================================================
--- test/src/test/methodselectors/NoTest1MethodSelector.java (revision
0)
+++ test/src/test/methodselectors/NoTest1MethodSelector.java (revision
0)
@@ -0,0 +1,33 @@
+package test.methodselectors;
+
+import java.util.List;
+
+import org.testng.IMethodSelector;
+import org.testng.IMethodSelectorContext;
+import org.testng.ITestNGMethod;
+
+public class NoTest1MethodSelector implements IMethodSelector {
+
+ public boolean includeMethod(IMethodSelectorContext context,
+ ITestNGMethod method, boolean isTestMethod)
+ {
+ for (String group : method.getGroups()) {
+ if (group.equals("test1")) {
+ ppp( method.getMethodName() + " is group test1, don't
include" );
+ context.setStopped(true);
+ return false;
+ }
+ }
+ ppp( method.getMethodName() + " is not in group test1" );
+ return true;
+ }
+
+ public void setTestMethods(List<ITestNGMethod> testMethods) {
+
+ }
+
+ public static void ppp(String s) {
+ //System.out.println("[NoTest1MethodSelector] " + s);
+ }
+
+}
Index: test/src/test/methodselectors/CommandLineTest.java
===================================================================
--- test/src/test/methodselectors/CommandLineTest.java (revision 0)
+++ test/src/test/methodselectors/CommandLineTest.java (revision 0)
@@ -0,0 +1,167 @@
+package test.methodselectors;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.testng.Assert;
+import org.testng.ITestResult;
+import org.testng.TestListenerAdapter;
+import org.testng.TestNG;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import testhelper.OutputDirectoryPatch;
+
+public class CommandLineTest {
+
+ private String[] argv;
+ private TestListenerAdapter tla;
+
+ @BeforeMethod
+ public void setup() {
+ ppp("setup()");
+ argv = new String[]{
+ "-log", "0",
+ "-d", OutputDirectoryPatch.getOutputDirectory(),
+ "-testclass", "test.methodselectors.SampleTest",
+ "-methodselector", "",
+ "-groups", ""
+ };
+ tla = new TestListenerAdapter();
+ }
+
+ @Test
+ public void commandLineNegativePriorityAllGroups() {
+ ppp("commandLineNegativePriorityAllGroups()");
+ argv[7] = "test.methodselectors.AllTestsMethodSelector:-1";
+ TestNG.privateMain(argv, tla);
+ String[] passed = {
+ "test1", "test2", "test3"
+ };
+ String[] failed = {
+ };
+ verifyTests("Passed", passed, tla.getPassedTests());
+ verifyTests("Failed", failed, tla.getFailedTests());
+ }
+
+ @Test
+ public void commandLineNegativePriorityGroup2() {
+ ppp("commandLineNegativePriorityGroup2()");
+ argv[7] = "test.methodselectors.Test2MethodSelector:-1";
+ TestNG.privateMain(argv, tla);
+ String[] passed = {
+ "test2"
+ };
+ String[] failed = {
+ };
+ verifyTests("Passed", passed, tla.getPassedTests());
+ verifyTests("Failed", failed, tla.getFailedTests());
+ }
+
+ @Test
+ public void commandLineLessThanPriorityTest1Test() {
+ ppp("commandLineLessThanPriorityTest1Test()");
+ argv[7] = "test.methodselectors.Test2MethodSelector:5";
+ argv[9] = "test1";
+ TestNG.privateMain(argv, tla);
+ String[] passed = {
+ "test1", "test2"
+ };
+ String[] failed = {
+ };
+ verifyTests("Passed", passed, tla.getPassedTests());
+ verifyTests("Failed", failed, tla.getFailedTests());
+ }
+
+ @Test
+ public void commandLineGreaterThanPriorityTest1Test2() {
+ ppp("commandLineGreaterThanPriorityTest1Test2()");
+ argv[7] = "test.methodselectors.Test2MethodSelector:15";
+ argv[9] = "test1";
+ TestNG.privateMain(argv, tla);
+ String[] passed = {
+ "test2"
+ };
+ String[] failed = {
+ };
+ verifyTests("Passed", passed, tla.getPassedTests());
+ verifyTests("Failed", failed, tla.getFailedTests());
+ }
+ @Test
+ public void commandLineLessThanPriorityAllTests() {
+ ppp("commandLineLessThanPriorityAllTests()");
+ argv[7] = "test.methodselectors.AllTestsMethodSelector:5";
+ argv[9] = "test1";
+ TestNG.privateMain(argv, tla);
+ String[] passed = {
+ "test1", "test2", "test3"
+ };
+ String[] failed = {
+ };
+ verifyTests("Passed", passed, tla.getPassedTests());
+ verifyTests("Failed", failed, tla.getFailedTests());
+ }
+
+ @Test
+ public void commandLineMultipleSelectors() {
+ ppp("commandLineMultipleSelectors()");
+ argv[7] = "test.methodselectors.NoTestSelector:
7,test.methodselectors.Test2MethodSelector:5";
+ argv[9] = "test1";
+ TestNG.privateMain(argv, tla);
+ String[] passed = {
+ "test1", "test2"
+ };
+ String[] failed = {
+ };
+ verifyTests("Passed", passed, tla.getPassedTests());
+ verifyTests("Failed", failed, tla.getFailedTests());
+ }
+
+ @Test
+ public void commandLineNoTest1Selector() {
+ ppp("commandLineNoTest1Selector()");
+ argv[7] = "test.methodselectors.NoTest1MethodSelector:5";
+ TestNG.privateMain(argv, tla);
+ String[] passed = {
+ "test2", "test3"
+ };
+ String[] failed = {
+ };
+ verifyTests("Passed", passed, tla.getPassedTests());
+ verifyTests("Failed", failed, tla.getFailedTests());
+ }
+
+ @Test
+ public void commandLineTestWithXmlFile() {
+ ppp("commandLineTestWithXmlFile()");
+ argv[4] = argv[5] = "";
+ argv[7] = "test.methodselectors.NoTest1MethodSelector:5";
+ argv[8] = "test/testng-methodselectors.xml";
+ TestNG.privateMain(argv, tla);
+ String[] passed = {
+ "test2", "test3"
+ };
+ String[] failed = {
+ };
+ verifyTests("Passed", passed, tla.getPassedTests());
+ verifyTests("Failed", failed, tla.getFailedTests());
+ }
+
+ private void verifyTests(String title, String[] expected,
List<ITestResult> found) {
+ List<String> resultMethods = new ArrayList<String>();
+ for( ITestResult result : found ) {
+ resultMethods.add( result.getName() );
+ }
+
+ Assert.assertEquals(resultMethods.size(), expected.length, "wrong
number of " + title + " tests");
+
+ for(String e : expected) {
+ Assert.assertTrue(resultMethods.contains(e), "Expected to find
method " + e + " in "
+ + title + " but didn't find it.");
+ }
+ }
+
+ public static void ppp(String s) {
+ //System.out.println("[CommandLineTest] " + s);
+ }
+}
Index: test/src/test/methodselectors/NoTestSelector.java
===================================================================
--- test/src/test/methodselectors/NoTestSelector.java (revision 922)
+++ test/src/test/methodselectors/NoTestSelector.java (working copy)
@@ -19,6 +19,6 @@
}
private static void ppp(String s) {
- System.out.println("[NoTestSelector] " + s);
+ //System.out.println("[NoTestSelector] " + s);
}
}
Index: test/testng.xml
===================================================================
--- test/testng.xml (revision 922)
+++ test/testng.xml (working copy)
@@ -384,6 +384,7 @@
<classes>
<class name="test.methodselectors.MethodSelectorTest" />
<class name="test.methodselectors.BeanShellTest" />
+ <class name="test.methodselectors.CommandLineTest" />
</classes>
</test>
Index: test/testng-methodselectors.xml
===================================================================
--- test/testng-methodselectors.xml (revision 0)
+++ test/testng-methodselectors.xml (revision 0)
@@ -0,0 +1,8 @@
+<!DOCTYPE suite SYSTEM "
http://testng.org/testng-1.0.dtd">
+<suite name="Sample Suite">
+ <test verbose="1" name="Sample">
+ <classes>
+ <class name="test.methodselectors.SampleTest" />
+ </classes>
+ </test>
+</suite>