Catching exceptions and errors from junit tests without stopping the program? - java

I am using junit and selenium to test a web application and I have a test suite that I'm running. Sometimes when a web page fails to load properly in the browser, tests will fail through no fault of the actual application. To remedy this I wanted to catch any first time errors and run tests again to ensure that the problem indeed lies with the application.
I've tried the code below.
try{
ts.runTest(ts.testAt(testNum), a);
}
catch (Error er){
ts.runTest(ts.testAt(testNum), a);
}
catch (Exception e){
ts.runTest(ts.testAt(testNum), a);
}
Ive also tried this
ts.runTest(ts.testAt(testNum), a);
if (!a.wasSuccessful()){
ts.runTest(ts.testAt(testNum), a);
if (!a.wasSuccessful()){
fail();
System.out.println("Test "+testNum+" failed");
}
}
But in both tests the program stops testing entirely the first time it encounters an error. I need to be able to run these tests multiple times despite failures.

I beleive the easiest way to handle this issue will be to check if your page has loaded before even start executing tests. I am not sure how your tests navigation works. But for me it's something like this we use
public SomePage ClickUpdate()
{
Driver.FindElement(By.Id("MyId")).Click();
//taking page objects in return
return new SomePage (Driver);
}
And inside the SomePage() object use a unique selector and inside the constructor wait until that to exist and wrap that in try catch
try
{
var wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(5));
wait.Until(ExpectedConditions.ElementExists(By.Id("Your Id")));
}
catch (YourException)
{
Driver.Navigate().Refresh();
// Or you can perform another click to allow the page to load
var wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(5));
wait.Until(ExpectedConditions.ElementExists(By.Id("Your Id")));
}
Mine is C#. Hope this helps

Related

Is there a point to handle exceptions in selenium besides for logging purposes?

I am finding it hard to understand the point of exception handling in selenium.
For example, if I try to click on an element, and the element could not be found then NoSuchElementException occurs.
I can catch the exception, throw new RunTimeException, or do nothing. The result will be the same ( the program will fail and stop ).
Why would I bother to handle such an exception?
Am I missing something here?
thanks
public void clickOnElement(MobileElement element, Integer waitInSeconds){
waitInSeconds = (waitInSeconds != null ? waitInSeconds : this.secondsToWait);
try {
waitFor(ExpectedConditions.elementToBeClickable(element),waitInSeconds);
element.click();
} catch (Exception e) {
System.out.println("Could not click on element");
e.printStackTrace();
}
}
Exception handling for Selenium is a great way to proof your tests against unexpected conditions. For example, you can try to find the element again if it is no longer attached to the page, for example after a javascript is executed that changes something in the element.
try{
driver.findElement(By.id("MyId")).click();
} catch (StaleElementReferenceException e){
driver.findElement(By.id("MyId")).click();
}
Or, for example, you can ignore if an element does not appear, for example, a GDPR overlay at the top of the page after logging in.
try {
wait.until(ExpectedConditions.presenceOfElementLocated(By.id("gdpr_overlay")));
} catch (TimeoutException ignored){
}
This will ignore the exception thrown by the wait if the overlay does not appear and continue to run your test.
Exceptions are very useful features, far more useful than just for logging, you should look it up.
You can do whatever you want in the catch block, you can try to click a different element if the first one failed, redirect to another page... The possibilities are endless really.
Advice: Avoid generic exceptions, you should catch specific exceptions and react accordingly, and in the last catch block you can do generic Exception e and throw an error.
Firstly ExceptionHandling is not a concept of Selenium but it is related to JAVA. Now coming to the usage of handling exceptions it has a lot of depth to the concept which you will understand while constructing frameworks but as of now it is important to understand by handling exceptions you can continue to execute your code without JVM terminating the rest when it comes across an exception.
try{
}
catch{
}
finally
{
}
Finally is also very helpful when you always want to execute a block of code irrespective of whether ur scenario is going to pass or fail for example like driver.close().
Hope that helped ... Happy coding :)

How to skip a test and not fail it

In the middle of the test, if the condition of the test is not satisfied, how can I skip the test without failing it.
I try to throw an exception and it is marked as failed.
You will need to use the assume:
org.junit.Assume.assumeTrue(condition());
If this fails your test will be ignored.
I recommend doing this assume in your #Before method
Hope this helps
I think you can use some thing like
try {
///some process
try {
///your middle test
}catch (excetion e){
}
}catch (excetion e){
}
If the middle test is failed the rest will work

Webdriver test pause unexpectedly

