migrating EJB2 JUnit test cases to TestNG

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

migrating EJB2 JUnit test cases to TestNG

bwatsonluke

I have some JUnit tests that I'd like to migrate to TestNG. These
tests are used to test the methods exposed in the local interfaces of
EJB 2 beans.

As a bit of context, here is how the tests work currently:
The tests all subclass a common EJBTestCase.  This EJBTestCase
overrides the JUnit runBare() method (http://www.junit.org/junit/
javadoc/3.8.1/junit/framework/TestCase.html#runBare()) to control the
test execution.  The runBare creates an instance of a (remote)
EJBTestRunnerBean and calls a runTest() method on it, passing in the
test class name and the test name.  This method uses reflection to
instantiate the test (so the tests are part of the deployed EJB
application)  and then calls a runInServer() method which is exposed
by EJBTestCase.   This calls the JUnit runTest method (http://
www.junit.org/junit/javadoc/3.8.1/junit/framework/
TestCase.html#runTest()).  Any test failure is thrown back to the
"client" EJBTestCase by the EJBTestRunnerBean, and hence reported by
runBare().

The net effect is that an EJB test case can be invoked using the
standard Ant <junit> task and it will execute the tests in the EJB
container and report the results like tests that have been executed
locally.  In fact we generally run a set of tests together that
includes both in container tests (testing EJB local methods) and out
of container tests (testing plain Java objects and EJBs via their
remote methods) and developers do not have to care much what the kind
of test is - as long as they subclass the right TestCase.

I'm uncertain what would be the best way to implement in container
testing with TestNG, so would love some expert advice and the wisdom
of anyones experience.

I'm considering splitting the test suite into tests that are run in
container and those that aren't (e.g. by marking tests with groups).
For the in container tests, initiate them using an EJBTestRunnerBean
using an EJB client application that creates the EJBTestRunnerBean
instance calls an execute method.  It would programmatically run
TestNG on the suite of tests that should run in container.

However, I wonder if I couldn't create a special test runner or suite
runner that recognises EJB in container test cases (via group
annotation or marker interface) and takes care of invoking them in the
EJB container.  (i.e. the test runner/suite runner directly invokes
the EJBTestRunnerBean).  I've browsed the TestNG API but am not clear
on exactly how I'd do this.  Also the TestNG ant task only lets you
specify the driver class and not the class to be used to run tests or
suites.  So I'd have to create a new driver (extend TestNG class and
call setTestRunnerFactory)?  Are there any examples where that has
been done?

Thanks in advance for any suggestions.
Regards, Brett.


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "testng-users" group.
To post to this group, send email to [hidden email]
To unsubscribe from this group, send email to [hidden email]
For more options, visit this group at http://groups.google.com/group/testng-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

Re: migrating EJB2 JUnit test cases to TestNG

Hani Suleiman

Hi Brett,

Phew! What a convoluted setup!

There are some things you can and can't do. For example, the test  
redirection via runBare (effectively shunting the test call to  
somewhere else) isn't something that's possible right now in TestNG.  
So that avenue is closed.

However, it's fairly easy to invoke TestNG programatically, which is  
what you'll want to do inside of the container.

So on the server:

deploy tests (same as you do now)
write a servlet/jsp page that listens in for incoming test requests,  
and runs the tests
read results as returned by the server

Note that one main difference between how your tests work now and how  
they'll work with tng is that one client call equates to one suite  
run instance, not just one test.

You could of course have the server run just one test, and just  
invoke it multiple times. That gets messy though since results won't  
really be aggregated, and you'll see one result at a time.

Here's some code to get you started, to write jsp/servlet that  
invokes the tests:

TestNG tester = new TestNG();
tester.setDefaultSuiteName("container-tests");
//create a list of test classes, this can be either by scanning the  
server jars, or it can come from the request, or a combination
Class[] classes = ...
tester.setTestClasses(classes);
IReporter reporter = ... (either your own IReporter instance or one  
of the built in ones modified to handle the fact that tests are  
running remotely)
tester.addListener(reporter);
tester.run();

This probably isn't quite what you want to hear, but your current  
design can't really work since I don't know of any way of doing test  
redirection. The reason it's trivial to do in terms of JUnit's  
implementation is that those tests don't have state, and so you can  
just reinstantiate classes for every test. Within tng, you'd have to  
worry about keeping the second instance in sync with the original  
test class' state, which gets messy very quickly.


On Feb 16, 2007, at 12:14 AM, bwatsonluke wrote:

>
> I have some JUnit tests that I'd like to migrate to TestNG. These
> tests are used to test the methods exposed in the local interfaces of
> EJB 2 beans.
>
> As a bit of context, here is how the tests work currently:
> The tests all subclass a common EJBTestCase.  This EJBTestCase
> overrides the JUnit runBare() method (http://www.junit.org/junit/
> javadoc/3.8.1/junit/framework/TestCase.html#runBare()) to control the
> test execution.  The runBare creates an instance of a (remote)
> EJBTestRunnerBean and calls a runTest() method on it, passing in the
> test class name and the test name.  This method uses reflection to
> instantiate the test (so the tests are part of the deployed EJB
> application)  and then calls a runInServer() method which is exposed
> by EJBTestCase.   This calls the JUnit runTest method (http://
> www.junit.org/junit/javadoc/3.8.1/junit/framework/
> TestCase.html#runTest()).  Any test failure is thrown back to the
> "client" EJBTestCase by the EJBTestRunnerBean, and hence reported by
> runBare().
>
> The net effect is that an EJB test case can be invoked using the
> standard Ant <junit> task and it will execute the tests in the EJB
> container and report the results like tests that have been executed
> locally.  In fact we generally run a set of tests together that
> includes both in container tests (testing EJB local methods) and out
> of container tests (testing plain Java objects and EJBs via their
> remote methods) and developers do not have to care much what the kind
> of test is - as long as they subclass the right TestCase.
>
> I'm uncertain what would be the best way to implement in container
> testing with TestNG, so would love some expert advice and the wisdom
> of anyones experience.
>
> I'm considering splitting the test suite into tests that are run in
> container and those that aren't (e.g. by marking tests with groups).
> For the in container tests, initiate them using an EJBTestRunnerBean
> using an EJB client application that creates the EJBTestRunnerBean
> instance calls an execute method.  It would programmatically run
> TestNG on the suite of tests that should run in container.
>
> However, I wonder if I couldn't create a special test runner or suite
> runner that recognises EJB in container test cases (via group
> annotation or marker interface) and takes care of invoking them in the
> EJB container.  (i.e. the test runner/suite runner directly invokes
> the EJBTestRunnerBean).  I've browsed the TestNG API but am not clear
> on exactly how I'd do this.  Also the TestNG ant task only lets you
> specify the driver class and not the class to be used to run tests or
> suites.  So I'd have to create a new driver (extend TestNG class and
> call setTestRunnerFactory)?  Are there any examples where that has
> been done?
>
> Thanks in advance for any suggestions.
> Regards, Brett.
>
>
> >


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "testng-users" group.
To post to this group, send email to [hidden email]
To unsubscribe from this group, send email to [hidden email]
For more options, visit this group at http://groups.google.com/group/testng-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

Re: migrating EJB2 JUnit test cases to TestNG

Steve Loughran-7
In reply to this post by bwatsonluke

On 16/02/07, bwatsonluke <[hidden email]> wrote:

>
> I have some JUnit tests that I'd like to migrate to TestNG. These
> tests are used to test the methods exposed in the local interfaces of
> EJB 2 beans.
>
> As a bit of context, here is how the tests work currently:
> The tests all subclass a common EJBTestCase.  This EJBTestCase
> overrides the JUnit runBare() method (http://www.junit.org/junit/
> javadoc/3.8.1/junit/framework/TestCase.html#runBare()) to control the
> test execution.  The runBare creates an instance of a (remote)
> EJBTestRunnerBean and calls a runTest() method on it, passing in the
> test class name and the test name.  This method uses reflection to
> instantiate the test (so the tests are part of the deployed EJB
> application)  and then calls a runInServer() method which is exposed
> by EJBTestCase.   This calls the JUnit runTest method (http://
> www.junit.org/junit/javadoc/3.8.1/junit/framework/
> TestCase.html#runTest()).  Any test failure is thrown back to the
> "client" EJBTestCase by the EJBTestRunnerBean, and hence reported by
> runBare().
>

This is effectively what apache cactus does out the box.

I really like what cactus achieves, and it is one of the reasons why I
still advocate junit 3.8.x to people as a test framework. However, its
design has one big flaw: it still has to load every test case class in
the client, so needs the client classpath set up right.



> The net effect is that an EJB test case can be invoked using the
> standard Ant <junit> task and it will execute the tests in the EJB
> container and report the results like tests that have been executed
> locally.  In fact we generally run a set of tests together that
> includes both in container tests (testing EJB local methods) and out
> of container tests (testing plain Java objects and EJBs via their
> remote methods) and developers do not have to care much what the kind
> of test is - as long as they subclass the right TestCase.
>

yes, this is the cactus experience -you get to mix in-server and
client side tests

> I'm uncertain what would be the best way to implement in container
> testing with TestNG, so would love some expert advice and the wisdom
> of anyones experience.
>
> I'm considering splitting the test suite into tests that are run in
> container and those that aren't (e.g. by marking tests with groups).
> For the in container tests, initiate them using an EJBTestRunnerBean
> using an EJB client application that creates the EJBTestRunnerBean
> instance calls an execute method.  It would programmatically run
> TestNG on the suite of tests that should run in container.
>
> However, I wonder if I couldn't create a special test runner or suite
> runner that recognises EJB in container test cases (via group
> annotation or marker interface) and takes care of invoking them in the
> EJB container.  (i.e. the test runner/suite runner directly invokes
> the EJBTestRunnerBean).  I've browsed the TestNG API but am not clear
> on exactly how I'd do this.  Also the TestNG ant task only lets you
> specify the driver class and not the class to be used to run tests or
> suites.  So I'd have to create a new driver (extend TestNG class and
> call setTestRunnerFactory)?  Are there any examples where that has
> been done?
>

some options

* move to EJB3 and run your stuff client side. This is possible, but I
wouldnt encourage it. you still dont get the full java ee api; and
things may behave differently in EJB3-standalone than in an app server

* have a separate jsp page for every test and call them remotely. I
like to use this a lot as it lets me do hot diagnostics of a running
site; see what is going on and debug a system configuration. Ops teams
are happier with web pages than they are with test runners too.

* Produce the TestNG equivalent of cactus. This would be your best
long term action, as the whole testNG community would benefit

-steve

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "testng-users" group.
To post to this group, send email to [hidden email]
To unsubscribe from this group, send email to [hidden email]
For more options, visit this group at http://groups.google.com/group/testng-users?hl=en
-~----------~----~----~----~------~----~------~--~---