Saturday, June 21, 2008

Writing Integration Tests with the AbstractTestRunner

Writing integration tests around your ESB Services can be a bit of a pain in the head under the current 4.x codebase (5.0 will be fixing many of these issues). A number of resources are managed statically. This is "OK" under normal running conditions, but a major head wrecker when trying to write multiple isolatable tests i.e. tests where you can easily dump/create clean environments for each test, without one test magically screwing with another.

A while ago I created the ESBConfigUtil test utility class (dumb name), which went some way towards making it a little easier to write tests, but was still a bit painfull. The latest addition is the AbstractTestRunner class, which I think is a bit better again. It wraps the ESBConfigUtil class, setting up the test env (ESB deployment, Registry, ESB properties ala the beloved PropertyManager), starting the ESB Controller, running the test and then shutting down the Controller and ensuring that the test env is returned to it's state from before the test run (or at least tries to ;-) ), which hopefully helps to avoid leakage between tests.

The AbstractTestRunner tries to allow you to write Integration level tests more easily. You can define a full ESB configuration and run it through the ESB Controller class, run tests (invoke endpoints etc).

As an example from the InVM transport tests, we have the following ESB configuration named "in-listener-config-01.xml":

<?xml version = "1.0" encoding = "UTF-8"?>
<jbossesb xmlns="http://anonsvn.labs.jboss.com/labs/jbossesb/trunk/product/etc/schemas/xml/jbossesb-1.0.1.xsd">

<services>
<service category="ServiceCat" name="ServiceName"
description="Test Service">
<actions mep="RequestResponse">
<action name="action"
class="org.jboss.soa.esb.mock.MockAction" />
</actions>
</service>
</services>

</jbossesb>

Writing some test code around this, with the configuration deployed in the ESB Controller (quite near to the full running env):

public void test_async() throws Exception {
AbstractTestRunner testRunner = new AbstractTestRunner() {
public void test() throws Exception {
ServiceInvoker invoker =
new ServiceInvoker("ServiceCat", "ServiceName");

Message message = MessageFactory.getInstance().getMessage();

message.getBody().add("Hi there!");
invoker.deliverAsync(message);

sleep(50);
assertTrue(message == MockAction.message);
}
}.setServiceConfig("in-listener-config-01.xml");

testRunner.run();
}

So as you can see, the test method creates an anonymous instance of the AbstractTestRunner class. It implements the "test" method, in which the actual test code is placed. The Service config file is set on the anonymous instance through the setServiceConfig method (the String param version of this method looks up the resource using getClass().getResourceAsStream()). The ESB properties file can be set through the setEsbProperties method (supports the same mechanisms as the setServiceConfig method). Both setServiceConfig and setEsbProperties methods return the instance of the anonymous inner class (i.e. "return this;"), so you can string the config calls together e.g.:

public void test_async() throws Exception {
AbstractTestRunner testRunner = new AbstractTestRunner() {
public void test() throws Exception {
.... test code....
}
}.setEsbProperties("jbossesb-properties.xml")
.setServiceConfig("jboss-esb.xml");


testRunner.run();
}
Of course, you need to call the run() method to run the actual test code. You can do this as above, or you can just string it onto the end of the anonymous inner class:
public void test_async() throws Exception {
AbstractTestRunner testRunner = new AbstractTestRunner() {
public void test() throws Exception {
.... test code....
}
}.setServiceConfig("jboss-esb.xml").run();
}

Calling the run() method:
  1. Parses the Service configuration, creating the Controller instance.
  2. Installs the specified ESB properties (recording the currently installed properties)
  3. Installs and configures the Registry.
  4. Starts the Controller
  5. Calls the "test()" method to run the test code.
  6. Stops the Controller
  7. Uninstalls the Registry.
  8. Resets the ESB properties to their pre-test state.
You may ask why I didn't just implement a base TestCase class. Well... it just ends up getting in the way when you're trying to write your own test code. You end up having to be contious of what you're inheriting, making sure you call super.xxx() at the appropriate times etc. You end up not being able to extend another TestCase base impl (if you need to do that). Basically, as a solution it sucks for many of the same reasons that other inheritance based solutions suck!

Would be great if people could try it in their tests so we can evolve it and fix any issues. I hope it can make integration testing a bit easier in the 4.x codebase.

5 comments:

wholesale air jordan said...

