Selenium Exception Handling Design - java

In Order to prevent exception handling in each method in selenium page objects, i thought to have a general exception handling, a try catch in the test block,
other handlers only if more specific handling required,
Now the issue is that this process needs to be written in each test...
is there a way to make the test methods have this common test handling written once for all tests?
#Test
public void test(WebDriver driver) {
try {
// common code in the try block
// using testNG may be moved to #BeforeMethod And #AfterMethod
Logger.log("Test Started....");
Logger.log("Test Ended....");
Assert.assertAll();
}
catch() {
// in Case Automation Fails, common operations required
ScreenShoot.getScreenShoot();
}
finally
{
// finally for all tests
driver.close();
}
}

If you are using jUnit, you can create a TestWatcher Rule (the TestNG alternative ITestListener is mentioned here).
public class YourTestWatcherImplementation extends TestWatcher() {
#Override
protected void starting(Description description) {
// initialize your WebDriver
// perhaps login to your tested application?
}
#Override
protected void finished(Description description) {
// shutdown your WebDriver
}
#Override
protected void failed(Throwable error,
Description description) {
// take a screenshot
// do more error handling/reporting
}
}
This way, your tests only contain the actual test code and you got all the preparation/tearDown in one place.
Each test class only needs a public member variable with the #Rule annotation like this:
public class OneOfYourTestClasses {
#Rule
public TestWatcher watcher = new YourTestWatcherImplementation();
#Test
public void testSomething() {
...
}
#Test
public void testEvenMore() {
...
}
}

I'd suggest to create parent test class, which all other tests will extend. In this parent test class, create #AfterMethod, which will take screenshot on failure. Here is an example (although without inheritance):
http://artoftesting.com/automationTesting/screenShotInSelenium.html

Related

Setup JUnit test timeout using reflection

I have found so far 2 ways to setup JUnit test timeout. Either using:
#Test(timeout=XXX)
Or using something like:
#ClassRule
public static Timeout timeoutRule = new Timeout(XXX, TimeUnit.MILLISECONDS);
In my case, I have a Test Runner as a main class to run all my test suites, so I can execute the tests as an executable jar.
I'd like this runner to setup the timeouts dinamically using reflection.
Is it possible to do?
You could add the timeout feature to a custom test runner like so:
public class TimeoutTestRunner extends BlockJUnit4ClassRunner {
public TimeoutTestRunner(Class<?> clazz) throws InitializationError {
super(clazz);
}
#Override
protected Statement withPotentialTimeout(FrameworkMethod method, Object test, Statement next) {
return FailOnTimeout.builder()
// you'll probably want to configure/inject this value rather than hardcode it ...
.withTimeout(1, TimeUnit.MILLISECONDS)
.build(next);
}
}
Using this test runner the tests in the following test case ...
#RunWith(TimeoutTestRunner.class)
public class YourTest {
#Test
public void willTimeout() throws InterruptedException {
Thread.sleep(50);
assertTrue(true);
}
#Test
public void willNotTimeout() throws InterruptedException {
assertTrue(true);
}
}
... will behave as follows:
willTimeout: will fail with a TestTimedOutException
willNotTimeout: will pass
Although you will need your tests to be run via this runner you will be able to control their timeout setting from one place and provide custom timeout derivation strategies such as if test name matches <some regex> then timeout is x else ....

Use Mockito to unit test a function which contains static method call & async task

I have a helper class which contains an public static method getProductHandler(String name):
public class ProductHandlerManager {
public static Handler getProductHandler(String name) {
Handler handler = findProductHandler(name);
return handler;
}
}
A CustomerService class uses the above ProductHandlerManager:
public class CustomerService {
...
public void handleProduct() {
Handler appleHandler = ProductHandlerManager.getProductHandler("apple");
appleHandler.post(new Runnable() {
#Override
public void run() {
//...
}
});
}
}
I want to unit test handleProduct() method in CustomerService class. I tried using mockito to mock the ProductManager.getProductHandler("apple") part in test, however, mockito doesn't support static method mocking. How can I use Mockito to unit test handleProduct() function then?
Please don't suggest me to use Powermock, since I read some article which says if I need to mock static method, it indicates a bad design. But I can accept suggestions about code refactoring to make it testable.
You can refactor and specify a Handler yourself. These can often be package private, if you put your tests in the same package as your classes-under-test—even if they're in a different source folder (e.g. src vs testsrc). Guava (Google Commons) has a handy #VisibleForTesting documentation annotation, too, though Javadoc tends to work as well.
public class CustomerService {
public void handleProduct() {
handle(ProductHandlerManager.getProductHandler("apple"));
}
/** Visible for testing. */
void handleProduct(Handler handler) {
handler.post(new Runnable() {
#Override
public void run() {
//...
}
});
}
}
At this point, you can test handleProduct(Handler) intensively as a unit test, then only test handleProduct() as an integration test to ensure the "apple" product handler interacts correctly.

