0

When I run my Selenium script, the assertion method I use sorta works. When the assertion is met (element is present), the script writes to an xls file. When it is not met, the script does not write to the xls file, and it it stops the test right there.

try {
                assertEquals(driver.findElement(By.xpath(prop.getProperty("failedlogin"))).getText(), "LOG IN");
                //add pass entry to the excel sheet
                testresultdata.put("4", new Object[] {
                    3d, "User should not be able to login with no password", "Login failed", "Pass"
                });
            } catch (Exception e) {
                //add fail entry to the excel sheet
                testresultdata.put("4", new Object[] {
                    3d, "User should not be able to login with no password", "Login failed", "Fail"
                });
            }

Here are my excel writer methods:

@BeforeClass(alwaysRun = true)
    public void setupBeforeSuite(ITestContext context) throws IOException {
        //create a new work book
        workbook = new HSSFWorkbook();
        //create a new work sheet
        sheet = workbook.createSheet("Test Result");
        testresultdata = new LinkedHashMap < String, Object[] > ();
        //add test result excel file column header
        //write the header in the first row
        testresultdata.put("1", new Object[] {
            "Test Step Id", "Action", "Expected Result", "Actual Result"
        });

    }

And:

@AfterClass
    public void setupAfterSuite(ITestContext context) {
        //write excel file and file name is TestResult.xls 
        Set < String > keyset = testresultdata.keySet();
        int rownum = 0;
        for (String key: keyset) {
            Row row = sheet.createRow(rownum++);
            Object[] objArr = testresultdata.get(key);
            int cellnum = 0;
            for (Object obj: objArr) {
                Cell cell = row.createCell(cellnum++);
                if (obj instanceof Date) cell.setCellValue((Date) obj);
                else if (obj instanceof Boolean) cell.setCellValue((Boolean) obj);
                else if (obj instanceof String) cell.setCellValue((String) obj);
                else if (obj instanceof Double) cell.setCellValue((Double) obj);
            }
        }
        try {
            FileOutputStream out = new FileOutputStream(new File("C:/Users/matt_damon/workspace/project/passfail.xls"));
            workbook.write(out);
            out.close();
            System.out.println("Excel written successfully..");

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

So why, even when I purposely make my test fail, does the excel writer not write the fail entry?

jagdpanzer
  • 693
  • 2
  • 10
  • 35

2 Answers2

4

Check what aseertEquals() actually does. Most probably it throws java.lang.AssertionError, which is not subclass of java.lang.Exception.

That's at least what JUnit's Assert.assert*() methods do.

Jiri Tousek
  • 12,211
  • 5
  • 29
  • 43
  • In that case I'd have to catch `AssertionError`, right? My understanding is that try/catch is kind of like if/else, only catch is more geared towards exceptions and what not. Correct me if I'm wrong. – jagdpanzer Oct 23 '15 at 14:24
  • 1
    That would work, yes. Using it as an if/else is not a good idea though! It is suited for exceptional situations, where the execution needs to be aborted and a corrective action taken. Also, throwing and catching an exception is *very* slow compared to if/else - think 100 times slower. http://stackoverflow.com/questions/299068/how-slow-are-java-exceptions – Jiri Tousek Oct 23 '15 at 14:28
  • And in your example I'd definitely use if/else. – Jiri Tousek Oct 23 '15 at 14:29
1

In test frameworks there are listeners you use to include actions after an assert.

Depending on which test framework you use, there are different implementations. But I assume you use JUnit. (If you can change to TestNG, much easier and better)

Credit this to MEMORYNOTFOUND at JUnit Listener

JUnit Listener

These are the options for where the listener can intercept test reesults. These include a lot of information such as name of the test case. Since you want to pass information, you have to add it to the message and in the listener parse the information you need.

package com.memorynotfound.test;

import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;

public class JUnitExecutionListener extends RunListener {

  public void testRunStarted(Description description) throws Exception {
      System.out.println("Number of tests to execute: " + description.testCount());
  }

  public void testRunFinished(Result result) throws Exception {
      System.out.println("Number of tests executed: " + result.getRunCount());
  }

  public void testStarted(Description description) throws Exception {
      System.out.println("Starting: " + description.getMethodName());
  }

  public void testFinished(Description description) throws Exception {
      System.out.println("Finished: " + description.getMethodName());
  }
  //This function will print your message added to the assert
  public void testFailure(Failure failure) throws Exception {
      System.out.println("Failed: " + failure.getMessage());
  }

  public void testAssumptionFailure(Failure failure) {
      System.out.println("Failed: " +  failure.getDescription().getMethodName());
  }

  public void testIgnored(Description description) throws Exception {
      System.out.println("Ignored: " + description.getMethodName());
  }
}

JUnit Runner The listener has to be added to the test execution.

package com.memorynotfound.test;

import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;

public class MyRunner extends BlockJUnit4ClassRunner {

    public MyRunner(Class<?> klass) throws InitializationError {
        super(klass);
    }

    @Override public void run(RunNotifier notifier){
        notifier.addListener(new JUnitExecutionListener());
        super.run(notifier);
    }
}

JUnit Test case

All test classes which include the annotation @RunWith activates the listener

package com.memorynotfound.test;

import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.assertTrue;

@RunWith(MyRunner.class)
public class RunListenerTest {

    @Test
    public void testListener(){

    }

    @Test
    public void testFalseAssertion(){
        assertTrue("3d, User should not be able to login with no password, Login failed, Fail",false);
    }

    @Ignore
    @Test
    public void testIgnore(){

    }

    @Test
    public void testException(){
        throw new RuntimeException();
    }

}