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

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

Related

How can I control how many JUnit5 Test Instances are going to be generated in Runtime and apply separate ParameterResolver to each of the instance

I'd like to execute Selenium Grid tests using Maven like this:
mvn verify-Dtest=BaseTest -Dprop.selenium.server.url=http://localhost:4444/wd/hub
-Dprop.browser=chrome
-Dprop.version=80.0.3987.106
I inject ChromeDriver into Test constructor using JUnit5 ParameterResolver interface
#ExtendWith(ChromeRemoteWebDriverParameterResolver.class)
#TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class MultiBrowserDemoTest {
RemoteWebDriver driver;
public MultiBrowserDemoTest(RemoteDriver driver) {
this.driver = driver.getDriver();
}
#SneakyThrows
#Test
public void testGrid() {
driver.get("https://www.google.com/");
WebElement search = driver.findElement(By.name("q"));
search.sendKeys("JUnit5 extensions");
search.submit();
}
#AfterAll()
void tearDown() {
driver.quit();
}
}
It works fine. But I can't see how to implement multi-browser test execution.
Let's say, I want to add multiple browsers -Dprop.browser=chrome, firefox, opera, ie11
I created multiple classes implementing ParameterResolver Interface. But JUnit5 does not let me inject them all into my Test Class. It does not create new instances of Test class either.
I tried to use TestInstanceFactory to create new Instances of my Test class and apply separate implementation of ParameterResolver interface, but it did not work for me.
End Result: I can run the same test in multiple browsers in parallel using Selenium Grid and only one Test Class that I will be able to instantiate multiple times with separate webdriver.
If I understood your scenario correctly, what you are asking for is support for what we call "parameterized containers" (i.e., something analogous to #ParameterizedTest but at the class level), which does not exist yet in JUnit Jupiter.
See JUnit Jupiter issues #871 and #878 for 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.

Using a one time login for my test suite in testNg

The code listed below is supposed to login in the 2nd #Test block and it will pick it up from the login file has been created. I extends the "Testbase" class. It is logging in fine, but the second code not able to pick it up from there, and again it performs the same function twice thus it opens the web browser twice. Please any suggestion will be highly appreciated. Thank you
public class Case_Trackin extends TestBase{
public WebDriver driver;
#Test
public void OpeningBrowser() throws IOException InterruptedException
{
Login();
}
#Test (dependsOnMethods="OpeningBrowser", alwaysRun=true ) //This block of code previews the ExcelSpreadsheet file
{
}
#AfterMethod public void tearDown()
{
//driver.quit();
}
}
The #Test will be called twice if you are passing the excel data twice. In #AfterMethod the quit method is commented. And make one #Test in one class file as possible.
It looks like you have two different tests. Once the first method runs, it closes (since you are extending the tearDown() method). So when the second method is going to run, there will be no login thus won't be able to perform its goal.
You should include the login method call in all tests(methods in this case) that need that to perform its goals, or change your testBase from #AfterMethod to #AfterClass.

TestNG: priority of #BeforeClass and #BeforeTest

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

How JUnit TestCase functionality actually works?

I have a code like this:
public class MyTest extends TestCase {
private MyObject mObject1;
private MyObject mObject2;
...
#Override
public void setUp() throws Exception {
super.setUp();
}
public void testSomething() {
mObject1 = new MyObject();
mObject2 = new MyObject();
}
public void testSomething2() {
// Here I can't access the previously created objects mObject1 and
// mObject2, because they are again null.
// Why is that, if *my* setUp() method doesn't touch them?
}
My guess is that JUnit instantiates the class again every time. Can someone please explain me the workflow?
Thanks.
JUnit will instantiate the class (MyTest) once per test and then execute the methods
setUp()
testXXX()
tearDown()
until it runs all the methods that start with test and don't receive any parameters. So in your example, Junit will instantiate MyTest twice. You can read more about this in the JUnit documentation.
Bear in mind that this is the old way of writing tests. From Junit 4 (I think) the preferred way is to use annotations. You can check the annotations documentation here.
As a side note, NUnit, reuses the instance of the test, so in the same scenario, it would only instantiate MyTest once.
JUnit will instantiate this class once per test method, so only once in the code above, but try it again with two test methods and you will see it instantiated twice. If you want to save some state in fields without having to use statics, take a look at TestNG, which reuses the same instance for all test methods.