How to add Grouping and Dependency in #BeforeMethod On TestNG - java

Is there any way to give dependency to #BeforeMethod on #Test,because in my scenario different TestMethod have different setup and I need one setup depends on TestMethod. I add here some code snippet for better understanding
#BeforeMethod(groups = {"gp2"})
public void setUp1() {
System.out.println("SetUp 1 is done");
}
#BeforeMethod(groups = {"gp1"}, dependsOnGroups = {"tgp1"})
public void setUp2() {
System.out.println("SetUp 2 is done");
}
#Test(timeOut = 1, groups = {"tgp1"})
public void testMethod() throws InterruptedException {
Thread.sleep(2000);
System.out.println("TestMethod() From Group1");
}
#Test(dependsOnMethods = {"testMethod"}, groups = {"tgp2"})
public void anotherTestMethod() {
System.out.println("AnotherTestMethod()From Group1 and Group2");
}
OutPut
SetUp 1 is done
SetUp 2 is done
but I need setUp1() should be executed not setUp2() because it is depends on tgp1 group.
Another thing I observe that,If I change dependencies from
#BeforeMethod(groups = {"gp1"}, dependsOnGroups = {"tgp1"})
to
#BeforeMethod(groups = {"gp1"}, dependsOnMethods = {"testMethod"})
then I got an Exception like
setUp2() is depending on method public void testMethod() throws java.lang.InterruptedException, which is not annotated with #Test or not included.
I need execution should be on this steps
SetUp1---->testMethod1()------->SetUp2--------->testMethod2()
I need this because different TestMethods have different work and it have different SetUp().

In your case, you can simply call respective setUp method from respective Test method as you really don't have common #BeforeMethod for each Test.
Or you can separate these two tests into different Test classes each having a #BeforeMethod.
Or you can do conditional setup call based on test method name with one #BeforeMethod method as below. Here #BeforeMethod can declare a parameter of type java.lang.reflect.Method. This parameter will receive the test method that will be called once this #BeforeMethod finishes
#BeforeMethod
public void setUp(Method method) {
if (method.getName().equals("testMethod")) {
setUp1();
} else if (method.getName().equals("anotherTestMethod")) {
setUp2();
}
}
public void setUp2() {
System.out.println("SetUp 2 is done");
}
public void setUp1() {
System.out.println("SetUp 1 is done");
}

The purpose of the #BeforeMethod is to run before each test method annotated with #Test and do some set-up work. Therefore it is somewhat confusing why you would want to create dependency that works the other way - execute the test method before set-up method.
The usual approach would be following:
#BeforeMethod
public void setUp() {
}
#Test
public void testMethod1() {
}
#Test
public void testMethod2() {
}
Which most likely generate following execution list:
setUp()
testMethod1()
setUp()
testMethod2()
If there multiple #BeforeMethods all of them will be run before the #Test method.
Now if you want to run different groups, you would annotate different methods with different groups and specify, which groups to run. However, for that you will need to provide either testng.xml or specify which groups to execute.
EDIT (based on additional comment):
I would suggest one of the following approaches:
Separate test methods into different classes and have #BeforeMethod
in each class perform required setup. This especially makes sense if
the tests are covering different areas.
Define different groups and
put corresponding test and set-up methods into same group. This
option lets you mix and match set-up methods with test method.
Some things that are unclear from your question, but if relevant could benefit from suggested approaches:
Is there need for dependency?
Does the order or the tests matter?

Related

Java Selenium close browser after assertTrue