AfterAll global hook cucumber-jvm

I'm using cucumber-jvm in my integration tests and I need to execute some code after all scenarios are finished, just once.
After reading carefully some posts like this and reviewed this reported issue, I've accomplished it doing something like this:
public class ContextSteps {
private static boolean initialized = false;
#cucumber.api.java.Before
public void setUp() throws Exception {
if (!initialized) {
// Init context. Run just once before first scenario starts
Runtime.getRuntime().addShutdownHook(new Thread() {
#Override
public void run() {
// End context. Run just once after all scenarios are finished
}
});
initialized = true;
}
}
}
I think the context initialization (equivalent to BeforeAll) done in this way is fine. However, although it's working, I'm not sure at all if the AfterAll simulation using Runtime.getRuntime().addShutdownHook() is a good practice.
So, these are my questions:
Should I avoid Runtime.getRuntime().addShutdownHook() to implement AfterAll?
Are there other better choices to emulate the AfterAll behaviour in cucumber-jvm?
Thanks in advance for the help.
Probably a better way would be to use a build tool, like Ant, Maven or Gradle for set-up and tear-down actions, which are part of integration tests.
When using Maven Fail Safe Plug-in, for setting up integration tests. There is the phase pre-integration-test, which is typically used for setting up the database and launch the web-container. Then the integration-tests are run (phase integration-test). And afterwards the phase post-integration-test is run, for shutting down and closing / removing / cleaning up things.
INFO In case the Cucumber tests are run through JUnit, the following might also be worth considering
In case it is simpler, smaller set up stuff, you can have a look at the JUnit #BeforeClass and #AfterClass. Or implement a JUnit #ClassRule, which has it's own before() and after() methods.
#ClassRule
public static ExternalResource resource = new ExternalResource() {
#Override
protected void before() throws Throwable {
myServer.connect();
}
#Override
protected void after() {
myServer.disconnect();
}
};
As of Cucumber 2.4.0, the following class gave me the equivalent of #BeforeClass in Junit.
You can place this in test/java/cucumber/runtime.
package cucumber.runtime; //cannot change. can be under /test/java
import cucumber.runtime.io.ResourceLoader;
import cucumber.runtime.snippets.FunctionNameGenerator;
import gherkin.pickles.PickleStep;
import java.util.List;
public class NameThisClassWhatever implements Backend {
private Glue glue;
private List<String> gluePaths;
#Override
public void loadGlue(Glue glue, List<String> gluePaths) {
this.glue = glue;
this.gluePaths = gluePaths;
//Any before steps here
}
#Override
public void disposeWorld() {
//any after steps here
}
#Override
public void setUnreportedStepExecutor(UnreportedStepExecutor executor) { }
#Override
public void buildWorld() { }
#Override
public String getSnippet(PickleStep p, String s, FunctionNameGenerator fng) {
return null;
}
public NameThisClassWhatever(ResourceLoader resourceLoader) { }
}

testNG annotation which would equal to "finally" in java?

i don't know if my question was clear, but i am using testNG and i have this:
#Test
public void passengerServiceTest() {
...
}
#AfterTest
public void deleteCreatedPassenger() {
...
}
I want to execute my deleteCreatedPassenger() method after passengerServiceTest, also, i want that in case of deleteCreatedPassenger fails, passengerServiceTest fails too, in other words, i want that both of them be the same test, so if one them fails, test fails.
So i tried with the annotations #AfterTest, #AfterMethod, #AfterClass and all make two tests as "separated" tests.
Do you know how to do this? Regards
You don't need annotations to achieve this, since it's exactly what the finally block is intended for:
#Test
public void passengerServiceTest() {
try {
//test code
} finally {
deleteCreatedPassenger();
}
}
public void deleteCreatedPassenger() {
...
}
If the delete throws an exception then your service test fails.
Annotations are useful in certain scenarios, you shouldn't aim to use them over core language constructs.
alwaysRun
https://testng.org/doc/documentation-main.html
Ex:
#AfterTest(alwaysRun = true)
public void deleteOldValuesFromDatabase() {
...
}
Docs say that this will cause the method to run "even if one or more methods invoked previously failed or was skipped"

