TestNG: priority of #BeforeClass and #BeforeTest - selenium

I have been using TestNG and having problems with two annotations, #BeforeTest and #BeforeClass. I would like to know if both are applied which will run first ?

Answer: Method annotated with #BeforeTest will be invoked before than the method annotated with #BeforeClass.
TestNG annotations execution order in reference to #Test and description:
#BeforeSuite: The annotated method will be run before all tests in
this suite have run.
#BeforeTest: The annotated method will be run before any test method belonging to the classes inside the
tag is run.
#BeforeGroups: The list of groups that this
configuration method will run before. This method is guaranteed to
run shortly
before the first test method that belongs to any of these groups is
invoked.
#BeforeClass: The annotated method will be run before the first test method in the current class is invoked.
#BeforeMethod: The annotated method will be run before each test method.
#Test: The test method or class
#AfterMethod: The annotated method will be run after each test method.
#AfterClass: The annotated method will be run after all the test methods in the current class have been run.
#AfterGroups: The list of groups that this configuration method will run after. This method is guaranteed to run shortly
after the last test method that belongs to any of these groups is
invoked.
#AfterTest: The annotated method will be run after all the test methods belonging to the classes inside the tag have
run.
#AfterSuite: The annotated method will be run after all tests in this suite have run.
There are various other annotations provided by TestNG and different
types of attributes/parameters can be passed to these annotations. For
more information on TestNG annotations follow this link

Annotations execution order:
BeforeSuite
BeforeTest
BeforeClass
BeforeMethod
Test
AfterGroups
AfterClass
AfterTest
You can check with the pseudo code:
public class TestAnnotationsPriorityOrder {
public int i=0;
#BeforeSuite
public void beforeSuite(){
i++;
System.out.println(i+"::BeforeSuite");
}
#AfterSuite
public void afterSuite(){
i++;
System.out.println(i+"::AfterSuite");
}
#BeforeTest
public void beforeTest(){
i++;
System.out.println(i+"::BeforeTest");
}
#AfterTest
public void afterTest(){
i++;
System.out.println(i+"::AfterTest");
}
#BeforeGroups
public void beforeGroups(){
i++;
System.out.println(i+"::BeforeGroups");
}
#AfterGroups
public void afterGroups(){
i++;
System.out.println(i+"::AfterGroups");
}
#BeforeClass
public void beforeClass(){
i++;
System.out.println(i+"::BeforeClass");
}
#AfterClass
public void afterClass(){
i++;
System.out.println(i+"::AfterClass");
}
#BeforeMethod
public void beforeMethod(){
i++;
System.out.println(i+"::BeforeMethod");
}
#AfterMethod
public void afterMethod(){
i++;
System.out.println(i+"::AfterGroups");
}
#Test
public void TestMethod(){
i++;
System.out.println(i+"::Test");
}
}

Before test first and then before class.
#BeforeTest: The annotated method will be run before any test method belonging to the classes inside the <test> tag is run.
#BeforeClass: The annotated method will be run before the first test method in the current class is invoked.
http://testng.org/doc/documentation-main.html#annotations

Related

How to log unique statements for each tests in the ExtentReport with the implementation of ITestListener?