I have a code with many classes.
There is a class which creates the driver -
public class DriverDelegate {
private String baseURL = "someLink";
private WebDriver driver;
private WebDriverWait wait;
DriverDelegate(String url) {
System.setProperty("webdriver.chrome.driver", "${directory}");
driver = new ChromeDriver();
driver.get(baseURL + url);
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
wait = new WebDriverWait(driver, 5);
}
public WebDriver getDriver() {
return driver;
}
I create new driver for every test. And most of my lines are the ones containing assertTrue like this-
public class UserInterfaceTests extends BaseTest{
#Test
public void headerClicker() throws java.lang.Exception {
//Startup
DriverDelegate driverDelegate = new DriverDelegate("url");
WebDriver driver = driverDelegate.getDriver();
//Some random assertTrue
assertTrue("Test(HeaderClicker) - NoSuchElementException click", TestHelper.headerClicker(schedule, driver));
//I hope that it is not neccessary to put up all helper classes like TestHelper or BaseTest
Now I launch my tests from a class called Startup -
public class Startup{
#Test
public void HeaderClicker() throws Exception{ UserInterfaceTests UI = new UserInterfaceTests(); UI.headerClicker();}
My question here is how to close the browser after the assertTrue fails. Things like #AfterTest, #AfterSuite etc do not work because other methods can not use the same driver that was used in the test.
Any ideas?
Ok there are a few things I want to touch on here. First off, #shutdown -h now is correct in their comment that you shouldn't be programmatically creating test classes and running their #Test methods yourself. Let the test running framework handle that (e.g. TestNG, JUnit, etc).
To the point of your actual question, though, is that you want pre-test and post-test methods to handle behavior that occurs before and / or after your actual test method. For these to work, though, you need to let the test framework handle the running of the tests. You mentioned #AfterTest and #AfterSuite as not being correct for your use case, though not for the reason you specified (entirely). #AfterTest in TestNG only is executed once after all the test methods in all the classes inside of a <test> node specified in a suite. #AfterSuite is only executed once after all the test methods in the entire suite. What you are looking for is the #AfterMethod annotation.
Example:
public class FooTest {
private DriverDelegate driver;
#BeforeMethod
public void setup() {
try {
driver = new DriverDelegate("url");
} catch (Exception ignore) { }
}
#AfterMethod
public void tearDown() {
try {
driver.quit();
} catch (Exception ignore) { }
driver = null;
}
#Test
public void foo() {
// do test stuff
}
}
In the above code, when TestNG runs this test class, each method annotated with #Test in this class will have a corresponding #BeforeMethod execution that initializes the driver and an #AfterMethod that closes the driver even if the test fails. Couple of points to make about this type of setup with TestNG:
(1) TestNG does not create separate instances of the test class so if you save state on the class object then you cannot run the test methods themselves in parallel within a class since you would have multiple methods trying to create new drivers and save them to the same variable, corrupting the state of the other tests that are running. You can run with parallel mode of per class (e.g. have 5 threads, each running a separate test class at the same time).
(2) Why did I wrap the #BeforeMethod and #AfterMethod bodies in a try-catch block? Because TestNG takes a fail quickly on configuration method exceptions and can cause other tests that haven't run yet to be skipped so you need to deal with any code that could possibly fail. By wrapping the creating and closing of the web driver you can ignore the error and continue on running other tests. If the driver fails to be created, for instance, the driver variable will be null and that #Test method will fail but others might succeed. Ideally, you should probably have some logging of the exception so that you can investigate why the driver failed to be created, for instance.
Also, if you need to use a driver in many test classes, you can make a base class that does the creation of the driver along with the closing of it after each method and have your test classes extend that. If you have a class with a method annotated with #Test on it, it will run any #BeforeMethod methods on that test class AND on all of the super classes as well. There is guaranteed ordering of the methods between classes (though not if you have multiple #BeforeMethod methods in the same class).
public abstract class A {
#BeforeMethod
public void setupA() { }
}
public class B extends A {
#BeforeMethod
public void setupB() { }
#Test
public void foo() { }
}
In the above, when foo is run, it will have run first setupA and then setupB. After methods work in the same way, but in the reverse order.

dependsOnMethods for #AfterTest not finding the test method

I am trying following code:
public class ShashiTest {
#Test
public void test1(){
System.out.println("1===========");
}
#Test(dependsOnMethods="test1")
public void test2(){
System.out.println("2===========");
}
#Test(dependsOnMethods="test2")
public void test3(){
System.out.println("3===========");
}
#AfterMethod(dependsOnMethods={"test2","test3"})
public void test4(){
System.out.println("4===========");
}
}
I am expecting output as:
1===========
2===========
4===========
3===========
4===========
But I am getting exception as test method not found:
com.ShashiTest.test4() is depending on method public void com.ShashiTest.test2(), which is not annotated with #Test or not included.
at org.testng.internal.MethodHelper.findDependedUponMethods(MethodHelper.java:111)
Where I am making the mistake? How I can achieve my goal?
#AfterMethod declares that this method is run after every method annotated with #Test. Right now you have a conflict with test4() being called after test1() and before test2(), while also requiring it to be run after test2(). Refer to this for more in-depth discussion.
edit: I should probably make the call order more clear.
test1()->test4()
test2()->test4()
test3()->test4()
As you can see, requiring test4() to be run after test2() and test3() is in conflict with the #AfterMethod annotation requiring it be called after every method.
dependsOnMethod is not working like that and just used to order methods between them.
The javadoc is clear enough IMO:
The list of methods this method depends on. There is no guarantee on the order on which the methods depended upon will be run, but you are guaranteed that all these methods will be run before the test method that contains this annotation is run. Furthermore, if any of these methods was not a SUCCESS, this test method will not be run and will be flagged as a SKIP. If some of these methods have been overloaded, all the overloaded versions will be run.
But the exception should not happen so I opened an issue for it.
About your need which is running an #AfterMethod for specific methods only (something looks weird, but why not), you can do the following:
public class ShashiTest {
#Test
public void test1(){
System.out.println("1===========");
}
#Test(dependsOnMethods="test1")
public void test2(){
System.out.println("2===========");
}
#Test(dependsOnMethods="test2")
public void test3(){
System.out.println("3===========");
}
#AfterMethod
public void test4(Method m){
switch(m.getName()) {
case "test2":
case "test3":
System.out.println("4===========");
}
}
}
should work as expected.
Bit late to answer but I just faced this problem today. Error: com.expedia.FlightBooking.tearDown() is depending on method public void com.expedia.FlightBooking.flightBooking(), which is not annotated with #Test or not included.
Solution: Changing dependsOnMethods to dependsOnGroups Ex: #AfterTest(dependsOnGroups = {"flightBooking"}) has solved my problem.

Marking test methods with #Test(dependsOnMethods=..) testNG annotation make them not to execute

I've got a problem in my production test suite runs.
testng.xml has set up to run test suite in multithreaded environment using custom listener. As result there are several driver instances that are running separately and in parallel, with each test.
Last time suite started failing and I noticed strange behavior:
Each test in each test method which has dependsOnMethods in its #Test annotation do not execute. Driver just skipps them, and does not execute #AfterTest methods as result.
Or, I suppose It does not skip them, it does not report to depend methods that "login" method is done and they can go on and execute.
But i have no idea why is it happening
Smth like this:
#BeforeClass
protected void beforeClassInit(){
setUp(///);
}
#Test
public void login() {
//login activities
}
#Test(dependsOnMethods = "login")
public void createSmth() {
///
}
#Test(dependsOnMethods = "createService")
public void deleteSmth() {
///
}
#AfterClass(alwaysRun = true)
protected void afterClass() {
shutDown();
}
See in your code,
#BeforeClass
protected void beforeClassInit(){
setUp(///);
}
#Test
public void login() {
//login activities
}
#Test(dependsOnMethods = "login", alwaysRun=true)
public void createSmth() {
///
}
#Test(dependsOnMethods = "createSmth", alwaysRun=true)
public void deleteSmth() {
///
}
#AfterClass(alwaysRun = true)
protected void afterClass() {
shutDown();
}
createSmth and deleteSmth always run even if dependant method will get fail to execute. Before and after class annotation will be run before/after the first/last test method in the current class is invoked.
#BeforeClass when multiple tests need to share the same computationally expensive setup code. #BeforeClass will be executed only once.
It works even if you will run using testng.xml in parellel
The problem was in testng logic.
Through tons of experiments it was defined, that TestNG always runs dependent methods in the end of parallel run.
Means, i.e. you have 3 Test Classes:
Test1.java
Test2.java
Test3.java
and each has some test methods.
TestNG suite contains that 3 classes will run each non-dependent method from those classes, than come back and finish run of those dependent methods which left.
Crazy behavior, but looks that's it/

Integration test before others

I have a bunch of integration tests that need to have a database populated before running. This task takes about 30 minutes, so it is not feasible to run it before every test.
I'm using junit and I'd like to be able to annotate this one class with something so that it runs and completes before the others start. Is this possible?
(most of the annotations I found only work on methods, e.g. #Rule)
I've done this in the past by adding setup and teardown functions to the individual test classes, annotated with #BeforeClass and #AfterClass.
#BeforeClass
public static void setupBeforeClass() {
DatabasePopulater.populate();
}
#AfterClass
public static void tearDownAfterClass() {
DatabasePopulater.dePopulate();
}
If more than one test class requires the same setup to be done, the setup function can do a kind of reference counting to make sure they only do their work the first time it's called:
public class DatabasePopulater {
AtomicInteger invocations = new AtomicInteger();
....
public static void populate() {
if (0 == ivocations.getAndIncrement()) {
// Actually populate DB
}
}
public static void dePopulate() {
if (0 == ivocations.decrementAndGet()) {
// Actually clear DB
}
}
If you are using something like ant/gradle to execute the test suite, you could separate out the db population into a standalone java program and then have a depends="populateDB" on the junit task.

How to run tearDown type method for a specific test in JUnit class with multiple tests?

I have a junit testCase class with multiple test methods in it ( As requirement , we don't want to create separate class for each test.)
I wanna create a tearDown type method for EACH test method , which will run specifically for that test. Not for ALL test.
My problem is , in many tests i Insert record in database, test it and delete it after test.
But, If a test fails mid way , control don't reaches till end my dummy record ain't deleting.
I think only ONE tearDown() is allowed for one class, and this tearDown() don't know what object/record i created or inserted and what to delete!!!
I want to create a tearDown() or #After method just for one specific test. Something like finally{} in java for each method.
For Eg:
public class TestDummy extends TestCase {
public void testSample1(){
InsertSomeData1();
assertFalse(true);
runTearDown1();
}
public void testSample2(){
InsertSomeData2();
assertFalse(true);
runTearDown2();
}
public void runTearDown1(){
deleteDummyDatafromTestSample1....
}
public void runTearDown2(){
deleteDummyDatafromTestSample2....
}
}
Here control will never go to runTearDown1() or runTearDown2() and I don't a one common tearDown() because it won't know what data I inserted and thats specific to each method.
It seems your test relies on a fixed database, and future tests will break if your current test breaks. What I'd recommend is not to focus on this particular problem (a test-specific tearDown method that runs for each test), but your main problem - borken tests. Before your test run, it should always work with a clean database, and this should be the case for each test. Right now, your first test has a relationship with the second (through the database).
What the right approach would be is that you recreate your database before each test, or at the very least reset it to a basic state. In this case, you'll want a test like this:
public class TestDummy {
// this code runs (once) when this test class is run.
#BeforeClass
public void setupDatabase() {
// code that creates the database schema
}
// this code runs after all tests in this class are run.
#AfterClass
public void teardownDatabase() {
// code that deletes your database, leaving no trace whatsoever.
}
// This code runs before each test case. Use it to, for example, purge the
// database and fill it with default data.
#Before
public void before() {
}
// You can use this method to delete all test data inserted by a test method too.
#After
public void after() {
}
// now for the tests themselves, we should be able to assume the database will
// always be in the correct state, independent from the previous or next test cases.
#Test
public void TestSample2() {
insertSomeData();
assertTrue(someData, isValid());
}
}
Disclaimer: JUnit 4 tests (using annotations), might not be the right annotations, might not even be the right answer(s).
You could have smth like this:
interface DBTest {
void setUpDB();
void test();
void tearDownDB();
}
class DBTestRunner {
void runTest(DBTest test) throws Exception {
test.setUpDB();
try {
test.test();
} finally {
test.tearDownDB();
}
}
}
public void test48() throws Exception {
new DBTestRunner().runTest(new DBTest() {
public void setUpDB() {...}
public void test() {...}
public void tearDownDB() {...}
});
}
#iluxa . Gr8.. Your solution is perfect!!! In one test class i created two tests test48 and test49 (same as required in my code above testSample1 and testSample2) and viola! every test method now gets its own setup() and tearDown. Only this solution looks little complicated as need to use DBTestRunner in each method, but I don't see any better solution. I was thinking Junit may have some direct solution. like #After or tearDown() with some parameter or something.
Tks a lot.
Use MethodRule:
public class MyRule implements MethodRule {
#Override
public Statement apply(final Statement base, FrameworkMethod method, Object target) {
return new Statement() {
#Override
public void evaluate() throws Throwable {
try {
base.evaluate();
} catch (AssertionError e) {
doFail();
} finally {
doAnyway();
}
}
};
}
}
Then declare it in your test class:
public class TestDummy{
public MethodRule rule = new MyRule();
......
}

Categories