Test is not getting failed incase any action method fails to execute - selenium & TestNG - selenium

In my framework - , Test & PageObjModel classes are there. incase any method is not executed because of wrong xpath or other any issue the Test is terminating but in the Report-Console it is showing all the Testcase are PASS.
Any issue in the Action methods of PageObjModel, some times it will skip that particular line of code and continue execution. sometimes entire test is terminating. in both the case Report-Console it is showing all the Testcase are PASS i.e No failures of Testcases.
Please have a look into below example of code and suggest me to fail the TC incase of failures.
I tried to include Assert.fail(), Assert.true(fail) in the "catch" block, though it is showing PASS results.
PageObjModel:
class A{
// list of xpaths
public static fibal String Login_xpath = "//*[#id='login'];
public void login(){
try{
// All Action methods are define here
}catch (Exception e){
e.printStackTrace();
//Assert.assertTrue(false);
Assert.fail();
} } }
Test class:
#Test
public void loginTest(){
//calling methods
xx.login();
}
This is just sample code. please help me where can I put Assertions to fail the TC when failure occurs in the code

If we are using try-catch in your code, please add throw as well. otherwise, it won't inform testng about the failure.
catch (AssertionError e) {
e.printStackTrace();
takeSnapShot(action);
throw e;
}

Related

How to write a test case method having System.exit() using Junit 5?

Scenario: Below negative scenario to be tested during Integration test. currently the test case getting failed due exit and not reaching to the test method.
example :
private void method1(int a){
try{
if(a == 0){
throw exception();
}else{
---
}
}catch(exceptionclass e){
System.exit(1);
}
}
Sound like a bad smell to me that calling a method on a object can cause JVM to exist. Normally it should be done in the main method.
So I would refactor your codes such that your testing object will throw a kind of Exception to indicate that some kind of fatal error happens such that the main method can catch it and terminate the JVM.
Then you can simply test that if it will throw this Exception from your test case.

Trying to Integrate Extent reports with Selenium WebDriver Event Listener

I am trying to integrate the Extent Reports with Selenium WebDriver Event listeners so that after every action (like navigateTo, clickon, elementChangeValue, etc) the logs get added to the extent report for every action and exceptions. Any thoughts on how can I achieve this since I think I cant pass the EventTest object as a parameter in extended/implemented WebDriverEventListener's methods.
I don't know if that is possible but you can create you own methods for navigateTo, clickon, elementChangeValue, etc and add the actions like steps in the extent report.
For example:
public void navigateTo(String url) throws Exception {
driver.get(url);
try {
driver.findElement(By.className("some_element_in_page"));
TestListener.getExtentTest().log(Status.INFO, "Login successful");
} catch (Exception e) {
TestListener.getExtentTest().log(Status.FAIL, "Login failed");
}
}
Here is a tutorial that might help you.

Report showing as Pass though i intenationally failed it in beforemethod

In my below code - Report always show testcase as Pass though i failed the testcase at BeforeMethod. Please help me to fix this problem
public class practice extends Test_CommonLib {
WebDriver driver;
ExtentReports logger;
String Browser="FireFox";
#BeforeMethod
public void setUp() throws Exception{
logger=eno_TestResport(this.getClass().getName(),Browser);
logger.startTest(this.getClass().getSimpleName());
Assert.assertTrue(false); //intentionally failing my BeforeMethod
}
#Test
public void CreateObject() throws Exception{
System.out.println("Test");
}
#AfterMethod(alwaysRun=true)
public void tearDown(ITestResult result) throws Exception{
if (ITestResult.FAILURE==result.getStatus()) {
logger.log(LogStatus.FAIL, "Test case failed");
}else if(ITestResult.SKIP==result.getStatus()){
logger.log(LogStatus.SKIP, "Test case skipped");
}else {
logger.log(LogStatus.PASS, "Aweosme Job");
}
}
}
with the same code i got result as given below:-
Well, what you are observing is correct. When an Assertion fails the rest of the code is not executed. The same is happening in your case as well. Irrespective of your Assertion whether it passes/fails driver is no more executing any code within that method & straightly comes out of #BeforeMethod Annotation and moves to the methods under #Test Annotation.
Further, your report will always show Testcase as "Pass" as your Testcase within #Test Annotation will successfully execute.
#AnandKakhandaki Here you need to follow certain guidelines of TestNG following this page - https://www.tutorialspoint.com/testng/testng_basic_annotations.htm
It is worth mentioning that, the piece of code within BeforeMethod Annotation will be executed everytime before executing any method. Likewise for BeforeSuite, BeforeClass, BeforeTest & BeforeGroups. Similarly, the piece of code within AfterMethod Annotation will be executed everytime after executing any method. Likewise for AfterSuite, AfterClass, AfterTest & AfterGroups. The code within these mentioned Annotation should be used to configure the Application aka System under test before and after the actual test execution begins/ends. These Annotation may include code for choosing the browser for test execution, opening/closing the browser with certain attributes, opening a url, switch to other url, closing the url, etc which are mandatory configurations to run the test execution.
Validation/Verification or Assertion should never be part of these Annotations. Rather, Assertions should be within Test Annotation. To be precise, Assertions should be kept out of Test Annotation as well, in a separate library. So your code with in Test Annotation contains only Testing Steps.
Let me know if this answers your question.

Testng report assert and continue test

I'm trying to us testng with fluentlenium, and report it to extent reports.
The problem is that I have asserts throughout the tests and want to report them without using try and catch.
Any ideas how to do it? Is there a assert listener or something?
What I did to do something like this ( I take screenshots on every assert failure ) is wrap the SoftAssert class like so:
import org.testng.asserts.IAssert;
public class SoftAssert extends org.testng.asserts.SoftAssert {
#Override
public void onAssertFailure(IAssert<?> assertCommand, AssertionError ex) {
LOGGER.log(Level.FATAL, assertCommand.getMessage());
//doReportingStuffHere
super.onAssertFailure(assertCommand, ex);
}
}
Now every time your soft assertion fails (while it happens, not just at the end) you can do your report stuff.
You can use SoftAssert of implement IAssert on your own

A central location for catching throwables of JUnit tests?

I would like to catch any throwable during a Selenium test e.g. in order to make a screenshot. The only solution I could come up with for now is to separately surround the test steps with a try and catch block in every test method as following:
#Test
public void testYouTubeVideo() throws Throwable {
try {
// My test steps go here
} catch (Throwable t) {
captureScreenshots();
throw t;
}
}
I'm sure there is a better solution for this. I would like a higher, more centralized location for this try-catch-makeScreenshot routine, so that my test would be able to include just the test steps again. Any ideas would be greatly appreciated.
You need to declare a TestRule, probably a TestWatcher or if you want to define the rules more explicitly, ExternalResource. This would look something like:
public class WatchmanTest {
#Rule
public TestRule watchman= new TestWatcher() {
#Override
protected void failed(Description d) {
// take screenshot here
}
};
#Test
public void fails() {
fail();
}
#Test
public void succeeds() {
}
}
The TestWatcher anonymous class can of course be factored out, and just referenced from the test classes.
I solved a similar problem using Spring's AOP. In summary:
Declare the selenium object as a bean
Add an aspect using
#AfterThrowing
The aspect can take the screenshot and save it to a
file with a semirandom generated name.
The aspect also rethrows the exception, with the exception message including the filename so you can look at it afterwards.
I found it more helpful to save the HTML of the page due to flakiness of grabbing screenshots.