Expresso builds upon the JUnit testing framework to provide an automated unit testing environment.
Version: |
Expresso 5.x |
Author: |
Michael Rimov, Ivan Ivanov |
JUnit's documentation can be found here. It was necessary to extend JUnit because Expresso applications expect certain system configurations to be available at any given time. These include database configuration, as well, as web-application location (which would normally be gleaned off of the servlet container). Further extensions were needed to be able to run test cases within a servlet container.
To accomplish this, we branched into two areas:
To provide a framework that we can perform client side testing with all standard expresso services such as logging, database connection management, and many others we provide the following class:
com.jcorporate.expresso.services.test.ExpressoTestCase
To create your own test case use the following sample as a model:
import junit.framework.*;
import junit.extensions.*;
import com.jcorporate.expresso.services.test.*;
public class SampleTestSuite extends ExpressoTestCase {
public SampleTestSuite(String name) throws Exception {
super(name);
}
public static void main(String[] args) throws java.lang.Exception {
//Set the system properties we need
junit.textui.TestRunner.run (suite());
}
public static junit.framework.Test suite() {
return new TestSuite(SampleTestSuite.class);
}
public void test1() {
//Do your testing code here
}
public void test2() {
//Do more testing here
}
public void test3() {
//You can do more testing here
}
/*....Do as many test cases as you want, all with the public void signature */
}
To run the test case, Expresso requires that you set the following Java Virtual Machine parameters to
junit.argv.configDir=<Full Path To Your Configuration Directory>
junit.argv.webAppDir=<Full Path To Tomcat's Webapp Directory>
For example, on the command line you will have the following:
-Djunit.argv.configDir=/usr/local/tomcat4/webapps/yourApp/WEB-INF/config -Djunit.argv.webAppDir=/usr/local/tomcat4/webapps/yourApp -Djunit.argv.logDir=/usr/local/tomcat4/webapps/yourApp/WEB-INF/logs
If you extend your test cases from com.jcorporate.expresso.services.test.ControllerTestCase or com.jcorporate.expresso.core.utility.DBToolTests you need add another database context in your expresso-config.xml file called 'test' that should point to your test database. Creating another database for testing your expresso application is recommended since expresso reinitializes it every time the tests are ran an you might lose the data in your development database. Some authors really suggest that you have your test database different from the development one to prevent damaged data among other reasons. While this is a matter of taste and habits, what the Expresso test system requires is that you have set up another context named test and what database it refers to is up to you.
The JUnit framework will automatically use Java Introspection to run all the public(void) test cases. See the JUnit documentation on how to use the framework to signal if a test passed or failed. Also, see the class: com.jcorporate.expresso.core.misc.CookieTests to see a fully functional sample of integration with JUnit Framework.
All expresso test case classes will play well with the JUnit test runners. So if you wish to run a text-based only test case, you can run junit.textui.TextRunner. If you wish to run within a nice graphical environment, you can run your test suite with:
To run all test cases within a graphical environment, run the class:
junit.swingui.TestRunner
use the UI to pick the class you wish to test and let her run.
The -c will determine which test suite to run. You can use your own test cases, or use the class sample above to run all Expresso test cases at once.

Picture of JUnit's Swing Test Runner doing its stuff.
There are a couple of necessary guidelines to follow when writing your own test cases.
When we're first creating our application, we want to make sure it runs correctly, right? But as we're developing our schema, and creating out databases, we have to each time go through the monotonous task of dropping a database, recreating it, starting up Expresso, running DBCreate, etc. This quickly becomes quite a chore. So we've created a special test case for testing Schema Creation. Here's all the code you need. The following example is borrowed directly from eForum and is complete:
import junit.framework.*;
Import com.jcorporate.expresso.services.test.*;
Import com.jcorporate.expresso.core.utility.DBToolTests; public class SchemaTests extends DBToolTests { public SchemaTests(String testName) throws Exception { super(testName); }
public static void main(String[] args) throws Exception {
//Set the system properties we need
junit.textui.TestRunner.run (suite());
}
public static junit.framework.Test suite() throws Exception {
return DBToolTests.suite();
}
protected void setUp() throws Exception {
//System must be initialized prior to instanatiating the schema instance
TestSystemInitializer.setUp();
Class c = Class.forName("com.jcorporate.eforum.ForumSchema");
schemaList.add(c.newInstance());
super.setUp();
}
}
That's it! To make this code work for your schema all you do is change the ONE line in setup() that loads ForumSchema to use your own schema class. When this class is run, it will make sure that all tables are removed from the Test database, and then attempt to create all schemas (Including Expresso's) in the test database. It will also run separately populateDefaultValues() and setupDefaultSecurity() so you can make sure that everything is cooprating.
This kind of testing is an extremely helpful and powerful tool for testing your schemas as you're building them.
The bulk of your web application is going to be logic within an Expresso Controller object, or possibly a standard Servlet. Unfortunately, standard JUnit client-side testing procedures definitely fall flat in being able to cope in this area. Enter Apache's Cactus project.
Cactus was designed to provide the unification of JUnit's client side testing API and in-container server-side testing. What it does is initiate a test case on the client side so you can stuff all the HTTP request parameters with everything you need such as state to request, login cookies, etc. The test case then serializes itself to the server, where a specially designed servlet loads your test class and executes the code on the server side. The result is then sent back to the client side so you can examine cookies sent back to client or other results.
Here is an animation created by the Apache Cactus documentation project that highlights what was said above.