I am currently using the ExtentReport framework to generate a comprehensive test report after TestNG completes its suite of test class using Selenium.
To make the process easier and to reduce code, I am using a listener class to automate the Test Success and Test Failure scenerios such that in case of every success/failure, there will some actions done to the report automatically. The listener implementation goes like this:
public class Listeners extends Base implements ITestListener{
ExtentTest test;
ExtentReports extent=ExtentReporterNG.getReportObject();
**ThreadLocal**<ExtentTest> extentTest =new **ThreadLocal**<ExtentTest>();
public void onTestStart(ITestResult result) {
// TODO Auto-generated method stub
test= extent.createTest(result.getMethod().getMethodName());
extentTest.set(test);
}
public void onTestSuccess(ITestResult result) {
takeScreenShotandAttachtoReport();
extentTest().get().log("Success");
}
public void onTestFailure(ITestResult result) {
takeScreenShotandAttachtoReport();
extentTest().get().log("Failure");
}
public void onFinish(ITestContext context) {
// TODO Auto-generated method stub
extent.flush();
}
As above, with every test case, an ExtentTest ThreadLocal would be instantiated along the interface methods, which would execute with respect to their individual listeners based on the test results. This reduces the extra code that are needed for the same implementation if ExtentReport was to be instantiated on every test class. However, this implementation has its own hurdle: It would not allow variations (logging, individual test result customization, etc). Say I'd want some ExtentReport logging to be done for each unique test case, I have no ways to invoke the listener and do any type of logging for that particular test.
Is there anyway that this can be solved?

What is the difference between #BeforeTest and #BeforeSuit annotation?

What is the difference between #BeforeTest and #BeforeSuit annotation? I have 2 methods with #Test annotation and one #BeforeTest method. When I ran it, a #BeoforeTest method was executed only once. Shouldn't it run before every #Test method?
You may refer this example,
https://stackoverflow.com/a/50814147/9405154
If you want to call annotation before every Test method, You need to use #BeforeMethod annotation.
Both #BeforeTest and #BeforeSuite will call only once on execution, They just have different approach on .XML suite execution.
#BeforeTest will run per class
You probably want per test method,then use #BeforeMethod:
The annotated method will be run before each test method.
#BeforeTest: The annotated method will be run before any test method belonging to the classes inside the tag is run
#BeforeTest
this annotation will run before every test method for example
#BeforeTest
public void Setup()
{
System.out.println("before test");
}
#Test
public void test1()
{
System.out.println("Test1");
}
#Test
public void test2()
{
System.out.println("Test2");
}
Then output is as
before test
Test1
before test
Test2
where as #BeforeSuite this annotation will run #beforeclass
#BeforeTest -
Any code written in the method with this annotation will run once for all methods with annotation #Test inside a class.
This is best suited for condition which is a prerequisite for all tests e.g. test 1 is view user profile, test 2 is add item to cart, test 3 is manage address, these tests are dependent on a condition that user should be logged in, so we can write login functionality in a method with #BeforeTest annotation.
It is present in same class in which #Test method is written.
This is mainly applied at method level.
#BeforeSuite -
Any code written in the method with this annotation will run once in complete suite life cycle i.e. for complete testng.xml.
This is best suited for initializing config files,creating database connections etc.
This annotation is mainly used in Base class of the class in which #Test method is present
#Edit - Changed the #BeforeTest annotation details

How did TestNg annotation mentioned in one class get executed from another from another class?

While learning Testng on Udemy, I come across a code which I am unable to understand. Instructor has created class named "testcore" where he defined #BeforeMethod/#aftermethod.Later he created another class named "LoginTest" where he wrote actual test with #test. He extended testcore class in loginTest to get variable initiated in testcore class. When he ran loginTest then #BeforeMethod/#aftermethod also ran with this. How did these two method ran along with #test when these methods are in different class.
here are both codes:
public class testcore {
public static Properties config = new Properties();
public static Properties obj = new Properties();
public static Xls_Reader xls = null;
public static WebDriver driver;//=null;
#BeforeMethod
public void init() throws Exception{
if(driver==null) {
// Loading Config Properties File
File Config_f = new File(System.getProperty("user.dir")+"\\src\\dd_Properties\\config.properties");
FileInputStream fs = new FileInputStream(Config_f);
config.load(fs);
// Loading Object Properties File
File Obj_f = new File(System.getProperty("user.dir")+"\\src\\dd_Properties\\Object.properties");
fs = new FileInputStream(Obj_f);
obj.load(fs);
//Loading xlsx file
xls = new Xls_Reader(System.getProperty("user.dir")+"\\src\\dd_Properties\\Data.xlsx");
System.out.println(config.getProperty("browerName"));
if(config.getProperty("browerName").equalsIgnoreCase("Firefox")) {
driver = new FirefoxDriver();
}
else if(config.getProperty("browerName").equalsIgnoreCase("Chrome")) {
driver = new ChromeDriver();
}
else {
throw new Exception("Wrong/No Browswer sepcified");
}
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
}
#AfterMethod
public void quitdriver() throws EmailException {
driver.quit();
//monitoringMail.Sendmail();
}
Here are LoginTest class:
public class LoginTest extends testcore {
#Test
public void doLogin() {
driver.findElement(By.xpath(obj.getProperty("LoginBtn"))).click();
driver.findElement(By.xpath(obj.getProperty("username"))).sendKeys();
driver.findElement(By.xpath(obj.getProperty("password"))).sendKeys();
}
1) How did these two method ran along with #test.
First of all LoginTest extends the testcore .
Due to this we can inherit the method of testcore in our LoginTest class.
2) When he ran loginTest then #BeforeMethod/#aftermethod also ran with this.
Please refer below details
Configuration information for a TestNG class:
#BeforeSuite: The annotated method will be run before all tests in this suite have run.
#AfterSuite: The annotated method will be run after all tests in this suite have run.
#BeforeTest: The annotated method will be run before any test method belonging to the classes inside the <test> tag is run.
#AfterTest: The annotated method will be run after all the test methods belonging to the classes inside the <test> tag have run.
#BeforeGroups: The list of groups that this configuration method will run before. This method is guaranteed to run shortly before the first test method that belongs to any of these groups is invoked.
#AfterGroups: The list of groups that this configuration method will run after. This method is guaranteed to run shortly after the last test method that belongs to any of these groups is invoked.
#BeforeClass: The annotated method will be run before the first test method in the current class is invoked.
#AfterClass: The annotated method will be run after all the test methods in the current class have been run.
#BeforeMethod: The annotated method will be run before each test method.
#AfterMethod: The annotated method will be run after each test method.
It's very simple inheritance related question. When you have extended testcore class in LoginTest class all the methods and data member available in parent will be available to child class including methods annotated with #Before Method etc.
I think you are confused due to miss concept regarding the way TestNG run a program. There are different different way to run a testNG annotated program to get executed and among them XML is a way. So don't get get confuse that all class, methods need to include in that xml. You just need an entry point only and rest will call accordingly.

Initializing objects from within Concordion test spec

I am wanting to use Concordion to write tests for a simple bankAccount pgm that is offered as part of a cucumber tutorial. I am having trouble working out how to initialize objects from the concordion test spec.
I created a method in the fixture called createAccount that took an initialBalance and account number as parameters.
I call it from the test spec with ...
<b concordion:execute="createAccount(#accountNum,#initBalance)">
but when I run the test I get an error ....
java.lang.Exception: Method createAccount should have no parameters.
I know that I can just assign values to these variables from within the fixture class but think it would be a lot more useful if I could do this from the test specification.
Below is part of my test fixture with the call to createAccount
#RunWith(ConcordionRunner.class)
public class CashMachineTest {
private Account newAccount;
int initBalance = 123;
int accountNum = 1;
#Before
public void createAccount(int accountNum, int initBalance) throws Throwable{
newAccount = new Account(accountNum, initBalance);
}
public int getBalance(){
return newAccount.getBalance();
}
public void deposit(int amount){
newAccount.deposit(amount);
}
....
Any help would be much appreciated.
When you want to call the initialization method from your Concordion specification, you don't need the #Before annotation. This is used by JUnit to call methods before the execution of the actual test method. But Concordion does not run a single test method, but calls the methods in your fixture class based on your instrumentation in your specification document.
Pleas, try to remove the #Before annotation and try again.

get Annotation of test method in testNG ITestListener

I am trying to integrate TestLink with TestNG
Approach is below
1>Write ITestListner with onTestFailure and onTestSuccess
2> get Annotation of the method(like testName which will be equivalent to test name in testlink) which is being failed/success in a variable
3>Make connection with TestLink using API available and update the test case.
However I am struggling to find method Annotation value in ITestListner and requirement is to get annotation values in ITestListner only so that correct test cases can be updated in Test_link
Can someone please help me how to get Test Method annotation value in ITestListner or any other approach in which i can integrate testlink update with TestNG
Hi Thanks niharika for help
,First of all you are correct in explaining use of TestNG but we are using TestNG for Selenium and already there are around 1000 test cases writen in test Methods and we have to live with that
Some how i have figured the solution ,we can still get the testName of the test method using two listners
This is just work around I am not sure if this is the best approach but as of now solving my purpose
package com.automation.testng.listner;
import org.testng.*;
public class MyIInvokeMethodListner_TestName_TestLink implements IInvokedMethodListener {
public static String testName;
public void afterInvocation(IInvokedMethod arg0, ITestResult arg1) {
// TODO Auto-generated method stub
}
public void beforeInvocation(IInvokedMethod m, ITestResult tr) {
// TODO Auto-generated method stub
//This give the Annotation Test object
org.testng.annotations.Test t=m.getTestMethod().getMethod().getAnnotation(org.testng.annotations.Test.class);
MyIInvokeMethodListner_TestName_TestLink.testName = t.testName().toString();
}
}
MyITestListner goes like below
package com.automation.testng.listner;
import org.testng.*;
public class MyITestListner_TestLink extends TestListenerAdapter {
/*IAnnotationTransformer at;
public Listner_1()
{
this.at = new Annotation_listner();
}*/
#Override
public void onTestFailure(ITestResult tr)
{
System.out.println("Hurray !I am being inboked from Test listner");
MyIInvokeMethodListner_TestName_TestLink a = new MyIInvokeMethodListner_TestName_TestLink();
System.out.println(MyIInvokeMethodListner_TestName_TestLink.testName);
}
public void onTestSuccess(ITestResult tr)
{
MyIInvokeMethodListner_TestName_TestLink a = new MyIInvokeMethodListner_TestName_TestLink();
System.out.println(MyIInvokeMethodListner_TestName_TestLink.testName);
}
}
Basically we are getting the method and then using Test Annotation class setting the static variable which can be used in MyITestListner
The ITestListener is the one which is used after <test> tag. For getting the method name and annotation specifics, you need to implement IInvokedMethodListener and in the after/before methods of this interface, and use something like method.getTestMethod().getMethodName() to get the executing method name.
If you are adding testName at the method level, I think you are doing it wrong since the help of testng mentions this "The name of the test this test class should be placed in. This attribute is ignore if #Test is not at the class level."
If you are indeed specifying the #Test at your class level then you can get it as below :
method.getTestMethod().getTestClass().getTestName()
A bit ugly and you probably want to wrap those parts in null checks in your code but this is how you get the testName specified in the annotation from the ITestResult:
iTestResult.getMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class).testName()