Calling a method from another class using TestNG and Java - java

Getting an error below after running test2.java running as TestNG if I run it as Java Application everything is working. What does the error mean and can anyone help me with this using TestNG and Java. I am using Webdriver and Eclipse and just want to do this simple trick to apply for my test scripts.
SKIPPED: main org.testng.TestNGException: Method main requires 1
parameters but 0 were supplied in the #Test annotation.
Here is my code for Test1.java
package firsttestngpackage;
import org.testng.annotations.Test;
#Test
public class Test1{
public void message(){
System.out.println("Test");
}
}
Here is my code for Test2.java
package firsttestngpackage;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
#Test
public class Test2{
public static void main(String[] args){
Test1 class1 = new Test1();
class1.message();
}
}

If you use #Test in the class level, all the public methods are considered test methods. You need to supply parameters to the main method as it expects an argument.
Just change it to public void main()

It looks you are using TestNG in wrong way. You don't need java main method. Just use annotation #Test and then run class with TestNG (org.testng.TestNG) and defined .xml test suite as Java Application or in Eclipse runner. TestNG invokes all tests methods so you don't have to call it manually.

i got it to work by removing "String[] args"
package firsttestngpackage;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;
#Test
public class Test2{
public void main(){
Test1 class1 = new Test1();
class1.message();
}
}

jaroslav is right.you are using #Test annotation in a wrong way.While using testNG framework u r not using the main method to run the test.u running it as TestNG tests

