Why does TestNG initialize all test classes at startup - java

I have a very simple test suite similar to the following:
public abstract class AbstractTestClass {
protected AbstractTestClass() {
System.out.println(getClass().getSimpleName());
}
}
#Test(groups = { "test1_test_group" })
public final class Test1 extends AbstractTestClass { ... }
#Test(groups = { "test2_test_group" })
public final class Test2 extends AbstractTestClass { ... }
<!-- testng.xml -->
<suite name="SimpleTestSuite">
<test name="DummyTest">
<groups>
<run>
<include name="test1_test_group" />
</run>
</groups>
<packages>
<package name="my.test.package.*" />
</packages>
</test>
</suite>
I'm not sure if it is by design but why does TestNG creates an instance of all classes in the given package when the only test group I want to execute is test1_test_group i.e. the output of the above test run is as follows:
Test1
Test2
I've tried to remove the complete <packages> tag replacing it with <classes> tags listing individual classes but it's the same behavior. The only defect reported which comes close to this scenario (although kind of rejected) is https://github.com/cbeust/testng/issues/1075

Change your testng xml file. Remove the package, instead use classes as follows:
<suite name="SimpleTestSuite">
<test name="DummyTest">
<groups>
<run>
<include name="test1_test_group" />
</run>
</groups>
<classes>
<class name="your class with fully qualified name where tests are written" />
</classes>
</test>
</suite>

Related

Test suites in Junit 5

I have several test classes sharing extending the BaseTest.class as following
class BaseTest{
#BeforeAll
static setup(){
// code to setup some configs for tests
}
}
AND
class TestClass1 extends BaseTest{
#Test
void test1(){
// test code
}
}
class TestClass2 extends BaseTest{
#Test
void test2(){
// test code
}
}
My need is to run these two tests in Parallel, but on different parameters passed to setup() method in BaseTest class, I found it easy in TestNg using testng.xml, but i need to use Junit5 to achieve this, Example from testng is
<suite name="Test-class Suite" parallel="classes" thread-count="2">
<test name="Test-class test 1">
<parameter name="paramName" value="paramValue1" />
<classes>
<class name="TestClass1" />
<class name="TestClass2" />
</classes>
</test>
<test name="Test-class test 2">
<parameter name="paramName" value="paramValue2" />
<classes>
<class name="TestClass1" />
<class name="TestClass2" />
</classes>
</test>
</suite>
I want your help to hear some suggestions/ideas how can i achieve this goal using Junit5, I appreciate all you inputs !
Thanks in advance

Parallel execution of tests in testNG Selenium

I am not able to invoke the browsers in parallel, which are currently invoking one after another. Need a way to invoke the browsers in parallel tests.
NOTE: In my configuration xml file I have kept the thread count as 2.
Below is my configuration file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "testng.org/testng-1.0.dtd"; >
<suite name="Parallel" parallel="tests" thread-count="4" >
<test verbose="3" name="<name>">
<parameter name="platform" value ="win8"/>
<parameter name="browsername" value ="internet explorer"/>
<classes>
<class name="com.parallel.execution.ParallelExecution">
<methods>
<include name="testmethod1"/>
</methods>
</class>
</classes>
</test>
</suite>
We have to define two attributes 'parallel' and 'thread-count' in simple testng.xml file. See below:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Parallel Execution suite" parallel="methods" thread-count="2">
<test name="Regression 2">
<classes>
<class name="com.parallel.TestParallelExecution"/>
</classes>
</test>
</suite>
In above, as we want the test methods to be executed parallel, we have set the parallel attribute as 'methods' and thread-count attribute will control the max number of threads to be created.
Re-installing TestNG solved the above problem.
You have to explicitly write code to invoke the browser as part of a #Before configuration to invoke the browser every time a #Test is run . I will specify one of the many approaches so that you get an idea.
<suite name="Parallel" parallel="tests" thread-count="4" >
<test verbose="3" name="test1">
<classes>
<class name="com.parallel.execution.ParallelExecution1"/>
</classes>
</test>
<test verbose="3" name="test2">
<classes>
<class name="com.parallel.execution.ParallelExecution2"/>
</classes>
</test>
</suite>
Consider a suite file with 2 tests set to run in parallel. What we expect is #Test methods in ParallelExecution1 runs in first browser and #Test methods in ParallelExecution2 runs in second browser. So you need a mechanism by which you can invoke browser sessions and run your test methods. Enter BaseTest class.
public abstract class BaseTest {
protected WebDriver driver;
#BeforeTest
#Parameters({"browser"})
public void init(String browser) {
// Initialize your browser here. Code below is dummy
driver = new FF();
}
#AfterTest
public void end() {
driver.close();
driver.quit();
}
}
Now inherit this 'BaseTest' in both your test classes.
public class ParallelExecution1 extends BaseTest {
#Test
public void test1() {
}
}
public class ParallelExecution2 extends BaseTest {
#Test
public void test2() {
}
}
Now both the tests have #BeforeTest and #AfterTest methods which will invoke the browsers.

Referring test groups in testng.xml

