Designing JSPs to be testable outside of a running server.
7.16.2 Solution
Write your JSPs to use helper classes that do not depend on a running server, and then test those helper classes with JUnit.
7.16.3 Discussion
Testing server code is challenging, as we have seen throughout this chapter. JSPs pose a greater risk of failure because multiple technologies are intermingled. JSPs mix snippets of Java code with snippets of HTML, XML, JSTL, and JavaBeans; add the deployment of JSP and the problems of testing only get worse. A better approach to designing and testing JSPs is to write support classes that do not depend on a running server to perform logic. These support classes can then be tested outside of a running server using JUnit.
7.16.4 See Also
Recipe 7.15 discusses testing non-server-dependent classes.
Chapter 8. JUnitPerf
Section 8.1. Introduction
Section 8.2. When to Use JUnitPerf Section 8.3. Creating a Timed Test
Section 8.4. Creating a LoadTest
Section 8.5. Creating a Timed Test for Varying Loads Section 8.6. Testing Individual Response Times Under Load Section 8.7. Running a TestSuite with Ant
Section 8.8. Generating JUnitPerf Tests
8.1 Introduction
Performance issues inevitably sneak into a project. Tracking down the issues is troublesome without the proper tools. Commercial performance-monitoring tools, such as JProbe or OptimizeIt, help pinpoint performance problems. These tools excel at providing performance metrics but typically require expert human intervention to run and interpret the results. These tools are not designed to execute automatically as part of a continuous integration process—which is where JUnitPerf enters the picture.
JUnitPerf, available from http://www.clarkware.com/software/JUnitPerf.html, is a tool for continuous performance testing. JUnitPerf transparently wraps, or decorates existing JUnit tests without affecting the original test.[1] Remember that JUnit tests should execute quickly. Figure 8-1 shows the UML diagram for the JUnitPerf
TimedTest
.[1] For more information on the decorator pattern refer to Design Patterns: Elements of Reusable Object-
Oriented Software (Addison-Wesley) by Erich Gamma, et al.
JUnitPerf tests can (and should) be executed separately from normal JUnit tests. This approach ensures that the overall execution of JUnit tests isn't hindered by the additional time spent executing JUnitPerf tests.
Here's a quick overview of how a JUnitPerf timed test works. The following occurs when a JUnitPerf
TimedTest.run(TestCase)
method is invoked:1. Retrieve the current time (before JUnit test execution).
2. Call
super.run(TestResult)
to run the JUnit test, wheresuper
refers to the JUnitTestDecorator
.3. Retrieve the current time (after JUnit test execution).
4. If the elapsed time turns out to be greater than the maximum allowed time, then a
junit.framework.AssertionFailedError(String)
is thrown. Otherwise, the test passes.8.2 When to Use JUnitPerf
8.2.1 Problem
You want to track down potential performance and scalability problems but are unsure of the tools you need.
8.2.2 Solution
Use a commercial profiling tool, such as JProbe or OptimizeIt, to manually inspect code and identify application bottlenecks. Use JUnitPerf to ensure that new features and refactoring do not slow down code that used to be fast enough.
8.2.3 Discussion
JUnitPerf is a tool for continuous performance testing. The goal of a performance test is to ensure that the code executes fast enough, even under varying load conditions. Let's take a look at a typical scenario.
You just completed a custom search algorithm, complete with a suite of JUnit tests. Next, the code is run through a profiling tool to look for any potential bottlenecks. If any performance issues are found, a new JUnit test is written to isolate the code (if one does not already exist). For example, the profiling tool reports that the search took ten seconds, but requirements dictate that it execute in less than three. The new JUnit test is wrapped around a JUnitPerf
TimedTest
to expose the performance bug. The timed test should fail; otherwise, there is no performance issue with the code you have isolated. Next, refactor the code that is causing the performance problem until the timed test passes.If the profiling tool did not report any performance issues, you do not have to write JUnitPerf tests. If you are concerned that a new feature might slow down an important piece of code, consider adding a JUnitPerf test to ensure that the code is always fast enough.
Here are the typical steps for writing a JUnitPerf test: 1. Write a JUnit test suite for you search algorithm.
Having a test that runs just the algorithm and exercises it with a reasonable set of test data makes it easy to gather repeatable metrics. Instead of manually clicking through an application, you can run your test through the profiler.
3. If performance is an issue, write another JUnit test to isolate the code with poor performance (if one does not already exist).
4. Write a JUnitPerf
TimedTest
for the new JUnit test. The test should fail. If the test passes, there is no performance issue with the code you have isolated.5. Tune the code until the performance test passes.
8.2.4 See Also
Recipe 8.3 shows how to create a JUnitPerf