I am using a suite file in TestNG to define the tests I want to run. Those suites are triggered with a jenkins job and now I need to make it optional to exclude a specific group or not.
I thought about adding an additional build parameter in jenkins and add a flag to the system properties if this parameter is set like so -DexcludeMyGroup=true. In some #BeforeSuite or #BeforeTest method in my base test I want to check for the property and its value. Depending on that I want to exclude that group from my suite.
I have tried
#BeforeTest
public void beforeTest(XmlTest test) {
if (!Boolean.parseBoolean(System.getProperty("excludeMyGroup"))) {
test.addExcludedGroup("myGroup");
}
}
as well as
#BeforeSuite
public void beforeSuite(ITestContext context) {
if (!Boolean.parseBoolean(System.getProperty("excludeMyGroup"))) {
cont.getSuite().getXmlSuite().addExcludedGroup("myGroup");
}
}
but both do not work.
I have tried to use the second approach to modify other parameters such as thread count and this works fine using cont.getSuite().getXmlSuite().setThreadCount(10) but I have not yet found a way to exclude a specific group besides the suite file. Is there a possibility to exclude this afterwards?
I found a couple ways to do this:
You can also run a TestNG suite programmatically in the main method, and use command line strings to define what groups to exclude (http://static.javadoc.io/org.testng/testng/6.11/org/testng/TestNG.html#setExcludedGroups-java.lang.String-):
public static void main(String[] args) {
TestNG tng = new TestNG();
tng.setExcludedGroups("excludedGroup1, excludedGroup2");
tng.run();
}
Then you could run the class file from the terminal and simply do
$ java <classfilename> excludedgroup1 excludedgroup2
and write the main function as the below:
public static void main(String[] args) {
TestNG tng = new TestNG();
tng.setExcludedGroups(args[0] + ", " + args[1]);
tng.run();
}
TestNG has a command-line switch called -excludegroups that will take a comma separated list of the groups you want to exclude, if you run the testng.xml file from the command line: http://testng.org/doc/documentation-main.html#running-testng.
Run it through Maven's surefire plugin. Go to the "excluded groups" part of this page -- you can define them in the pom.xml this way.
Related
What is the recommended solution to run a test multiple times with different system properties via command line?
What I would like to do could look like this:
gradle clean test --tests -Dmyproperty=foo my.fancy.test.TestClass --tests -Dmyproperty=bar my.fancy.test.TestClass
I need this parameter for the setup code in the #BeforeAll method.
As you use junit you can use #ParameterizedTest which allows you to repeat the same junit test with different parameters.
You would need to move the code for the setup from the "BeforeAll" somewhere else.
static Stream<String> testArgs() { return Stream.of(""," ", null,"12345"); }
#ParameterizedTest
#MethodSource("testArgs")
public void testByArgs(String arg){
// Your test with asserts based on args here ...
}
You need to also wire those parameters up with tests' JVM through Gradle's test dsl:
// build.gradle
test {
systemProperty 'myproperty', System.getProperty('myproperty')
}
// in your tests use it like:
#BeforeAll
fun setUp() {
System.getProperty("myproperty")
}
Basicailly this answer.
I want to run a simple TestNG class using terminal not after adding it in suite.xml
I want to invoke the eclipse operation Right click -> Run As -> TestNG Test using terminal/CLI.
Is there is any way to Do it?
public class FirstTest {
#Test()
public void test {
System.out.println("Hello TesNG!");
}
How to compile and Run the above TestNG code using CLI?
There's no direct way to do this according to the docs - you need to specify an xml suite in order to use the testNg CLI like java org.testng.TestNG testng1.xml
However, you can create some main method in your project and invoke TestNg programmatically: add necessary Test classes into suite and call this main method from CLI like any other Java application:
public static void main(String ... args){
TestListenerAdapter tla = new TestListenerAdapter();
TestNG testng = new TestNG();
testng.setTestClasses(new Class[] { FirstTest.class });
testng.addListener(tla);
testng.run();
}
And then in command line:
javac some.package.your.MainClass.java
java some.package.your.MainClass
I have two test classes each containing a number of tests. I'd like to run both of these together without having to have the #BeforeClass setup method being ran both times. I am calling the classes like this:
public static void main(String[] args) {
TestListenerAdapter tla = new TestListenerAdapter();
TestNG testng = new TestNG();
testng.setTestClasses(new Class[] { TestClass1.class, TestClass2.class });
testng.addListener(tla);
testng.run();
}
The reason for this is because I have both of them calling in a pop up menu and only want to select the option one time. If this is unclear I will try to further explain.
I have a collection of individual tests across 5 classes. I want each class to be able to run separately, but I also want to make them run collectively should I desire. In the #BeforeClass I have each of them calling another class that will select what URL I want to use (I am testing with TestNG and using Selenium WebDriver).
When this code runs it will execute the #BeforeClass in each class I list, and I would like to, if possible, ignore the #BeforeClass in all the tests if I execute the tests using the code above.
I would recommend passing a transformer in to your TestNG test case that implements, IAnnotationTransformer2. That transformer can allow you to control the behavior of the non #Test Annotations at runtime.
IAnnotationTransformer2
You can use a #BeforeTest in a common class of your 2 test classes.
I understand you want to run the stuff inside #Before only once for your 2 test classes that will be executed at same time together.
If you are using maven + junit 4.x, there is an option for setup things before and after test suit start and complete.
Or you can simply create a #ClassRule at suite level, please see the doc
I need to run certain tests depending using JUnitCore and Categories but I can't find a way to make it work, can you please take a look and let me know if this is valid?
I have the following TestSuite called:
#RunWith(Categories.class)
#IncludeCategory(FeatureA.class) //this is the interface required as per categories documenation
#SuiteClasses( { AllTests.class } ) //imagine that AllTests contains all my tests
public class FeatureASuite {
} //if I'm not mistaken this configuration
// will go over all my tests and
// pick up only the ones with category FeatureA
And then I have a main class that will handle the execution as follows:
public static void main(String[] args) {
List<Class<?>> classes = new ArrayList<Class<?>>(); //classes collection
boolean featureA= true; //as this is an example featureA is always enabled
if(featureA) { //if feature A enabled then..
classes.add(FeatureASuite.class); //...add the feature A suite.
}
JUnitCore jUnitCore = new JUnitCore(); //create the facade
jUnitCore.runClasses(classes.toArray(new Class[classes.size()])); //run the classes specified
}
After executing the code the tests are not run. I have tried this with a different runner (instead of using Categories.class I have tried Suite.class) and tests are executed, however I need to specify categories per test method and Suite.class is not hitting that mark.
I have found why my approach was not working, the implementation above is actually correct, the issue (what I consider a junit bug) is in how Junit reacts to RunWith, if any of the classes under SuiteClasses contains RunWith annotation for any reason the execution will stop before even starting to run a first test.
My scenario is:
public class ExampleTest extends AbstractExampleTest {
#Test(dependsOnMethods={"someMethodFromAbstractExampleTest"}
public void firstTest() {
// Assert
}
// here I would like to call CommonTests
}
public class CommonTests {
#Test
public void sharedTest() {
// Assert
}
}
The reason something like CommonTests exists, is that it will contain a repeated test sequence. The way I currently communicate information from ExampleTest to CommonTests is done via statics which seems to work, but probably not the best.
This works fine if I call CommonTests programmatically according to the TestNG documentation. The issue I have with that is the results aren't logged within the runner of ExampleTest.
#Test
public void actionBasedTest(ITestContext context) {
TestListenerAdapter tla = new TestListenerAdapter();
TestNG testng = new TestNG();
testng.setTestClasses(new Class[] { ExampleAction.class });
testng.addListener(tla);
context.getSuite().addListener(tla);
testng.run();
}
The above is slightly better, but the reporting back is limited to something like "org.testng.TestRunner#####" and doesn't expose the test methods run.
So my question is: can I run tests from another class(es) (not via inheritance) and get the results logged to the same listener?
EDIT: I want to avoid testng.xml.
Answering your last question , you can run tests of any classes using a testng.xml which allows you to structure your tests any way you like. You can specify your listener in the suite tag and that would be the listener used for all your classes. Refer this for examples.