wholesale shoes
Shoes wholesale
wholesale designer shoes
wholesale athletic shoes
wholesale jordans shoes
wholesale nike
wholesale sandals
wholesale purses
wholesale clothing
wholesale flip flops

cheap jordan
cheap kids jordans
cheap jordans for sale
fake jordans
cheap air force ones
wholesale jordans
rare jordans
cheap jordans shoes
wholesale jordans
wholesale air jordans
wholesale nike

sexy11 said...

情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣用品,情趣,情趣,情趣,情趣,情趣,情趣,情趣用品,情趣用品,情趣,情趣,A片,A片,情色,A片,A片,情色,A片,A片,情趣用品,A片,情趣用品,A片,情趣用品,a片,情趣用品

A片,A片,AV女優,色情,成人,做愛,情色,AIO,視訊聊天室,SEX,聊天室,自拍,AV,情色,成人,情色,aio,sex,成人,情色

免費A片,美女視訊,情色交友,免費AV,色情網站,辣妹視訊,美女交友,色情影片,成人影片,成人網站,H漫,18成人,成人圖片,成人漫畫,情色網,日本A片,免費A片下載,性愛

情色文學,色情A片,A片下載,色情遊戲,色情影片,色情聊天室,情色電影,免費視訊,免費視訊聊天,免費視訊聊天室,一葉情貼圖片區,情色視訊,免費成人影片,視訊交友,視訊聊天,言情小說,愛情小說,AV片,A漫,AVDVD,情色論壇,視訊美女,AV成人網,成人交友,成人電影,成人貼圖,成人小說,成人文章,成人圖片區,成人遊戲,愛情公寓,情色貼圖,色情小說,情色小說,成人論壇

a片下載,線上a片,av女優,av,成人電影,成人,成人貼圖,成人交友,成人圖片,18成人,成人小說,成人圖片區,成人文章,成人影城,成人網站,自拍,尋夢園聊天室

A片,A片,A片下載,做愛,成人電影,.18成人,日本A片,情色小說,情色電影,成人影城,自拍,情色論壇,成人論壇,情色貼圖,情色,免費A片,成人,成人網站,成人圖片,AV女優,成人光碟,色情,色情影片,免費A片下載,SEX,AV,色情網站,本土自拍,性愛,成人影片,情色文學,成人文章,成人圖片區,成人貼圖

sex999 said...

A片,A片,情色,情色,A片,A片,情色,情色,A片,A片,A片下載,做愛,成人電影,.18成人,日本A片,情色小說,情色電影,成人影城,自拍,情色論壇,成人論壇,情色貼圖,情色,免費A片,成人,成人網站,成人圖片,AV女優,成人光碟,色情,色情影片,免費A片下載,SEX,AV,色情網站,本土自拍,性愛,成人影片,情色文學,成人文章,成人圖片區,成人貼圖

美女交友,AIO交友愛情館,AIO,成人交友,視訊交友網,視訊交友,拓網交友,PC交友,視訊交友90739,交友,情色交友,聊天室交友,辣妹視訊,視訊辣妹,美女視訊,視訊美女,情色視訊,日本AV,免費視訊聊天,視訊聊天,AV女優,AV,視訊聊天室,視訊,免費視訊,情人視訊網,本土自拍,自拍,AVDVD,SEX,微風成人,微風論壇,微風成人區,成人網站,成人,成人電影,嘟嘟成人網,成人貼圖,成人影片,成人圖片區,成人圖片,18成人,成人小說,成人影城,成人文章,成人論壇,愛情公寓,情色論壇,情色,色情聊天室,色情,情色貼圖,情色文學,色情小說,情色小說,寄情築園小遊戲,色情遊戲,情色電影,情色網,做愛,UT聊天室,聊天室,聊天,哈拉聊天室,豆豆聊天室,尋夢園聊天室,聊天室尋夢園,080苗栗人聊天室,苗栗人聊天室,080中部人聊天室,080聊天室,中部人聊天室,柔情聊天網,6K聊天室,小高聊天室,上班族聊天室,免費A片,A片,成人聊天室,一夜情聊天室,情色聊天室,色色網,免費AV

Anonymous said...

A very useful tool. To bad it is not available in any JBoss ESB binary distribution :(

Reed Twil said...

aside from all the wholesale flip flops spam, your code worked like a charm, so thank you!