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.
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.
Prerequisite: JDBDT requires Java 8, it will not work with earlier Java versions.
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 .
JDBDT release artifacts are also available at GitHub.
The core functionality is exposed by a simple API facade.
import static org.jdbdt.JDBDT.*;
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);
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();
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 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! }
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>