I am trying to find out how to run all my TestNG tests in one class first, then all in the second class second and so forth. I need to use parallel running to speed execution though. These are selenium tests so can be slow running.
Given the following TestNG suite file:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite1" verbose="1" parallel="classes" thread-count="2">
<test name="parallel-running-test">
<classes>
<class name="com.mycompany.myproject.mypackage.MyFirstClassTest"/>
<class name="com.mycompany.myproject.mypackage.MySecondClassTest"/>
</classes>
</test>
..and the following 2 classes:
Class one:
public class MyFirstClassTest {
#Test
public void myFirstClassTestOne(){
System.out.println("myFirstClassTestOne");
}
#Test (dependsOnMethods = {"myFirstClassTestOne"})
public void myFirstClassTestTwo(){
System.out.println("myFirstClassTestTwo");
}
#Test (dependsOnMethods = {"myFirstClassTestTwo"})
public void myFirstClassTestThree(){
System.out.println("myFirstClassTestThree");
}
#Test(dependsOnMethods = {"myFirstClassTestThree"})
public void myFirstClassTestFour(){
System.out.println("myFirstClassTestFour");
}
#Test(dependsOnMethods = {"myFirstClassTestFour"})
public void myFirstClassTestFive(){
System.out.println("myFirstClassTestFive");
}
}
Class two:
public class MySecondClassTest {
#Test
public void mySecondClassTestOne(){
System.out.println("mySecondClassTestOne");
}
#Test(dependsOnMethods = {"mySecondClassTestOne"})
public void mySecondClassTestTwo(){
System.out.println("mySecondClassTestTwo");
}
#Test(dependsOnMethods = {"mySecondClassTestTwo"})
public void mySecondClassTestThree(){
System.out.println("mySecondClassTestThree");
}
#Test(dependsOnMethods = {"mySecondClassTestThree"})
public void mySecondClassTestFour(){
System.out.println("mySecondClassTestFour");
}
#Test(dependsOnMethods = {"mySecondClassTestFour"})
public void mySecondClassTestFive(){
System.out.println("mySecondClassTestFive");
}
}
Then the output is as follows:
...How can I have the report as:
MyFirstClassTest
myfirstClassTestOne
myfirstClassTestTwo
myfirstClassTestThree
myfirstClassTestFour
myfirstClassTestFive
MySecondClassTest
mySecondClassTestOne
mySecondClassTestTwo
mySecondClassTestThree
mySecondClassTestFour
mySecondClassTestFive
NB - I need dependsOnMethods and have obvs removed all the browser stuff and actual selenium stuff
Your issue is just the way how IntelliJ is displaying the result of tests.
By default, it displays tests by the order they finish.
You can change it and sort them by alphabetical order if you prefer:
Sadly, IntelliJ is not grouping tests by class name (or I didn't find the way to do it).
Maybe you should ask for the feature on https://youtrack.jetbrains.com
Steerpike, you can try running your tests in parallel (instead of classes) so slight changes to your XML should give you what you are after:
!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="Suite1" verbose="1" parallel="tests" thread-count="2">
<test name="parallel-running-test1">
<classes>
<class name="com.mycompany.myproject.mypackage.MyFirstClassTest"/>
</classes>
</test>
<test name="parallel-running-test2">
<classes>
<class name="com.mycompany.myproject.mypackage.MySecondClassTest"/>
</classes>
</test>
</suite>
Best of luck!
Related
BaseTest Class
public class BaseTest extends Base {
LoginPage login;
Logger logger = Logger.getLogger(Base.class);
#BeforeMethod()
public void setUp() throws IOException, IOException {
logger.info("starting initialisation method from base class");
initialisation();
logger.info("completed initialisation method from base class");
login = new LoginPage();
logger.info("initialising login page and profile page object");
}
#AfterMethod
public void tearDown() {
logger.info("starting tear down method");
Base.getDriver().close();
logger.info("ending tear down method");
}
#AfterSuite
public void sendEmailWithExtentReport() throws IOException {
logger.info("starting sendEmailWithExtentReport");
Utilities.sendJavaMailAfterExecution();
logger.info("ending sendEmailWithExtentReport");
}
LoginTest class
public class LoginTest extends BaseTest {
#Test(priority = 0,description = "Test case to verify login button is present or not")
public void loginPageLoadingTest() throws IOException, InterruptedException {
logger.info("starting loginPageLoadingTest");
Thread.sleep(2000);
Assert.assertEquals(login.verifyLoginButton(), true);
logger.info("ending loginPageLoadingTest");
}
#Test(priority = 1, description = "Test case to verify login page title")
public void loginPageTitleTest() throws IOException, InterruptedException {
logger.info("starting loginPageTitleTest");
Thread.sleep(2000);
Assert.assertEquals(login.getLoginPageTitle(), "Console");
logger.info("ending loginPageTitleTest");
}
}
testng-console.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite">
<listeners>
<listener class-name="com.analyzer.MyTransformer" />
<listener class-name="com.utilities.TestListener"></listener>
</listeners>
<test thread-count="5" name="Test">
<classes>
<class name="com.ui.tests.BaseTest" />
<class name="com.ui.tests.LoginTest" />
<class name="com.ui.tests.FilterTest" /> -->
</classes>
</test> <!-- Test -->
</suite> <!-- Suite -->
I need to skip the method in #AfterSuite if i am only executing the single test case from multiple test cases in LoginTest class without using testng.xml file, so that I can verify each test case separately. Right now when individual test is executed the method in #AfterSuite is also getting executed. I want to execute the method in #AfterSuite only when test cases are executed using testng.xml file. How can i add a condition in #AfterSuite to achieve this. Also i am using this command '''mvn clean test -Dbrowsername=chrome''' from command prompt. My testng file name is testng-console.xml .The method in #AfterSuite should only get executed when using the tesng-console.xml. Please help.
You can test your suite name for equality to Default Suite. Say you have testng.xml like:
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<suite name="Suite1" verbose="1" >
<test name="MyTest" >
<classes>
<class name="click.webelement.Suites" />
</classes>
</test>
</suite>
where you define suite name explicitly. Then you can have the logic like this:
package click.webelement;
import org.testng.ITestContext;
import org.testng.annotations.AfterSuite;
import org.testng.annotations.Test;
public class Suites {
#Test
public void doTest(){
System.out.println("Doing test..");
}
#AfterSuite
public void doingAfterSuite(ITestContext testContext){
if(!testContext.getSuite().getName().equalsIgnoreCase("Default Suite")){
System.out.println("Doing after suite");
}
}
}
Since when you run a single test, Default Suite is created you can just test if default suite is set in test context.
UPDATE: Eclipse plugin sets default suite name as Default suite so that I changed equals to EqualsIgnoreCase to cover both Idea and Eclipse
I have two separate packages in my project, one for integration tests and one for unit tests, my testng.xml looks as follows:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<suite name="All test cases" verbose="1" parallel="classes">
<test name="Integration Tests">
<classes>
<class name="com.sample.integration.ClassC"/>
<class name="com.sample.integration.ClassD"/>
</classes>
</test>
<test name="Unit tests">
<classes>
<class name="com.sample.unit.ClassA"/>
<class name="com.sample.unit.ClassB"/>
</classes>
</test>
</suite>
Class C:
public class ClassC {
#BeforeTest
public void beforeIntegrationTests() {
System.out.println("Before Integration tests");
}
#Test
public void classCMethod() {
System.out.println("Executing class C method");
}
}
Class D:
public class ClassD {
#Test
public void classDMethod() {
System.out.println("Executing class D method");
}
}
Class A:
public class ClassA {
#BeforeTest
public void beforeUnitTests() {
System.out.println("Before unit tests");
}
#Test
public void classAMethod() {
System.out.println("Executing class A method");
}
}
Class B:
public class ClassB {
#Test
public void classBMethod() {
System.out.println("Executing class B method");
}
}
If I run the entire test suite it works as expected as follows:
Before Integration tests
Executing class C method
Executing class D method
Before unit tests
Executing class A method
Executing class B method
However, if I try to either run/debug just classAMethod() from ClassA, it runs beforeUnitTests() [expected] and classAMethod() [expected], however it also runs beforeIntegrationTests() which is not expected. As per the official documentation: #BeforeTest: The annotated method will be run before any test method belonging to the classes inside the <test> tag is run.
How do I configure TestNG and/or IntelliJ to run this correctly?
Side Note: Although I can see that the beforeIntegrationTests() is getting run either by adding a breakpoint in the debug mode or by adding a Thread.sleep in the run mode, the output from this method does not get printed in final console output.
Firstly, is the expectation valid, as in I expect only beforeUnitTests() and classAMethod() to run if I run just the classAMethod().
No, all methods with #BeforeTest annotation will run before execution of method with #Test annotation.
Ideal way to handle this scenario is with groups.
Class A:
public class ClassA {
#BeforeTest(groups="unitTest")
public void beforeUnitTests() {
System.out.println("Before unit tests");
}
#Test(groups="unitTest")
public void classAMethod() {
System.out.println("Executing class A method");
}
}
Class B:
public class ClassB {
#Test(groups="unitTest")
public void classBMethod() {
System.out.println("Executing class B method");
}
}
Class C:
public class ClassC {
#BeforeTest(groups="integrationTest")
public void beforeIntegrationTests() {
System.out.println("Before Integration tests");
}
#Test(groups="integrationTest")
public void classCMethod() {
System.out.println("Executing class C method");
}
}
Class D:
public class ClassD {
#Test(groups="integrationTest")
public void classDMethod() {
System.out.println("Executing class D method");
}
}
testNG XML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd" >
<suite name="All test cases" verbose="1" parallel="classes">
<groups>
<run>
<include name="unitTest"></include>
</run>
</groups>
<test name="Test Suite">
<classes>
<class name="com.sample.integration.ClassC"/>
<class name="com.sample.integration.ClassD"/>
<class name="com.sample.unit.ClassA"/>
<class name="com.sample.unit.ClassB"/>
</classes>
</test>
</suite>
You can make further configuration to this testNg XML as per your needs.
I have created Project(Page Object Model) in Eclipse like this
Project name
Package 1
src
bin
package 2
src
bin
In package 1 contains, element description and method
In package 2 contains,
BaseScript.java ---------
preconditon
webdriver driver=new FirefoxDriver();
driver.get("url");
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
driver.manage().window().maximize();
LoginPage l=new LoginPage(driver);
l.setusername("");
l.setpassword("");
l.LoginBut();
Postconditons
driver.quit();
I have T1.java,T2.java and converted into.xml(testng.xml) and Run using Testng that file(testng.xml)
I want to execute all testcases at a time with one browser but i've got when i execute testcases it's calls BaseScript.java
Selenium is a tool which controls the browser/website like a user. It simulates a user clicking through the pages. Knowing the functionality of your web application, you can setup your tests. Now run set of test cases together i.e. Test Suite. TestNG gives this capability to manage test execution.
I suggest you to read this simple tutorial to setup TestNG suite of tests.
I want to execute all testcases at a time
Selenium Grid is a part of the Selenium Suite to run tests in parallel. You setup the driver in base classs
public class TestBase {
protected ThreadLocal<RemoteWebDriver> threadDriver = null;
#BeforeMethod
public void setUp() throws MalformedURLException {
threadDriver = new ThreadLocal<RemoteWebDriver>();
DesiredCapabilities dc = new DesiredCapabilities();
FirefoxProfile fp = new FirefoxProfile();
dc.setCapability(FirefoxDriver.PROFILE, fp);
dc.setBrowserName(DesiredCapabilities.firefox().getBrowserName());
threadDriver.set(new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), dc));
}
public WebDriver getDriver() {
return threadDriver.get();
}
#AfterMethod
public void closeBrowser() {
getDriver().quit();
}
}
An example of sample test would be:
public class Test01 extends TestBase {
#Test
public void testLink()throws Exception {
getDriver().get("http://facebook.com");
WebElement textBox = getDriver().findElement(By.xpath("//input[#value='Name']"));
// test goes here
}
}
You can add more tests in similar way as above
public class Test02 extends TestBase {
#Test
public void testLink()throws Exception {
// test goes here
}
}
TestNG Configurations:
testng.xml
<suite name="My Test Suite">
<suite-files>
<suite-file path="./testFiles.xml" />
</suite-files>
testFiles.xml
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Parallel test runs" parallel="tests" thread-count="2">
<test name="T_01">
<classes>
<class name="com.package.name.Test01" ></class>
</classes>
</test>
<test name="T_02">
<classes>
<class name="com.package.name.Test02" ></class>
</classes>
</test>
<!-- more tests -->
</suite>
there are some flows that i want to test through automation. i am using selenium , maven, java and testNG. i have 2 different class. Let say class A and Class B.
public class A (){
#Test(groups="flow1",priority=0)
public void method a1()
{
}
#Test(groups="flow1".priority=2)
public void method a2()
{
}
#Test
public void method a3()
{
}
and 2nd class is class B
public class b (){
#Test(groups="flow1", priority=1)
public void method b1()
{
}
#Test
public void method b2()
{
}
#Test
public void method b3()
{
}
now i want to achieve flow like below
method a1()
method b1()
method a2()
i had try in this way through testng.xml
<test name="test1">
<groups>
<run>
<include name="flow1" />
</run>
</groups>
<classes>
<class name="a" />
<class name="b" />
</classes>
</test>
but i am not getting that output. it will run only one test cases and then it is skipping others.
i had try also some different way but i am not getting my goal.
can anybody help me
thanks
in your testng.xml just add group-by-instances="true"
<suite thread-count="2" verbose="10" name="testSuite" parallel="tests">
<test verbose="2" name="MytestCase" group-by-instances="true">
<classes>
<class name="com.A.classA" />
<class name="com.A.classB" />
</classes>
</test>
</suite>
I want to run same test method as part of multiple . TestNG runs my test method only once irrespective. Paramters are different in both cases. Any pointers on how I can achieve this is greatly appreciated
public class Test1 extends TestBase{
#Test
public void test1(){
System.out.println("This si test1");
}
}
public class TestBase {
#Parameters({ "param1" })
#BeforeMethod
public void setup(#Optional("VCHS") String param1) {
System.out.println("the parameter is "+param1);
}
#Parameters({ "param1" })
#BeforeTest(groups="VC2-UI",alwaysRun=true)
protected void baseSetUpVC2EndPoint(#Optional("VC2") String param1){
System.out.println("This is base"+param1);
}
#Parameters({ "param1" })
#BeforeTest(groups="VC1-UI")
protected void baseSetUpVC1EndPoint(#Optional("VC1") String param1){
System.out.println("This is base and "+param1);
}
}
<suite name="Testing" verbose="1" configfailurepolicy="continue">
<test name="VC2-UI">
<parameter name="param1" value="VC2"/>
<classes>
<class name="Test1"></class>
</classes>
</test>
<test name="VC1-UI">
<parameter name="param1" value="VC1"/>
<classes>
<class name="Test1"></class>
</classes>
</test>
</suite>
You can use invocationCount annotation.