jakarta-cactus-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Vincent Massol" <vmas...@octo.com>
Subject [proposal] Cactus v2
Date Tue, 27 Nov 2001 20:19:22 GMT
This is a proposal for Cactus v2 ...

I have been thinking for some time now about what cactus should become in
the future ... During all this email, keep in mind that the overall goal of
Cactus is to provide a means to perform unit testing for server side java
components, whatever the kind of unit testing. Before we start with the
actual proposal, a bit of semantics. I can see 3 types of unit testing :

- logic unit testing,
- integration unit testing (unit tests that verifies that the components
work together and with the container). This is not full scale integration
testing across several subsystem but rather within a given subsystem (which
is why it is called integration unit testing)
- functional unit testing. This is not exactly acceptance testing. It
corresponds to the limit of integration unit testing (end to end test).
Acceptance testing correspond more to use case testing and could involve
several functional unit tests. However, the biggest difference is on the
ownership of these tests. Functional unit tests belong to developers and are
there so that developers are more confident that what they implement is what
is they understood they should implement. Acceptance tests belong to the
customer and are there to verify that the implementation does indeed match
the business requirements.

Cactus v2 goal is to address these 3 kinds of unit testing in a consistent
and flexible manner. What are the main differences with v1 ? Answer :
* complete blend of the 3 kinds of unit tests in a single homogeneous and
consistent way of writing tests
* not only focused on integration unit testing (as it was the case in v1).
It will be possible to write Mock Objects style tests that run outside the
container with the same framework. You'll be able to use mocks (from
www.mockobjects.com for example) if you wish but won't have too as mocks
won't need to be written prior to writing the tests
* easier to deploy than cactus v1
* add support for a new kind of tests : Pattern Testing. Pattern testing is
the ability to verify that the code is applying correctly some patterns.
Examples are :
  - ensure that a Facade pattern is used and that there all code goes
through that facade and does not bypass it
  - ensure that all logging is done by using such Log service and no code is
allowed to use System.out for example. Another example is to verify that all
jdbc code is found in a data access service.
  - ensure that all use cases are first handled by a controller (in the MVC
  - ... (the only limit is your imagination !)
* works for any existing framework. Cactus v1 had support for only a limited
number of APIs : Servlets, JSP Tag libs, Filters, EJB. Cactus v2 supports
any existing API out of the box : velocity, struts, turbine, jetspeed, ...
* allow for unit testing private methods

These are only a few of the advantages of Cactus v2 ... :-). Do you like it
so far ? I hope so ...

Now, let's stop the marketing and dive into more details. So, where's the
magic ? The answer lies in a wonderful new tool called AspectJ
(http://www.aspectj.org). Basically it would let you statically (dynamic
features are scheduled for version 2 of aspectj) intercept any call before,
after or around a given method, making it perfectly suited for unit testing.

So what would be the structure of a Cactus v2 test class ? Answer: a test
would be an Aspect. The "interception" feature of aspectj will actually let
you define where a test start and where it ends. If you decide that the
start and end of the test boundaries are in the same method, you'll find the
concept of mock objects. If you let it start in a given method and let the
test run in its container (possibly up to the database for example), then we
find the concept of Cactus v1 integration tests. If the start and end of the
test is outside the system, then we find the concept of functional tests.
These are only extreme cases but bear in mind that you have total control on
where exactly you'd like the test to start and end ! It is in that sense
that I say that Cactus v2 would bring together mock objects, integration
testing and functional testing.

I don't want to show too much of the implementation as it is very much in my
head at the current point and it needs to be proved it will work ! I
hesitated in writing this email before I had a working prototype to show but
I thought that it would still be good to share that little information with
you to start getting some feedback from you.

Some exemple test cases (just to give some ideas as it will probably change)

// Example of an integration test on an EJB's method using a JdbcDataAccess
component to access the database. The test starts in the remote call to the
ejb and stops before calling the database

public aspect TestXXXAspect extends TestAspect
  before(TestRunner runner) : run(runner) && test("testcase1")
     // 1 - Use the test runner to get an injector. There will several
     //  http injector, rmi injector, jms injector, ...
     TestInjector injector = runner.getInjector(TestRunner.EJB_INJECTOR);

     // 2 - Call test, passing init values if need be.

     // 3 - Possibly assert results

  ResultSet around() : call(JdbcDataAccess.executeSelect(..)) &&
     // return mock result set with values for the test
     return resultSet;

  // ---------------------------------------------------------------

  // Test : mock object style
  before(TestRunner runner) : run(runner) && test("testcase2")
     // 1 - Use the test runner to get an injector
     TestInjector injector = runner.getInjector(TestRunner.LOCAL_INJECTOR);

     // 2 - Call test, passing init values if need be.

     // 3 - Possibly assert results

If you want to perform an integration test on a method that is not
accessible from the outside, you need an entry point in the container. You
can either use a Cactus Proxy or an existing component accessible from the
outside. In either case, you would trap the call on the server side and call
the method to test :

around() : call(MyServlet.doGet(..)) && test("testcase3")
  // call the method to test (but from inside the container)
  // ex:
  InitialContext context = new InitialContext();
  myejbhome = (MyEJB)context.lookup("jndiname");
  myejb = myejbhome.create(); // or findby
  myejb.methodToTest(arg1, arg2, ...);

  // Assert results

It means that a single test is no longer made up of a single testXXX()
method as in junit but can actually be composed of as many "checkpoints" as
is desirable (and needed).

Note that all this will mean that cactus v2 tests will not be junit test
cases. However, it is probably possible to write a wrapper facade (if we
wish) so that junit test runners could be used along with existing junit
integration tools in IDEs for example.

What do you think about all that ? Im' interested in your feedback !


Vincent Massol, vmassol@octo.com
OCTO Technology, www.octo.com
Information System Architecture Consulting

To unsubscribe, e-mail:   <mailto:cactus-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:cactus-dev-help@jakarta.apache.org>

View raw message