Junit - Multiple #Before vs. one #Before split up into methods

In a unit test, I need to perform a quite complex setup (this may be a code smell but this is not what this question is about :-)). What I'm interested in is if it is better to have multiple #Before methods performing the setup or just one, which calls helper methods to perform the initialization.
E.g.
#Before
public void setUpClientStub() {
}
#Before
public void setUpObjectUnderTest() {
}
vs.
#Before
public void setUp() {
setUpClientStub();
setUpObjectUnderTest();
}
As has been said in other responses, the order in which JUnit finds methods is not guaranteed, so the execution order of #Before methods can't be guaranteed. The same is true of #Rule, it suffers from the same lack of guarantee. If this will always be the same code, then there isn't any point in splitting into two methods.
If you do have two methods, and more importantly, if you wish to use them from multiple places, then you can combine rules using a RuleChain, which was introduced in 4.10. This allows the specific ordering of rules, such as:
public static class UseRuleChain {
#Rule
public TestRule chain= RuleChain
.outerRule(new LoggingRule("outer rule"))
.around(new LoggingRule("middle rule"))
.around(new LoggingRule("inner rule"));
#Test
public void example() {
assertTrue(true);
}
}
This produces:
starting outer rule
starting middle rule
starting inner rule
finished inner rule
finished middle rule
finished outer rule
So you can either upgrade to 4.10 or just steal the class.
In your case, you could define two rules, one for client setup and one for object, and combine them in a RuleChain. Using ExternalResource.
public static class UsesExternalResource {
private TestRule clientRule = new ExternalResource() {
#Override
protected void before() throws Throwable {
setupClientCode();
};
#Override
protected void after() {
tearDownClientCode()
};
};
#Rule public TestRule chain = RuleChain
.outerRule(clientRule)
.around(objectRule);
}
So you'll have the following execution order:
clientRule.before()
objectRule.before()
the test
objectRule.after()
clientRule.after()
I would do the latter. AFAIK, there is no way to guarantee order of #Before annotated setup methods.
Note that there are no guarantees about the order in which #Before annotated methods are invoked. If there are some dependencies between them (e.g. one method must be called before the other), you must use the latter form.
Otherwise this is a matter of preference, just keep them in a single place so it is easy to spot them.
I don't think it makes much of a difference, but I personally prefer the second one (the order Before methods are executed being not defined, you'll have a better control that way).
For me it seems using JUnit 4.12, the methods annotated with #Before get indeed sorted deterministically by the following characteristic:
by reversed lexicographic order with respect to the method name.
You can see this behaviour by executing this Testclass:
import java.util.Arrays;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
/*
* key points:
* - multiple #Before methods get sorted by reversed lexicographic order
* */
public class JUnitLifecyle {
#BeforeClass
public static void runsOnceBeforeClassIsInited() {
System.out.println("#BeforeClass");
}
public JUnitLifecyle() {
System.out.println("Constructor");
}
#Before
public void a() {
System.out.println("#Before a");
}
#Before
public void b() {
System.out.println("#Before b");
}
#Before
public void cd() {
System.out.println("#Before cd");
}
#Before
public void ca() {
System.out.println("#Before ca");
}
#Before
public void cc() {
System.out.println("#Before cc");
}
#Before
public void d() {
System.out.println("#Before d");
}
#Before
public void e() {
System.out.println("#Before e");
}
#Test
public void firstTest() {
System.out.println("#Test 1");
}
#Test
public void secondTest() {
System.out.println("#Test 2");
}
#After
public void runsAfterEveryTestMethod() {
System.out.println("#After");
}
#AfterClass
public static void runsOnceAfterClass() {
System.out.println("#AfterClass");
}
}
I came to this conclusion after playing around with the output, while changing the method names of the methods annotated with #Before.
Keeping this reversed lexicographic order in mind you could name your methods accordingly to let JUnit execute your setup tasks in the right order.
Although the above approach is possible, I think you should not do this in your tests, because the Java-Annotations thing in JUnit was introduced to get away from convention-based testing.
I declared all my #Before methods private and created a single method annotated with #Before that called all those and my tests worked. I have worked in kotlin.
Here's how you can do it:
private fun setUpClientStub() {
//whatever you want to do
}
private fun setUpObjectUnderTest() {
//whatever you want to do
}
#Before
fun setUp() {
setUpClientStub()
setUpObjectUnderTest()
}
#Test
fun test() {
//your test logic
}
This way you can ensure that your methods are called in the right order and you can name them any way you want.

Categories

Resources