testing without the embedded container

Lukas Krejci lkrejci at redhat.com
Tue Nov 30 14:30:26 UTC 2010


This is great, John. Not having known about unitils (I need to work on my 
googling skills there), I created a DB export/import mechanism together with 
TestNG integration a couple of months ago for our performance testing efforts. 
Even though we still do need the AbstractEJB3Test in the perf tests so that we 
can test our SLSBs what you did will become useful in perftest as well I hope.

I'd just like to point you to modules/helpers/perftest-support where you can 
find a console app that is able to import/export data in/out of a database 
given some fairly simple configuration. That should make creating the dbunit 
datasets easier.
I even wrote a blog about this ;) 
http://metlos.wordpress.com/2010/09/15/how-to-export-data-from-a-db-using-jpa-
model/

Further, in our perf-related work, we defined a couple of annotations that can 
be used in the tests to automatically setup the database with given dataset - 
this is where we probably overlap with unitils, even though our annotations go 
a little bit further in integrating with RHQ because you can specify the 
dbVersion your test data are based on (so that one doesn't have to re-generate 
the test dataset if the schema changes). Again, the code for this is inside 
the perftest-support project. 
https://metlos.wordpress.com/2010/09/20/database-setup-for-testng-tests/

It would be great if we could talk about this some more together with Heiko so 
that we can merge our two approaches and define the features that we need in 
both domain model tests as well as perf and other database dependent tests.

Lukas

On Monday, November 29, 2010 21:33:37 John Sanda wrote:
> A while back when I was testing JPQL queries that I had updated to
> account for resource types being deleted, I got tired off using the
> embedded container. The start up time in particular is what wore my
> patience thin. It dawned on me as I was running my tests in core/domain,
> which is where we define all of our JPQL queries, that there are only
> two things for which we are using the embedded container in core/domain
> tests - 1) entity manager and 2) transactions. We can get both of these
> things without the embedded container. A little over a month I created a
> branch in which I refactored all of the tests in core/domain such that
> there is no longer any dependency on the embedded container.
> Specifically, tests no longer inherit from AbstractEJB3Test.
> 
> Tests are instead relying on unitils (http://www.unitils.org). Unitils
> provides a lot of useful, interesting features. There are three things
> for which I was using it.
> 
> 1) A persistence service. Unitils can inject an EntityManager,
> EntityManagerFactory, and DataSource into tests using standard JEE
> annotations.
> 2) A transaction service. Each test method by default is wrapped in a
> transaction.
> 3) Integration with DbUnit. Unitils executes a dbunit data set
> immediately before each test method is executed, ensuring that the
> database is in a known, consistent state before the test begins.
> 
> There are a number of upsides to this change. The overall build time for
> core/domain is a good bit faster. More importantly though, executing a
> single test class is substantially faster since there is no longer the
> overhead of bootstrapping the embedded container.
> 
> I simplified the control flow in a large number of tests. There is
> longer any need for the try/finally/rollback pattern that we commonly
> used. In fact, you will notice that the test code has been taken out of
> those try/finally blocks altogether. This *does* mean that tests are
> committing transactions, and that's ok since each test resets the
> database (or more precisely, relevant parts of the database) before it
> runs. Committing transactions has the added benefit of being able to
> inspect the state of the database after a test failure. I am sure most
> of us at some point have spent time debugging a test failure and
> resorted to temporarily changing the rollback call to a commit in the
> test method so that we could inspect the state of the database. That is
> not only unnecessarily time-consuming, it is also very error-prone.
> 
> Using dbunit can and does simplify the set up logic for tests. It
> provides a way to do test set up independent of the code under test. It
> also makes for good documentation and makes tests more readable.
> 
> It would remiss of me not to point out some of the downsides of using
> unitils. Unitils is somewhat of a glue framework in that it ties
> together nicely some other frameworks for use in JUnit and TestNG tests.
> Under the covers it uses spring, dbunit, hibernate, and several other
> libraries. This can (and did for me) lead to some problems with
> dependency management. Granted we are only talking about test scope, but
> I still had to spend time resolving a few dependency conflicts.
> 
> Defining the dbunit data sets in xml might be considered another
> downside. It limits the use of some refactoring tools. If I change part
> of an entity mapping in the Java source file, I will have to
> independently make any changes necessary to the data set file.
> Everything in the xml data set is defined statically. If I need to
> create a number of rows in a table that let's say differ in only ids, I
> have to write out each one in the data set whereas a simple, compact
> loop to generate those rows would likely be more preferable.
> Fortunately, both dbunit and unitils are pretty flexible. We are not
> limited to defining data sets in xml, although that is likely to be the
> easiest and fastest approach most of the time.
> 
> The other issue with dbunit is that it does not manage foreign keys. For
> an entity like ResourceType, care has to be taken to ensure that things
> are deleted in the correct order; otherwise, you will run into FK
> constraint violations. I have found though that once the data set is set
> up, it is pretty easy to manage with respect to FKs.
> 
> I want to emphasize that my goal was not to simply replace the embedded
> container with unitils. Rather, the intention was to make tests faster,
> more concise, more reliabe, and easier to maintain. Unitils is just one
> way to achieve this, but I do think it is a very good way to achieve it.
> I did not integrate unitils into any of the server/jar tests since we
> rely heavily on the embedded container there for accessing our SLSBs.
> 
> I did this work in the unitils branch, and it can all be found in a
> single commit - 0e666c041b3047c5a8919325615569c0d95a06d7. Please look at
> some of the tests in the branch. I would like to get some feedback and
> consider eventually integrating this upstream into master.
> 
> - John
> _______________________________________________
> rhq-devel mailing list
> rhq-devel at lists.fedorahosted.org
> https://fedorahosted.org/mailman/listinfo/rhq-devel


More information about the rhq-devel mailing list