Test suites in Junit 5 - java

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

Related

Selenium: TestNG: Tests are not running in parallel

I have a simple maven project with three class files.
When I run my testng.xml file, tests are running in series.
I tried keeping parallel="classes", parallel="methods", parallel="tests" but no luck.
Also tried by changing testng version from 6.9.0 to 7.0.0 but it didn't work.
Expectation:
Tests should run in parallel
What is happening:
Tests run in sequence
Below is my project and all files:
Test Class: 1
public class TestOne {
private static WebDriver driver;
private static String baseURL;
#Test
public void launch() throws IOException {
baseURL = "http://www.gmail.com";
System.setProperty("webdriver.chrome.driver", "path");
WebDriver driver = new ChromeDriver();
driver.get(baseURL);
driver.quit();
}
}
Test Class: 2
public class TestTwo {
private static WebDriver driver;
private static String baseURL;
#Test
public void launch() throws IOException {
baseURL = "http://www.gmail.com";
System.setProperty("webdriver.chrome.driver", "path");
WebDriver driver = new ChromeDriver();
driver.get(baseURL);
driver.quit();
}
}
Test Class: 3
public class TestThree {
private static WebDriver driver;
private static String baseURL;
#Test
public void launch() throws IOException {
baseURL = "http://www.gmail.com";
System.setProperty("webdriver.chrome.driver", "path");
WebDriver driver = new ChromeDriver();
driver.get(baseURL);
driver.quit();
}
}
TestNG xml:
!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd"
suite name="Test" parallel="tests" thread-count="3" data-provider-thread-count="5"
<test name="Launch">
<classes>
<class name="test.demo.grid.TestOne" />
<class name="test.demo.grid.TestTwo" />
<class name="test.demo.grid.TestThree" />
</classes>
</test>
Version:
selenium-java = 3.4.0
testng = 6.14.3
=================================
Please let me know how I can fix it.
Thank you!
Try first a simple example logging the thread id on each test method, without calling ChromeDriver yet
long id = Thread.currentThread().getId();
System.out.println("Sample test-method " + testName
+ ". Thread id is: " + id);
https://howtodoinjava.com/testng/testng-executing-parallel-tests/
If it logged the ids in parallel maybe is something related to ChromeDriver
<test> tag is only one in your testng.xml and that is the reason, parallel execution is not working.
In your case, you need to use parallel="classes" and all the classes would execute parallely.
Edit:
You can use the testng.xml as:
<test name="Launch">
<classes>
<class name="test.demo.grid.TestOne" />
</classes>
</test>
<test name="Second test">
<classes>
<class name="test.demo.grid.TestTwo" />
</classes>
</test>
<test name="Third test">
<classes>
<class name="test.demo.grid.TestThree" />
</classes>
</test>
And now use parallel="tests" in the testng.xml
Try with parallel="classes" and without the data-provider-thread-count="5" because you are not using data provider here.
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Test" parallel="classes" thread-count="3">
<test name="Launch">
<classes>
<class name="test.demo.grid.TestOne" />
<class name="test.demo.grid.TestTwo" />
<class name="test.demo.grid.TestThree" />
</classes>
</test>
</suite>
You can try:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" configfailurepolicy="continue">
<parameter name="parallelSetup" value="tests" />
<parameter name="threadsNumber" value="3" />
<test name="Launch">
<classes>
<class name="test.demo.grid.TestOne" />
<class name="test.demo.grid.TestTwo" />
<class name="test.demo.grid.TestThree" />
</classes>
</test>
</suite>
add #BeforeClass annotation in every class and initialize WebDriver in that annotaion
and close driver in #AfterClass annotion for every class

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.

Why does TestNG initialize all test classes at startup

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>

Selenium: Run same test on different browsers

I want to run same test on different browsers (Firefox, Chrome and Safari). To do this I am using parametrization in tests. Where in if browser is chrome run chrome and so on.
And in testng.xml I have specified to run tests in parallel and repeated same test in under several <test> tags.
What if I have so many tests to run. I will be copy pasting same test in <test> tags. Which doesn't see optimal solution.
How can I fix this?
Here is what I tried:
public class SameTestDifferentBrowsers {
WebDriver driver;
#BeforeMethod
#Parameters("browser")
public void openBroswer(String browser) {
if (browser.equalsIgnoreCase("Chrome")) {
System.out.println(System.getProperty("user.dir"));
System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir")+"//lib//browsers//chromedriverMac");
driver = new ChromeDriver();
} else if (browser.equalsIgnoreCase("Firefox")) {
driver = new FirefoxDriver();
} else if (browser.equalsIgnoreCase("safari")) {
System.setProperty("webdriver.safari.driver", System.getProperty("user.dir")+"//lib//browsers//SafariDriver.safariextz");
driver = new SafariDriver();
}
}
#AfterMethod
public void closeBrowser() {
driver.quit();
}
#Test
public void login_TestCase() {
driver.get("https://www.google.com");
}
}
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Parallel test suite" parallel="tests">
<test name="Firefox Test">
<parameter name="browser" value="browser"/>
<classes>
<class name="ParallelBrowser.SameTestDifferentBrowsers"/>
</classes>
</test>
<test name="Chrome Test">
<parameter name="browser" value="browser"/>
<classes>
<class name="ParallelBrowser.SameTestDifferentBrowsers"/>
</classes>
</test>
<test name="Safari Test">
<parameter name="browser" value="browser"/>
<classes>
<class name="ParallelBrowser.SameTestDifferentBrowsers"/>
</classes>
</test>
</suite>
If you are sure that you would want to run all the tests for all the three browsers then you may change your design a little.
Create multiple test classes for different test cases. In your xml test tags pass different test class names as parameters.
Write three #test methods in your parametrized test class each for each browser that accepts the class name as a parameter. Now using Reflections you can invoke the right test method in every #test method.
Two things require fixing here and the problem sill be solved.
First: Update the TestNG.xml file to include the browser names
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Parallel test suite" parallel="tests">
<test name="Firefox Test">
<parameter name="browser" value="Firefox" />
<classes>
<class name="ParallelBrowser.SameTestDifferentBrowsers" />
</classes>
</test>
<test name="Chrome Test">
<parameter name="browser" value="Chrome" />
<classes>
<class name="ParallelBrowser.SameTestDifferentBrowsers" />
</classes>
</test>
<test name="Safari Test">
<parameter name="browser" value="safari" />
<classes>
<class name="ParallelBrowser.SameTestDifferentBrowsers" />
</classes>
</test>
Second: Safari browser extension should be installed and enabled in the browser and shouldn't be kept in the path.
So just comment following line from Java Code File
//System.setProperty("webdriver.safari.driver",
//System.getProperty("user.dir") + "/lib/browsers/SafariDriver.safariextz");

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.

Categories