• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1232
  • Last Modified:

Another Junit logging question.

I hope I can make this succinct as possible.

I am trying to log junit results to a database usinf hibernate. The hibernate is a many to one relational set up. The layout is like this:

I have two tables in my database.

- Summary
- Result

The Summary record gets built when I run a Test Suite. It's an overview of the tests run.

The Results records are the results of each test case I run.

Here is how I build the summary:

   public void runAllTests() {
        try {
            _RootDAO.initialize();
            SessionFactory sessionFactory = new Configuration().configure()
            .buildSessionFactory();
            Session session = sessionFactory.openSession();
            Summary p = new Summary();
            p.setResult(new HashSet());
            p.setCategory("Configuration");
            p.setFirmware(Util.getFirmwareApp());
            p.setInterface("http");
            p.setPowernetMib(Util.getMib());
            java.util.Date now = new java.util.Date();
            p.setTestDate(new java.sql.Timestamp(now.getTime()));
            p.setSsh(Util.getSsh());
            p.setSl(Util.getSsl());
            p.setTester(System.getProperty("user.name"));

            TestResult results = new TestResult();
            TestSuite suite = getTestSuite();
            runTestSuite(suite, results);
            displayResults(results, p);
            session.save(p);
            session.flush();
            session.close();
        } catch (HibernateException e) {
            atelog.error(e);
            e.printStackTrace();
        }
    }

   protected void displayResults(TestResult results, Summary p) {
        atelog.info("Ran " + results.runCount() + " tests");
        p.setTestRun(results.runCount());
        if(results.wasSuccessful()) {
            p.setTestPassed(results.runCount());
            atelog.info("All tests successful");
        }
        else {
            // failures occur when the fail method is invoked within a
            // test method
            atelog.info(results.failureCount() + " Failures");
            p.setTestFailed(results.failureCount());
            p.setTestPassed(results.runCount() - results.failureCount());
            for (Enumeration e = results.failures() ; e.hasMoreElements() ;) {
                atelog.info(e.nextElement());
            }
           
            // errors happen when the test method throws an exception
            // you can get the initial Throwable and interrogate it to
            // retrieve the stack trace
            atelog.info(results.errorCount() + " Errors");
            for (Enumeration e = results.errors() ; e.hasMoreElements() ;) {
                TestFailure failure = (TestFailure) e.nextElement();
                atelog.info(failure);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                PrintStream ps = new PrintStream(baos);
                Throwable t = failure.thrownException();
                t.printStackTrace(ps);
                atelog.info(baos);
            }
        }
    }

So, when I run "runAllTests", it get's the suite and runs the test, and starts the summary record. When all the tests are complete in the test suite, it tallies the passes, fails, and total run and puts them into the database.

Now, my results, the results has has to be built in the actual test case. I do not know how to pass that result back to the runAllTests so I can add it to the summary:

p.getResult().add(result);

