The page assembles tips on converting old tests to JUnit. (Navigate back to the DerbyTesting page).

Table of Contents

How do I do X?

Check the "Conversion of writing JUnit tests FAQ" on the KillDerbyTestHarness page for a variety of Question and Answer topics.

My new junit test compiles and runs just fine – why doesn't it actually execute?

Many of the old tests take a connection argument, such as:

static void testLongBinary(Connection conn)

When you copy the code into a JUnit test, remember to remove the connection argument:

static void testLongBinary ()

Are there examples?

The IntroToJUnit wiki page has some starter examples. Also, DerbyTesting lists pages that track conversions by area (client, lang, jdbcadpi, etc.). Check the completed code for those other conversions.

How do you delete the old harness files after a test is converted to junit?

Below is a checklist that was posted to derby-dev:

  • Remove (svn delete) the test file (.java or .sql) and any support files it has like test_app.properties.
  • Remove (svn delete) any master files for that test
  • Remove the test from any suite (.runall file) it is in.
  • Add (svn add) the new test file.
  • Add the new test to a suite, e.g. lang._Suite.java.
  • ant clobber ; ant all (check no build failures)
  • run derbyall - check for no (new) failures
  • svn diff to create a patch & attach to the jira issue along with the output of svn stat

How do I get the expected SQLStates?

  • use the canon file located at functionTests/master/someTest.out to capture expected SQLStates.

or

  • put System.out.println("Expected message: "+ e.getSQLState() +":" + e.getMessage()); statements in the new test, to get the SQLStates

Common mistakes

  • Not using the utility methods that have already been created.
    There are quite a few built in utility methods which can be used in tests. Before you get started, study the derbyTesting.junit javadoc for utility methods and decorators that are already available. Tests using JDBC should inherit from BaseJDBCTestCase and can use all of the utility methods available in that class such as getConnection, openDefaultConnection, createStatement, assertSQLState, usingDerbyNetClient etc. Some of the common methods used in JDBC are assertFullResultSet for checking result sets returned, and the vmSupportsXXX() calls for jvm specific behavior.
  • Misusing the utility methods.
    Be careful of the order of the arguments of the utility methods. For example in assertSQLState the expected exception comes first. Even though the test might pass if the arguments are reversed, if it were to ever fail the message would not make sense.
  • Not using the utility methods to get a connection.
    Normally to get a connection to the default database, you should use getConnection() This is a single connection that is reused so if you call getConnection twice, you will get the same connection. If you want a secondary connection, use openDefaultConnection
  • Not removing the old test files.
    You should remove the old test files, canons and remove the old test from its suite. This includes references in any junit *HarnessJavaTest classes. ant clobber before you build, to make sure their are no residual dependencies on the old test files.
  • Closing the statements created with createStatement()
    There is no need to close the statements created with createStatement() as they are now cleaned up automatically.
  • Omitting the fail assert method after a method call in a try-catch block if that method is expected to fail by throwing an exception. The following code would not fail if the Statement.execute() method succeeds.
try {
  s.execute(command);
}
catch (SQLException e)
{
   assertSQLState("42502", e);
}
 

It should be:

try {
  s.execute(command);
  fail("Command expected to fail" + command);
}
catch (SQLException e)
{
   assertSQLState("42502", e);
}
 

or for this specific example a utility method already exists

   assertStatementError("42502",s,command);
  • Putting multiple methods in a try-catch block when expecting the last to fail, the test has some chance of passing if one of the methods that is expected to work incorrectly fails with a matching exception.
try {
   PreparedStatement ps = prepareCall(sql);
   ps.setInt(1, 23);
   ps.setString(2, 'hello');
   // this call should fail
   ps.executeUpdate();
   fail("expected the executeUpdate() to fail");
} catch (SQLException e) {
   assertSQLState("07000", e);
}

Instead move the methods expected to work outside of the try catch block.

PreparedStatement ps = prepareStatement(sql);
ps.setInt(1, 23);
ps.setString(2, 'hello');
try {
   ps.executeUpdate();
   fail("expected the executeUpdate() to fail");
} catch (SQLException e) {
   assertSQLState("07000", e);
}
  • Catching and discarding exceptions, especially on a close. If such a method throws an exception then it's a bug in Derby, and thus the test should fail.
  } finally {
    if (rs != null)
    { try {rs.close()} catch (SQLException e) {} }
  }

Just call the close methods in line with the rest of the code, no need for any finally blocks.

   PreparedStatement ps = prepareStatement(sql);
   ...
   ResultSet rs = ps.executeQuery();
   ...
   rs.close();
   ps.close();

When writing tests is there a short cut to creating the ResultSet two dimensional arrays?

You can use org.apache.derbyTesting.junit.Utilities.showResultSet(ResultSet rs) to print out the two dimensional array and then cut and paste into your code.

Where is the javadoc for the derby junit infrastructure

The javadoc for the tests and test infrastructure is generated daily and posted here

  • No labels