The rest of the cactus documentation set can be found here.
If you are writing a servlet, the Cactus documentation will be sufficient to get you started on a servlet. Even if you're writing a controller test case, it is strongly recommended that you browse through the Cactus website to get an idea of how a Cactus test case is written since the controller test cases are extensions to a standard Cactus test.
If you are writing a controller test harness, there are quite a few things to consider such as having a running underlying database, negotiating security, and parsing the controller response. To assist in this, we've provided the classes:
com.jcorporporate.expresso.services.test.ControllerTestCase
and
com.jcorporate.expresso.services.test.ControllerTestSuite
Below is a sample showing a simple usage of a controller test case (suite). All comments with a number are footnoted/explained in the area below the code sample.
Import com.jcorporate.expresso.services.test.*;
Import com.jcorporate.expresso.core.controller.*;
Import org.apache.commons.cactus.*;
Import org.apache.commons.cactus.util.*;
Import junit.framework.*;
Import org.w3c.dom.*;
Import java.net.HttpURLConnection; import java.io.IOException; import javax.servlet.*; Import java.util.*;
Public class SampleControllerTest extends ControllerTestCase {
public SampleControllerTest(String name) {
super(name, "com.jcorporate.expresso.services.DBSecurityMatrix"); //1
}
public static void main(String[] args) throws Exception {
junit.textui.TestRunner.run(suite()); //2
}
public static TestSuite suite() throws Exception {
ControllerTestSuite cts = new ControllerTestSuite(); //3
cts.addReadOnlySchemaDependency("com.jcorporate.expresso.core.ExpressoSchema"); //4
cts.addTestSuite(SampleControllerTest.class);
return CTS;
}
/* Executed on the client side of the web request */ public void beginPromptState(WebRequest theRequest) throws Exception
{
super.logIn(theRequest); //5
super.setupParameters("prompt",theRequest); //6
}
/* Executed on the server side of the web request */
public void testPromptState() throws Exception {
ControllerResponse response = super.controllerProcess(); //7
assertTrue("Got a null response", response != null);
assertTrue("Title returned from the controller state.",
response.getTitle().length() > 0); //8
}
/*....Do as many test cases as you want, all with the public void signature */
}
<servlet>
<servlet-name>ServletTestRunner<servlet-name>
<servlet-class>org.apache.cactus.server.runner.ServletTestRunner<servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletTestRunner</servlet-name>
<url-pattern>/ServletTestRunner</url-pattern>
</servlet-mapping>
Then start your servlet container and type in the address bar like the following:
http://localhost:8080/yourApp/ServletTestRunner?suite=com.your.package.YourTestCase
where yourApp is the web context of your application (could be blank) and com.your.package.YourTestCase is the fully qualified class name of your test case.
The results of the tests (fails, successes, and stack traces) will appear in your browser in XML format or you can format it according to Cactus' documentation.
Note the 'suite' is a parameter expected by Cactus' ServletTestRunner and that your test cases should be visible to your servlet container.
You can take a look at the class com.jcorporate.expresso.services.controller.test.DBSecurityMatrixTests for a complete working controller test case that tests a couple of states including getting the results of a form POST.
To run the Cactus tests you need the following software pieces.
There is one step that has to be done for Cactus to run properly on your system.
-Djunit.argv.configDir=<Full path to your expresso config directory>
-Djunit.argv.webAppDir=<Full path to the expresso webapp directory>
-Djunit.argv.logDir=<Full path to to where expresso should put log files>
You can run any JUnit test runner for a controller test case including SwingTestRunner for graphical test suites.
It should be noted that to follow Extreme Programming's (XP) unit testing strategies, you will want to chain your test cases together. Check the example of com.jcorporate.expresso.core.ExpressoTestSuite for a clear example of this usage.
Copyright © 2002-2004 Jcorporate
Ltd. All rights reserved. Copyright Privacy
Last Modified:
26-Aug-2003