JDBDT

Hosted at: GitHub License: MIT Maven Central GitHub release Build status AppVeyor build status

About

JDBDT (Java DataBase Delta Testing) is an open-source Java library for testing database applications. The library is designed for automation of database setup and validation in test code. JDBDT is compact and has no third-party library dependencies (it just uses the Java 8 SE API internally), making it also easy and lightweight to integrate.

Compared to existing database testing frameworks, the main conceptual novelty is the possibility of using δ-assertions. For details, you may browse the reference documentation available in this site, along with the Javadoc for the JDBDT API and the JDBDT tutorial.

Contribute

The code is hosted at GitHub. Please use the issue tracker to report bugs or propose new features. For other issues e-mail delta _at_ jdbdt.org.

Installation

Prerequisite: JDBDT requires Java 8, it will not work with earlier Java versions.

Maven Central

JDBDT is available from Maven Central.

Maven setup

<dependency>
    <groupId>org.jdbdt</groupId>
    <artifactId>jdbdt</artifactId>
    <version>1.4.1</version>
</dependency>

Gradle setup

 compile 'org.jdbdt:jdbdt:1.4.1'

Setup instructions for other build systems are available here .

GitHub

JDBDT release artifacts are also available at GitHub.

Snapshot builds

To compile and install the latest snapshot from scratch, use the following commands:

git clone git@github.com:JDBDT/jdbdt.git
cd jdbdt
mvn install 

Main features in a nutshell

API facade

The core functionality is exposed by a simple API facade.

import static org.jdbdt.JDBDT.*;

Data sources

Tables and queries can be used as data sources in association to a database.

DB db = database("jdbc:myFaveDBEngine://myDB");

Table userTable = 
  table("USER")
 .columns("ID", "LOGIN", "NAME", "PASSWORD", "CREATED")
 .build(db);

Query idQuery = 
  select("LOGIN", "NAME")
 .from("USER")
 .where("ID = ?")
 .arguments(userId)
 .build(db);

Programmatic definition of data sets

Data sets are defined programmatically, for instance using data set builders, without need to maintain external “data files”. Data sets can also be read from CSV files anyway if convenient.

DataSet data = 
   builder(t)
  .sequence("ID", 1) // 1, 2, 3, ...
  .sequence("LOGIN", "harry", "mark", "john")
  .sequence("NAME", "Harry H", "Mark M", "John J")
  .sequence("PASSWORD", i -> "password " + i , 1)
  .random("CREATED", Date.valueOf("2015-01-01"), Date.valueOf("2015-12-31"))
  .generate(3) // generate 3 rows 
  .sequence("LOGIN", i -> "guest_" + i, 4)  // "user_4", "user_5", ...
  .sequence("NAME", i -> "Guest User " + i, 4) // "Guest User 4", ...
  .value("password", "samePasswordForAllGuests") 
  .generate(6) // 6 more rows keeping ID sequence and CREATED random filler
  .data();   

Database setup

Setup methods can be used to define database contents, for instance to populate tables, clear them, setting & restoring save points, …

static Table theTable;
static DataSet theinitialStata; 

@BeforeClass
public static void globalSetup() {
  theTable = ... ;
  theInitialData = ... ;
}

@Before
public void perTestSetup() {
   populateIfChanged(initialData);
}

δ-assertions

δ-assertions can be used to verify database changes incrementally, in addition to standard assertions for database state or data set comparison.

@Test
public void testUserInsertion() {
  User uJohn = ...;
  DataSet newRow = 
     data(theTable)
    .row(999, "john", "John", "jpass", Date.valueOf("2016-01-01"));
  sut.insertUser( uJohn ); 
  // Verify the insertion; assertion fails if other changes are detected
  assertInserted(newRow); 
}

@Test
public void testHarmlessQuery() {
  User u = sut.getUser("john");
  ... // standard assertions
  assertUnchanged(theTable); // no delta, query is really harmless!
}

Logging

Assertions and setup operations can be logged onto (optionally compressed) XML files.

<jdbdt-log-message time="..." version="...">
...
  <delta-assertion>
    <expected>
      <old-data count="0"/>
      <new-data count="0"/>
    </expected>
    <errors>
      <old-data>
        <expected count="0"/>
        <actual count="1">
          <row>
            <column java-type="java.lang.String" label="LOGIN">linus</column>
            <column java-type="java.lang.String" label="NAME">Linus Torvalds</column>
            <column java-type="java.lang.String" label="PASSWORD">linux</column>
            <column java-type="java.sql.Date" label="CREATED">2015-01-01</column>
          </row>
        </actual>
      </old-data>
      <new-data>
        <expected count="0"/>
        <actual count="0"/>
      </new-data>
    </errors>
  </delta-assertion>
</jdbdt-log-message>