I have a Selenium WebDriver based testcase, which pauses during execution. It should upload thousands of files to a website. When it chooses the file to upload it sometimes doesn't click ok, but waits for manual interaction. In most cases it is working perfectly.
I use StringSelection to copy and paste file source to input field.
StringSelection cp = new StringSelection(fileSource);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(cp, null);
I think your test could be running to quickly? If this is the case, then you could potentially use WebDriverWait?? WebDriverWait could be used to wait for the 'OK' element to be visible prior to clicking and therefore proceeding.
I might be wrong, but I can't really tell what the issue is without the rest of the code.
Personally, I use the following method which I can then call
public void waitForElementToBeVisible(String cssSelector) throws Throwable {
try {
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.or(
ExpectedConditions.visibilityOfElementLocated(By.cssSelector(cssSelector))
));
} catch (Exception e) {
System.out.println("Timeout exceeded");
closeDriver();
}
}
For behavior "When it chooses the file to upload it sometimes doesn't click ok, but waits for manual interaction. In most cases it is working perfectly." I prefer use failed retry count. Every step with click should be wrapped up on the test and if test result=failed - retry test some times(3 or 5). JUnit have good mechanizm for that:
#RunWith(Runner.class)
public abstract class AbstractTest extends LibTest {
#Rule
public JUnitRetry retry = new JUnitRetry(3);
}
public class Test extends AbstractTest
#Test
public void testCp(String fileSource){
StringSelection cp = new StringSelection(fileSource);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(cp, null);
}
}
Below code working fine for the similar scenario in our environment.
StringSelection cp = new StringSelection(fileSource);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(cp, null);
Robot robot=new Robot();
robot.keyPress(KeyEvent.VK_ENTER);
robot.keyRelease(KeyEvent.VK_ENTER);
We can also use AutoIT to perform this type actions.
Please find AutoIT code to handle this case.
Download AutoIT ,write this code in AutoIT name it as 'Loadfromdisk' and compile. .exe will be generated, please place exe somwhere in your local drive(ex: E:\Loadfromdisk.exe)
AutoItSetOption("WinTitleMatchMode","2") ;
$title=WinGetTitle("[CLASS:DirectUIHWND; INSTANCE:2]")
WinActivate($title)
WinWaitActive($title)
If WinExists($title) Then
WinFlash($title,"", 4, 500) ;Just to Flash the window
EndIf
Sleep(1000)
ControlSetText($title, "", "Edit1", fileSource)
Sleep(1000)
ControlClick($title,"","Button1")
Exit
Load from disk Selenium Java code, this will load the file placed at 'filesource' path mentioned in AutoIT code into web application
String strAutoIT = "E:\\Loadfromdisk.exe";
Thread.sleep(3000);
String[] astrArg = null;
astrArg=new String[]{strAutoIT};
Runtime.getRuntime().exec(astrArg);
Please see whether this helps to run your testcase.

TestNG - How to force end the entire test suite from the BeforeSuite annotation if a condition is met

Is there a way to quit the entire test suite if a condition is met in the #BeforeSuite annotation? Maybe a way to call the #AfterSuite and bypass the entire test?
I make a database call in the #BeforeSuite. If the query returns any results, I send an email and now am wanting to kill the entire test suite.
I have tried System.exit(1); and org.testng.Assert.fail("There are unpaid invoices");, but neither of those terminate the entire suite. My scripts are setup to run classes in parallel and when I run the test from the test.xml file, each class tries to start and opens a window and then immediately closes it.
FYI, the drivers do not get created until the #BeforeClass or #BeforeMethod (depending on the switch I created for parallel methods or classes). So in all reality, there should never even be an attempt to open a browser window.
try new SkipException("message"); this will skip the tests if the provided condition is not true.
Try the below code in beforesuite annotation method , check if the run mode of your suite is Y/N. if that's N Then throw an Exception
throw new skipException("desired Message")
Please keep it in mind don't catch the skip exception in try and catch block. otherwise it will go for the execution of testcases in that suite after throwing skip Exception
package com.qtpselenium.suiteA;
import org.testng.SkipException;
import org.testng.annotations.BeforeSuite;
import com.qtpselenium.base.TestBase;
import com.qtpselenium.util.TestUtil;
public class TestSuiteBase extends TestBase{
#BeforeSuite
public void checksuiteskip(){
//Initialize method of Test BASE Class to Initialize the logs and all the excel files
try {
Initialize();
} catch (Exception e) {
e.printStackTrace();
}
App_Logs.debug("checking run mode of SuiteA");
if( !TestUtil.isSuiterunnable(suitexlsx, "suiteA")){
App_Logs.debug("Run mode for SuiteA is N");
throw new SkipException("Run mode for suiiteA is N");
}else
App_Logs.debug("Run mode for SuiteA is Y");
}
}

Take screenshot in selenium (java) only in after method

I have created a automation suite in java selenium using testng frame work.Basically in my suite the scenarios are placed in between before and after method.
I want to take the screen shot for each failed and passed test scenario.For that i have created a separate class and calling it in each script to capture the screenshot before the after Method.
The issue that i am facing here is if the scenario is getting failed the script stopped executing and it is not moving to the take screenshot line of code and so it is not capturing the screenshot for the failed ones.
So i want the take screenshot program to be only placed in after method so before the driver quit it will take the screenshot inspite of the scenario result of pass/fail.
I have written code for nearly 20 scenario using testng.
Can some one tel me the code in the after method only to take the screenshot without so much effecting the code which i have written.
The screenshot program should only be in the after method so it will capture teh screen before driver quit.
Make sure you catch exceptions so you won't exit the code prematurely.
For example, this is how I take screenshots after every test run (passed or failed). I use the exception value (if any) to dynamically name the screenshot files.
First, an example test method:
[DataSource("System.Data.SqlClient", "Data Source=DEV338\\X2B;Initial Catalog=SeleniumDb;Integrated Security=True",
"dbo.F_single_ErkenningAannemerKlasse1", DataAccessMethod.Sequential), TestMethod]
public void erkenningAannemerKlasse1()
{
try
{
frontUser.erkenningAannemerKlasse1(data);
}
catch (Exception e)
{
exception = e.Message + " " + e.StackTrace;
}
}
Then this method executes after every test. Default behaviour in Microsoft UnitTest framework, in this case.
[TestCleanup()]
public void Cleanup()
{
frontUser.takeScreenshot(data.get("testnaam"), data.get("datarow"), exception);
frontUser.closeBrowser();
}

Categories