What Iw as thinking, is that in my test class, There could be a method that builds the result hash based on the test method. Is that possible? Here is what I have now:

    public void testDeviceInfo() throws Exception {
        Result r = new Result();
        try {

            r.setScript(this.getName());
            String comment = null;
           
            //atelog.debug(this.getName());
           
            //New Web Conversation
            WebConversation wc = new WebConversation();

            //Web Response
            WebResponse resp = wc.getResponse(Util.getLoginUrl());

            //Get the Login Form
            WebForm form = resp.getForms()[0];

            //Set the form username and password
            form.setParameter("login_username", Util.getUsername());
            comment = "Logging in with username: " + Util.getUsername() + "\n";
            form.setParameter("login_password", Util.getPassword());
            comment = comment + "Logging in with password: " + Util.getPassword() + "\n";
           
            //Submit the form
            form.submit();

            //Now check to see if you can access the main URL
            resp = wc.getResponse(Util.getMainIndex());

            //Assert that the login worked
            if (resp.getText().indexOf("Updated:") != -1) {
                fail("Did not login or find the main index");
                r.setResult("fail");
            } else {
                atelog.debug("Logged in properly");
            }

            WebLink admin = resp.getLinkWith(LinkConstants.LINK_ADMIN);
            if (admin.equals(null)) {
                fail("Could not find the admin link");
                r.setResult("fail");
            } else {
                atelog.debug("Found Admin Link");
                resp = admin.click();
            }
           
            WebLink general = resp.getLinkWith(LinkConstants.LINK_GEN);
            if(general.equals(null)) {
                fail("Could not find General link");
                r.setResult("fail");
            } else {
                atelog.debug("Found General Link");
                resp = general.click();
            }
           
            WebLink iden = resp.getLinkWith(LinkConstants.LINK_IDEN);
            if (iden.equals(null)) {
                fail("Could not find Identification link");
                r.setResult("fail");
            } else {
                atelog.debug("Found Identification Link");
                resp = iden.click();
            }

            WebForm ident = resp.getForms()[0];
            if (ident.equals(null)) {
                fail("Could not find Identification form");
                r.setResult("fail");
            } else {
                atelog.debug("Found System Info Form");
                ident.setParameter(FieldConstants.FIELD_SYSIDEN,
                        ValueConstants.VALUE_SYSIDEN);
                atelog.info("Setting System Name: " + ValueConstants.VALUE_SYSIDEN);
                ident.setParameter(FieldConstants.FIELD_SYSCONT,
                        ValueConstants.VALUE_SYSCONT);
                atelog.info("Setting System Contact: "
                        + ValueConstants.VALUE_SYSCONT);
                ident.setParameter(FieldConstants.FIELD_SYSLOC,
                        ValueConstants.VALUE_SYSLOC);
                atelog.info("Setting System Location: "
                        + ValueConstants.VALUE_SYSLOC);
                ident.submit();
            }
           
            //request the main index again
            resp = wc.getResponse(Util.getMainIndex());
           
            if (resp.getText().indexOf("Updated:") != -1) {
                fail("Did not login or find the main index");
                r.setResult("fail");
            } else {
                atelog.debug("got the Main Index");
            }

            admin = resp.getLinkWith(LinkConstants.LINK_ADMIN);
            if (admin.equals(null)) {
                fail("Could not find the admin Link");
                r.setResult("fail");
            } else {
                atelog.debug("Found Admin Link");
                resp = admin.click();
            }
           
            general = resp.getLinkWith(LinkConstants.LINK_GEN);
            if(general.equals(null)) {
                fail("Could not find General Link");
                r.setResult("fail");
            } else {
                atelog.debug("Found General Link");
                resp = general.click();
            }
           
            iden = resp.getLinkWith(LinkConstants.LINK_IDEN);
            if (iden.equals(null)) {
                fail("Could not find Identification Link");
                r.setResult("fail");
            } else {
                atelog.debug("Found Identification Link");
                resp = iden.click();
            }


            ident = resp.getForms()[0];
            if (ValueConstants.VALUE_SYSIDEN != ident.getParameterValue(FieldConstants.FIELD_SYSIDEN)) {
                fail("Did not set System Name properly");
                r.setResult("fail");
            } else {
                atelog.info("System Name Set: " + ValueConstants.VALUE_SYSIDEN);
            }
            if (ValueConstants.VALUE_SYSCONT != ident.getParameterValue(FieldConstants.FIELD_SYSCONT)) {
                fail("Did not set System Contact properly");
                r.setResult("fail");
            } else {
                atelog.info("System Contact Set: " + ValueConstants.VALUE_SYSCONT);
            }
            if (ValueConstants.VALUE_SYSLOC != ident.getParameterValue(FieldConstants.FIELD_SYSLOC)) {
                fail("Did not set System Location properly");
                r.setResult("fail");
            } else {
                atelog.info("System Location Set: " + ValueConstants.VALUE_SYSLOC);
            }
           
            //Find the logout image
            WebImage image = resp.getImageWithSource("images/exit.gif");
            if (image.equals(null)) {
                fail("Could not find logout image");
                r.setResult("fail");
            } else {
                atelog.debug("Found Logout Image");
            }

            //Find the logout link associated with the image
            WebLink findLogoutLink = image.getLink();
            if (findLogoutLink.equals(null)) {
                fail("could not find logout link");
                r.setResult("fail");
            } else {
                atelog.debug("Found Logout Link");
                resp = findLogoutLink.click();
            }

            if (resp.getText().indexOf("You are now logged off.") != -1) {
                atelog.info("Successfully logged out");
                r.setResult("pass");
                Date now = new Date();
                r.setTimestamp(new java.sql.Timestamp(now.getTime()));
            } else {
                fail("Did not Log out");
                r.setResult("fail");
                Date now = new Date();
                r.setTimestamp(new java.sql.Timestamp(now.getTime()));
            }
            r.setComment(comment);
         
        } catch (Exception e) {
            fail(e.getMessage());
            atelog.error(e.getMessage());
        }
    }

note my result hash is r.

also, if I have several test methods in this one class, each one needs to be it's own result has, and I should be able to add each one back to the parent summary.

You can see how this is relational in the database, each result is the child of a summary, so it has to be added to the summary before I save the session and flush it.

Any and all advice is welcome.