Let's say I've annotated my test class with a test group in TestNG:
#Test(group='smoke-tests')
public class CheckEnvironmentTest {
...
}
Is there a way to refer to this group in testng.xml? Something like this (if it was implemented):
<suite name="Suite1" verbose="1" >
<test name="Sequential" parallel="false" >
<test-group ref="smoke-tests" />
</test>
<test name="ParallelGroup" parallel="classes" >
<test-group ref="regular-tests" />
</test>
</suite>
You might want to do something like this
<test name="sample">
<groups>
<run>
<include name="smoke-tests"/>
</run>
</groups>
<classes>
<class name="CheckEnvironmentTest"/>
</classes>
</test>

Selenium grid with webdriver and testNG

I am experiencing the following problem. I have set up a grid with 2 nodes, in order to run tests in parallel.My suite.xml file has two groups, one for each node:
<suite name="testSuites" configfailurepolicy="continue" thread-count="2" parallel="tests">
test name="testSuite1" preserve-order="true">
<classes>
<class name="testA1" />
<class name="testB1" />
<class name="testC1" />
</classes>
</test>
<test name="testSuite2" preserve-order="true">
<classes>
<class name="testA2" />
<class name="testB2" />
<class name="testC2" />
</classes>
</test>
Each class, for example testA1 has the following testNG configuration:
#BeforeClass(alwaysRun = true)
public void createInitialData() {
}
#Test(alwaysRun = true, description = "bla bla")
public void testStep_1() throws Exception{
}
#Test(alwaysRun = true, description = "bla bla ", dependsOnMethods ="testStep_1" )
public void testStep_2() {
}
Upon running I noticed that during the execution, the tests are executing in test step wise order, meaning:
testA1-testStep_1, testB1-testStep_1, testC1-testStep_1, testA1-testStep_2, testB1-testStep_2, testC1-testStep_2
whereas it should have been:
testA1-testStep_1, testA1-testStep_2, and then testB1-testStep_1, testB1-testStep_2, testC1-testStep_1, testC1-testStep_2
Any suggestions?
Try to set group-by-instances in your xml
<suite group-by-instances="true">
or
<test group-by-instances="true">
<test name="testSuite2" parallel="false">
Seem also be doing what you need.

How to use testNG #Parameters in #BeforeSuite to read resource file

I am using testNG with Selenium webdriver2.0.
In my testNG.xml I have
<suite data-provider-thread-count="2" name="selenium FrontEnd Test" parallel="false" skipfailedinvocationCounts="false" thread-count="2">
<parameter name="config_file" value="src/test/resources/config.properties/"/>
<test annotations="JDK" junit="false" name="CarInsurance Sanity Test" skipfailedinvocationCounts="false" verbose="2">
<parameter name="config-file" value="src/test/resources/config.properties/"/>
<groups>
<run>
<include name="abstract"/>
<include name="Sanity"/>
</run>
</groups>
<classes>
</classes>
</test>
</suite>
In java file
#BeforeSuite(groups = { "abstract" } )
#Parameters(value = { "config-file" })
public void initFramework(String configfile) throws Exception
{
Reporter.log("Invoked init Method \n",true);
Properties p = new Properties();
FileInputStream conf = new FileInputStream(configfile);
p.load(conf);
siteurl = p.getProperty("BASEURL");
browser = p.getProperty("BROWSER");
browserloc = p.getProperty("BROWSERLOC");
}
Getting error as
AILED CONFIGURATION: #BeforeSuite initFramework
org.testng.TestNGException:
Parameter 'config-file' is required by #Configuration on method initFramework
but has not been marked #Optional or defined in
How to use #Parameters for resource file?
Looks like your config-file parameter is not defined at the <suite> level. There are several ways to solve this:
1. Make sure the <parameter> element is defined within <suite> tag but outside of any <test>:
<suite name="Suite1" >
<parameter name="config-file" value="src/test/resources/config.properties/" />
<test name="Test1" >
<!-- not here -->
</test>
</suite>
2. If you want to have the default value for the parameter in the Java code despite the fact it is specified in testng.xml or not, you can add #Optional annotation to the method parameter:
#BeforeSuite
#Parameters( {"config-file"} )
public void initFramework(#Optional("src/test/resources/config.properties/") String configfile) {
//method implementation here
}
EDIT (based on posted testng.xml):
Option 1:
<suite>
<parameter name="config-file" value="src/test/resources/config.properties/"/>
<test >
<groups>
<run>
<include name="abstract"/>
<include name="Sanity"/>
</run>
</groups>
<classes>
<!--put classes here -->
</classes>
</test>
</suite>
Option 2:
#BeforeTest
#Parameters( {"config-file"} )
public void initFramework(#Optional("src/test/resources/config.properties/") String configfile) {
//method implementation here
}
In any case, I would recommend not having two parameters with almost identical names, identical values, and different scope.
You want to use #Parameter in #BeforeSuite. Suite level parameters are parsed once the suite begins execution and I believe TestNG invokes #BeforeSuite even before the suite is processed:
Here is a workaround: add ITestContext in method parameters to inject
#BeforeSuite(groups = { "abstract" } )
#Parameters({ "configFile" })
public void initFramework(ITestContext context, String configFile) throws Exception {

Categories