Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JUnit + DbUnit: Switch database connection between development and testing environments

I'm setting up some test scaffolding around an existing project. This includes some integration tests, using JUnit and DbUnit. I've also set up a Jenkins installation for continuous integration.

My problem involves changing the DB connections between the development and testing environments. I have my own product stack installed locally for quick ad-hoc testing and investigation. As I'm developing, I run tests against my private database, since it's faster and I won't ruin anybody else's day with buggy work-in-progress code.

Once code is checked in, Jenkins will run my tests. Right now it's still pointing at my local db. I'd prefer to have Jenkins run tests against a different database, one that is in the test environment.

Is there a best practice / strategy / technology / etc. for changing database connections for testing without having to change code? Bonus points if the solution allows Jenkins to run the same tests against multiple DBs (should be possible since DbUnit is agnostic).


Edits for more info:

The product is a large one, with dozens of different interacting components (usually in separate vms / processes). In a live system, the different processes typically communicate through the database. IE, the UI process writes changes to a table and the back-end process polls that table for changes. Yes, it's awful. For integration testing, I configure a system using the UI and capture that state with DbUnit. I can then run tests against that "input."

My component, and all new components, are managed by maven. DB Connections are currently hard-coded in the test setup. The DbUnit system works; I'd just like to be able to switch which database my tests are referencing depending on whether they're being run by me in my development environment, or run by Jenkins in the testing environment.

like image 848
Eric Grunzke Avatar asked May 22 '12 16:05

Eric Grunzke


1 Answers

Assuming that you can externalise the database connectivity parameters for your tests into a .properties or .xml file, and that you are using Maven, then one approach is to use Maven properties (and optionally profiles) to define each environment, and use resource filtering to configure these properties into your configuration file.

For example, suppose during testing that you manage to externalise your database connectivity parameters into a file called datasource.properties in src/test/resources that looks like this:

datasource.driverClassName = ${test.datasource.driverClassName}
datasource.url = ${test.datasource.url}
datasource.username = ${test.datasource.username}
datasource.password = ${test.datasource.password}

And you have this in your POM:

<build>
  <testResources>
    <testResource>
      <directory>src/test/resources</directory>
      <filtering>true</filtering>
    </testResource>
  </testResources>
</build>

Then you could define test.datasource.driverClassName etc. properties in various ways to tell Maven to use different databases:

  • You could define defaults in the <properties> section of your POM;
  • You could define user-specific databases in the <properties> section of each developer's (and Jenkins') settings.xml;
  • You could define some profiles in your POM for different environments (e.g. development, jenkins, anotherDB) and run your build with different profiles.

If you go for the last option, then you could get Jenkins to run against multiple databases by performing multiple Maven builds from one Jenkins project, differing only by profile. That said, it would be better to have different Jenkins project for each environment.

like image 162
Kkkev Avatar answered Oct 30 '22 19:10

Kkkev