Thank you.
0
k41d3n
Asked:
k41d3n
  • 3
  • 2
1 Solution
 
aozarovCommented:
>> protected void displayResults(TestResult results, Summary p) {
I assume, based on "p.setResult(new HashSet());" that Summary is associated with 1 to many relation to some POJO that describe a TestResult or TestFailure, right?
If so then you can add those results for each individual test inside displayResults by calling p.getResult().add(result); where result represent the related result/faluire.
Isn't that what you are looking for?
0
 
k41d3nAuthor Commented:
Ok, I got it to work for a singular test. What I did was this:

I created a separate class just to be the interpreter between the TestSuite and the TestCase, it looks like this:

/*
 * Created on May 9, 2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package com.apc.qa.ate.test.http;

import java.sql.Timestamp;
import java.util.Date;

import com.apc.qa.ate.Result;
import com.apc.qa.ate.Summary;

/**
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 *
 * @author marcadam
 **/
public class TestResults {
   
    static String script = null;
    static String result = null;
    static String comment = null;
    static Timestamp timestamp = null;
    static Summary summary = null;
   
   
    /**
     * @return Returns the summary.
     */
    public static Summary getSummary() {
        return summary;
    }
    /**
     * @param summary The summary to set.
     */
    public static void setSummary(Summary summary) {
        TestResults.summary = summary;
    }
    /**
     * @return Returns the comment.
     */
    public static String getComment() {
        return comment;
    }
    /**
     * @param comment The comment to set.
     */
    public void setComment(String comment) {
        TestResults.comment = comment;
    }
    /**
     * @return Returns the result.
     */
    public static String getResult() {
        return result;
    }
    /**
     * @param result The result to set.
     */
    public void setResult(String result) {
        TestResults.result = result;
    }
    /**
     * @return Returns the script.
     */
    public static String getScript() {
        return script;
    }
    /**
     * @param script The script to set.
     */
    public void setScript(String script) {
        TestResults.script = script;
    }
    /**
     * @return Returns the timestamp.
     */
    public static Date getTimestamp() {
        return timestamp;
    }
    /**
     * @param timestamp The timestamp to set.
     */
    public void setTimestamp(Timestamp timestamp) {
        TestResults.timestamp = timestamp;
    }

    public static Result testResults() {
        Result r = new Result();
       
        r.setComment(getComment());
        r.setResult(getResult());
        r.setScript(getScript());
        r.setTimestamp(getTimestamp());
        r.setSummary(AllHttpTests.getSummary());
        return(r);
    }

}

In my actual test I have this:

   public void testQuickLinks() throws Exception {
        TestResults tr = new TestResults();
        Date now = new Date();
        String result = "pass";
        try {
           
            tr.setScript(this.getName());
           
            String comment = null;
           
           
            //New Web Conversation
            WebConversation wc = new WebConversation();

            //Web Response
            WebResponse resp = wc.getResponse(Util.getLoginUrl());

            //Get the Login Form
            WebForm form = resp.getForms()[0];

            //Set the form username and password
            form.setParameter("login_username", Util.getUsername());
            comment = "Logging in with username: " + Util.getUsername() + "\n";
            form.setParameter("login_password", Util.getPassword());
            comment = comment + "Logging in with password: " + Util.getPassword() + "\n";

            //Submit the form
            form.submit();

            //Now check to see if you can access the main URL
            resp = wc.getResponse(Util.getMainIndex());

            //Assert that the login worked
            assertTrue("Login not accepted",
                    resp.getText().indexOf("Updated:") != -1);

            //Log the login only if you are logged in
            atelog.info("Logged in properly");

            WebLink admin = resp.getLinkWith(LinkConstants.LINK_ADMIN);
            assertNotNull("Couldn't Find Admin Link", admin);
            atelog.debug("Found Admin Link");
            resp = admin.click();
            WebLink general = resp.getLinkWith(LinkConstants.LINK_GEN);
            assertNotNull("Couldn't Find General Link", general);
            atelog.debug("Found General Link");
            resp = general.click();
            WebLink quickLink = resp.getLinkWith(LinkConstants.LINK_QUICKLINKS);
            assertNotNull("Couldn't Find Identification Link", quickLink);
            atelog.debug("Found Quick Links");
            resp = quickLink.click();

            WebForm ident = resp.getForms()[0];
            assertNotNull("Couldn't Find Quick Link Form", ident);
            atelog.debug("Found Quick Link Form");
            ident.setParameter(FieldConstants.FIELD_QLDIS1,
                    ValueConstants.VALUE_QLDIS1);
            atelog.info("Setting Quick Link Display: "
                    + ValueConstants.VALUE_QLDIS1);
            ident.setParameter(FieldConstants.FIELD_QLNAME1,
                    ValueConstants.VALUE_QLNAME1);
            atelog.info("Setting Quick Link Display: "
                    + ValueConstants.VALUE_QLNAME1);
            ident.setParameter(FieldConstants.FIELD_QLURL1,
                    ValueConstants.VALUE_QLURL1);
            atelog.info("Setting Quick Link URL: "
                    + ValueConstants.VALUE_QLURL1);
            ident.submit();

            resp = wc.getResponse(Util.getMainIndex());

            admin = resp.getLinkWith(LinkConstants.LINK_ADMIN);
            assertNotNull("Couldn't Find Admin Link", admin);
            atelog.debug("Found Admin Link");
            resp = admin.click();
            general = resp.getLinkWith(LinkConstants.LINK_GEN);
            assertNotNull("Couldn't Find General Link", general);
            atelog.debug("Found General Link");
            resp = general.click();
            quickLink = resp.getLinkWith(LinkConstants.LINK_QUICKLINKS);
            assertNotNull("Couldn't Find Quick Links", quickLink);
            atelog.debug("Found Quick Links");
            resp = quickLink.click();

            ident = resp.getForms()[0];
            atelog.debug("Found Quick Link Form");
            assertEquals(ValueConstants.VALUE_QLDIS1, ident
                    .getParameterValue(FieldConstants.FIELD_QLDIS1));
            assertEquals(ValueConstants.VALUE_QLNAME1, ident
                    .getParameterValue(FieldConstants.FIELD_QLNAME1));
            assertEquals(ValueConstants.VALUE_QLURL1, ident
                    .getParameterValue(FieldConstants.FIELD_QLURL1));
            atelog.info("Quick Link Display Set: "
                    + ValueConstants.VALUE_QLDIS1);
            atelog.info("Quick Link Name Set: " + ValueConstants.VALUE_QLNAME1);
            atelog.info("Quick Link URL Set: " + ValueConstants.VALUE_QLURL1);

            //Find the logout image
            WebImage image = resp.getImageWithSource("images/exit.gif");
            assertNotNull("Couldn't Find Logout Image", image);
            atelog.debug("Found Logout Image");

            //Find the logout link associated with the image
            WebLink findLogoutLink = image.getLink();
            assertNotNull("Couldn't Find Logout Link", findLogoutLink);
            atelog.debug("Found Logout Link");

            //click the link
            resp = findLogoutLink.click();

            assertNotNull("Finding Logout Page", resp);
            assertTrue("Couldn't Log Out", resp.getText().indexOf(
                    "You are now logged off.") != -1);
            atelog.info("Successfully logged out");
            tr.setResult(result);
            tr.setComment(comment);
            tr.setTimestamp(new java.sql.Timestamp(now.getTime()));
        } catch (Exception e) {
            result = "fail";
            tr.setResult(result);
            fail(e.getMessage());
            atelog.error(e.getMessage());
        }
    }

And finally the AllTests that runs the tests:

/*
 * Created on May 6, 2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package com.apc.qa.ate.test.http;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;

import junit.framework.TestFailure;
import junit.framework.TestResult;
import junit.framework.TestSuite;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.cfg.Configuration;

import org.apache.log4j.Logger;

import com.apc.qa.ate.Summary;
import com.apc.qa.ate.dao._RootDAO;
import com.apc.qa.ate.util.Util;

/**
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 *
 * @author marcadam
 **/
public class AllHttpTests extends TestSuite {
    /**
     * Logger for this class
     */
    private static final Logger atelog = Logger.getLogger(AllHttpTests.class);
   
    static Summary summary = null;
    static Map resultMap = new HashMap();
   
    /**
     * @return Returns the resultMap.
     */
    public static Map getResultMap() {
        return resultMap;
    }
    /**
     * @param resultMap The resultMap to set.
     */
    public void setResultMap(Map resultMap) {
        AllHttpTests.resultMap = resultMap;
    }
    /**
     * @return Returns the summary.
     */
    public static Summary getSummary() {
        return summary;
    }
    /**
     * @param summary The summary to set.
     */
    public void setSummary(Summary summary) {
        AllHttpTests.summary = summary;
    }
    protected TestSuite getTestSuite() {
       
        TestSuite suite;
        suite = new TestSuite("AllHttpUnitTests");
        suite.addTestSuite(DeviceIdentification.class);
        return suite;
    }
   
    /**
     * Creates a TestSuite by going through each of the classes
     * in the testCaseClasses array and adding them to a TestSuite.
     * @return a TestSuite with all test classes or an empty TestSuite
     * if no test classes are specified.
     */
    /*  protected TestSuite getTestSuite() {
     TestSuite suite = new TestSuite();
     for(int i = 0; i < testCaseClasses.length; i++) {
     suite.addTest(new TestSuite (testCaseClasses[i]));
     }
     return suite;
     }*/
   
    public static void main(String args[])
    {
        String args2[] = {"-noloading", "AllHttpUnitTests"};
       
        junit.swingui.TestRunner.main(args2);
    }
   
    /**
     * Runs all the test classes specified in the testCaseClasses array.
     * Gets the TestSuite to run, then runs the tests and finally
     * displays the results.
     */
    public void runAllTests() {
        try {
            _RootDAO.initialize();
            SessionFactory sessionFactory = new Configuration().configure()
            .buildSessionFactory();
            Session session = sessionFactory.openSession();
            Summary p = new Summary();
            p.setResult(new HashSet());
            p.setCategory("Configuration");
            p.setFirmware(Util.getFirmwareApp());
            p.setInterface("http");
            p.setPowernetMib(Util.getMib());
            java.util.Date now = new java.util.Date();
            p.setTestDate(new java.sql.Timestamp(now.getTime()));
            p.setSsh(Util.getSsh());
            p.setSl(Util.getSsl());
            p.setTester(System.getProperty("user.name"));
           
            TestResult results = new TestResult();
            TestSuite suite = getTestSuite();
            runTestSuite(suite, results);
            displayResults(results, p);
            summary = p;
            p.getResult().add(TestResults.testResults());
            //getResultHash(p);
            session.save(p);
            session.flush();
            session.close();
        } catch (HibernateException e) {
            atelog.error(e);
            e.printStackTrace();
        }
    }
   
   
    /**
     * Runs the test suite
     * @param TestResults results: all results are placed within this object
     * @param TestSuite suite: the suite of tests to run
     */
    protected void runTestSuite(TestSuite suite, TestResult results) {
        suite.run(results);
    }
   
    /**
     * Prints out the status of the results (successful/unsuccessful).
     * If there are errors or failures more detailed error messages are
     * printed giving the stack trace.
     * @param TestResults results: the results to use.
     */
    protected void displayResults(TestResult results, Summary p) {
        atelog.info("Ran " + results.runCount() + " tests");
        p.setTestRun(results.runCount());
        if(results.wasSuccessful()) {
            p.setTestPassed(results.runCount());
            atelog.info("All tests successful");
        }
        else {
            // failures occur when the fail method is invoked within a
            // test method
            atelog.info(results.failureCount() + " Failures");
            p.setTestFailed(results.failureCount());
            p.setTestPassed(results.runCount() - results.failureCount());
            for (Enumeration e = results.failures() ; e.hasMoreElements() ;) {
                atelog.info(e.nextElement());
            }
           
            // errors happen when the test method throws an exception
            // you can get the initial Throwable and interrogate it to
            // retrieve the stack trace
            atelog.info(results.errorCount() + " Errors");
            for (Enumeration e = results.errors() ; e.hasMoreElements() ;) {
                TestFailure failure = (TestFailure) e.nextElement();
                atelog.info(failure);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                PrintStream ps = new PrintStream(baos);
                Throwable t = failure.thrownException();
                t.printStackTrace(ps);
                atelog.info(baos);
            }
        }
    }


When the test suite is run, it builds the parent record, then proceeds to run the test cases in the second class, the test cases build the TestResults method, and then gets the parent record from the AllHttpTests class and adds the summary (parent) to the result.

this inserts the record properly.

Now th eproblem is this:

If I have more than one test in a class, can I build a hash of hash's that I can iterate through for adding them properly?

This is getting so convoluted, my own code confuses me!

0
 
aozarovCommented:
>>I created a separate class just to be the interpreter between the TestSuite and the TestCase, it looks like this:
Not sure how you connect the TestResults to your to your TestSuite, but in anycase you can instead provide to the TestSuite your own subclass of junit.framework.TestResult
then in that subclass "record" all the tests (startTest/endTest/failures) and then you can use it to return your own Result objects to associate with Summary. Isn't that simpler?
That "recording" can be done on Test function level as each call to startTest/endTest is done specific method on a specific class. [ use ((TestCase) test).getName() ]
0
 
k41d3nAuthor Commented:
I got it working.

I created a hash of results, and built the hash from the results from each test, then I iterate through that hash and add each one to the parent record.

Thanks for your help.
0
 
aozarovCommented:
NP. :-)
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now