Firstly the above comments are right. Don't use main method if you are using testNG annotations. Main method can only be used in #Beforeclass and #Afterclass. Also no need of (String[] args).
If you are still facing problem with TestNg,
Make sure you have installed it correctly.
Use this code before your 1st test case (#Test)
#BeforeTest
public void setup ()
{
System.setProperty("webdriver.chrome.driver", "*location of your driver*");
ChromeOptions options = new ChromeOptions();
options.addArguments("test-type");
options.addArguments("start-maximized");
options.addArguments("--js-flags=--expose-gc");
options.addArguments("--enable-precise-memory-info");
options.addArguments("--disable-popup-blocking");
options.addArguments("--disable-default-apps");
options.addArguments("test-type=browser");
options.addArguments("disable-infobars");
driver = new ChromeDriver(options);
driver.manage().deleteAllCookies();
}
Let me know if this helps.

Related

Tests in WebDriver Selenium suite are used to setup further tests. Is there some way I can make my tests not so dependent on previous 'setup' tests?

I am fairly new to software testing (3 -4 years) and I work as a sole tester in an organisation. Unfortunately I have not have a mentor to help me when building the automated test suite.
The main issue I want to overcome is tests failing because a previous test failed. This is mainly because the tests in the WebDriver Selenium suite are used to setup further tests. Is there some way I can make my tests not so dependent on previous 'setup' tests? Let me describe a typical scenario:
To create a transaction, the following things are prerequisites and must be set up in the system first. These are all done as individual tests on the site first:
Source Country
Source Currency
Destination Country
Destination Currency
Commission charge
Agent profile
Sender profile
Receiver profile
Only then can I run the tests to actually create a transaction.In some cases, there are more steps involved in setting up the system before a tests can be run. The problem arises when, for example, the Destination Currency test fails. This will cause all subsequent tests to fail.
What can I do to make the tests more independent so if a previous 'setup' test fails for any valid reason, it doesn't affect the remainder of the tests? I just want to follow best test practices and cannot find the answer to this question anywhere online.
Many thanks in advance.
If your tests can pass independently then it can be done using cucumber-guice injection to independently open browser for each scenario.
You may have to arrange your tests as scenarios like below
Scenario: set source country
Given source country is setup
Scenario: set source currency
Given source currency is setup
OR you can use example feature of cucumber. In this method you may to do extra parsing in step defs depending on how much different it is to set up each source
Scenario Outline: login registration
Given these <source> are set up with <details>
Examples:
|source|details|
|"country" |"xyz"|
|"currency" |"abc"|
...
...
cucumber-guice will open one browser for each scenario in both above methods ( cucumber consider each example line a scenario)
Now the actual guice implementation. To use guice you will need cucumber-guice dependency
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-guice</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>4.2.3</version>
<scope>test</scope>
</dependency>
These are the classes that I use to independently open browser for each scenario. In a chromemanager class you do
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
public class ChromeManager extends DriverManager {
protected ChromeDriver driver;
#Override
protected WebDriver createDriver() {
System.setProperty("webdriver.chrome.driver", "/Users/../chromedriver");
return driver = new ChromeDriver(ChromeDriverService.createDefaultService());
}
#Override
public WebDriver getDriver() {
if (driver == null) {
this.createDriver();
}
return driver;
}
}
Driverfactory class
import org.openqa.selenium.WebDriver;
public class DriverFactory {
public WebDriver getManager() {
return new ChromeManager().getDriver();
}
}
Drivermanager class
import org.openqa.selenium.WebDriver;
public abstract class DriverManager {
protected abstract WebDriver createDriver();
public abstract WebDriver getDriver();
}
and then in a global class
import org.openqa.selenium.WebDriver;
import io.cucumber.guice.ScenarioScoped;
#ScenarioScoped
public class Global {
public WebDriver driver;
public WebDriverWait wait;
public Global() {
driver = new DriverFactory().getManager();
wait = new WebDriverWait(driver, 3000);
//any class you instantiate here will be injected in below initialIT class for each scenario
}
}
and finally your test class
import com.google.inject.Inject;
import com.test.support.Global;
public class InitialIT {
public static ChromeDriver driver ;
#Inject
Global global;
#Test
#Given("source country is setup")
public void setCountry() throws MalformedURLException {
global.driver.get(yourSite);
}
#Test
#Given("source currency is setup")
public void setCurrency() throws MalformedURLException {
global.driver.get(yourSite);
}
#After
public void closeBrowser() {
global.driver.quit();
}
}

Why am I asked to refactor code and include org.testng.AssertJUnit when creating testng.xml suite?

I have two TestNG classes containing a few #Test annotations, nothing fancy, and test methods just under them. When I select both of my class files in Eclipse, right-click, choose TestNG - Convert to TestNG, I am presented with a refacotoring wizard in Eclipse to create said testng.xml suite. But when I cliked Next, I'm asked to refactor my code and include org.testng.AssertJUnit.
Why JUnit? What does JUnit have to do with this?
Here's a code sample:
package seleniumTestovi.Pages; import org.testng.Assert;
import org.testng.annotations.Test;
public class NewTest {
#Test
public void foo() {
Assert.assertTrue(true);
}
}
And here is the code Eclipse wants me to refactor when i try to create testng.xml suite.
package seleniumTestovi.Pages;
import org.testng.annotations.Test;
import org.testng.AssertJUnit;
import org.testng.annotations.Test;
public class NewTest {
#Test
public void foo() {
AssertJUnit.assertTrue(true);
}
}

While using TestNG if we define WebDriver driver; globally then without creating object of that class how we are able to use driver under a method?

The code is working fine but why? without creating object of class Testing123 How we are able to access that driver?
public class Testing123 {
WebDriver driver ;
#Test
public void test1() {
driver = new ChromeDriver();
driver.get("http://google.com");
}
}
TestNG framework is taking care of creating an instance of your test class behind the scenes. Basically by annotating your method with '#Test' the annotation processor associate the class to the test runner. For further info look at: http://makeseleniumeasy.com/2018/06/08/testng-tutorials-21-why-dont-we-require-a-main-method-in-testng-class-for-execution-of-methods/

JUnit Category doesn't work with TestCase?

I found a strange thing and I'm interested to know why it happens. I'm using maven surefire plugin ( 2.12.4 ) with Junit 4.11. When I wanted to use #Category annotation in order to disable some tests. the strange thing that it works correctly only with tests that don't extend TestCase. For test that don't extend TestCase I was able to put the annotation only on the test method to run/disable, but with others it disables all tests in the class.
Example:
Command Line:
mvn test -Dgroups=!testgroups.DisabledTests run only test B for the first snippet:
import static org.junit.Assert.*;
public class DataTest {
#Test
public void testA(){...}
#Test #Category(testgroups.DisabledTests.class)
public void testB(){...}
}
for the second case with class extending TestCase, it will run no tests.
public class DataTest extends TestCase {
#Test
public void testA(){...}
#Test #Category(testgroups.DisabledTests.class)
public void testB(){...}
}
Why it happens?
The solution was given in a comment by deborah-digges:
The problem is that the second class is an extension of TestCase. Since this is JUnit 3 style, the annotation #Category didn't work. Annotating the class with #RunWith(JUnit4.class) should give you the same result in both cases
and another by Stefan Birkner:
JUnit 4 finds test by looking for the #Test annotation. You can remove the extends TestCase from your test class. Furthermore the name of the test method does no longer have to start with test. You're free to choose any method name you want.

How to specify order of execution of Java classes in a Selenium-Java Webdriver test project

I have to automate a test-suite for a web application which let user connect and sync with their Dropbox account. I am using Java Selenium Webdriver.
Here I have created test classes like this.
Class1.java - Test case to check if connected to Internet.
Class2.java- Test case for sign in with Dropbox
Class3.java- Test case to verify if Dropbox folders are shown on web page.
Now these test classes are supposed to execute in this order.
But when I run the project as JUnit test, it executes these tests in some other order. I don't find any XML file so that I can specify order of execution of these classes.
I also have tried TestNG because I read Here that TestNG provides an attribute "preserve-order".
But It is not working. I don't have much experience with Selenium and Java Webdriver.
So any help would be appreciable.
Thanx in advance.
Peter Niederwieser is right.
In addition you can set the order of the tests to run within the classes (Junit 4.11):
import org.junit.runners.MethodSorters;
import org.junit.FixMethodOrder;
import org.junit.Test;
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SampleTest {
#Test
public void firstTest() {
System.out.println("first");
}
#Test
public void secondTest() {
System.out.println("second");
}
}
Addition to Ittiel's post:
Instead of:
#FixMethodOrder(MethodSorters.NAME_ASCENDING)
You can use:
#FixMethodOrder(MethodSorters.JVM)
This way, you don't have to play tricks with your test names. You only have to arrange your tests in the correct order.
This works fine for me. Thanks to Ittiel!
You can use a JUnit test suite:
import org.junit.RunWith;
import org.junit.runners.Suite;
#RunWith(Suite.class)
#Suite.SuiteClasses({Class1.class, Class2.class, Class3.class})
public class DropboxWorkflow {}
Try this
#Test(dataProvider = "Login", priority = 1)
public void login()
{
//code
}
#Test(dataProvider = "Search", priority = 2)
public void search()
{
//code
}

Categories