在我们测试 Java 应用程序时,往往需要连接数据库,并从数据库中获得准确 的测试数据用以测试应用程序是否正确。然而准备测试数据的工作较为复杂,一 旦数据库中的数据发生变化,要想恢复到之前的版本也很费时。对于那些没有条 件连接数据库的测试者而言,测试工作是不能进行下去的。因此,如果可以为某 个待测应用准备一套完备的测试数据,让程序开发、测试人员在不依赖于具体数 据库的情况下对应用进行测试,这无疑是十分方便的。
简介
JdbcProxy 是 SourceForge 上一个开源的 Java 项目,用 Java 语言编写, 遵循 LGPL 和 MPL1.1 协议,由 Frans van Gool 开发,支持 JDBC2.0 规范。通 过继承和重写 JDBC2.0 的接口,将一个 Java 应用访问数据库的过程记录在 XML 文件中,并通过这些文件在脱离数据库的情况下重现这个调用过程。 JdbcProxy 可以用在 Java 应用程序的测试中,进行数据准备并模拟数据库调用过程。读者 可以从 JdbcProxy 主页 获得最新的程序源代码以及说明文档。目前最新的版本 是 1.1 。
使用 JdbcProxy 代替普通的数据库调用可以满足程序开发、测试人员的很多 需求,使准备测试数据的工作变得简单。以文章查询系统为例,有些测试用例需 要测试当数据库中没有数据时页面的显示情况——显示没有相应数据的页面;有 些测试用例需要测试当数据库中只有一条数据时页面的显示情况——显示文章的 内容而不是文章的列表;还有些测试用例需要测试页面的分页效果,这时就需要 为程序准备不同的测试数据。如果采用直接连接测试用数据库的方式进行测试, 不同的测试用例需要重新准备测试数据库,操作起来比较复杂,也不能同时测试 不同的测试场景。如果使用 JdbcProxy,就可以为同一个 Java 程序准备不同的 测试用数据文件,测试者可以脱离后端数据库的限制,只需要访问到数据文件就 能完成测试。不同测试人员能够彼此不受影响的同时测试这个应用,从而大大简 化了准备测试环境的过程。
使用 JdbcProxy
JdbcProxy 提供了两种记录 JDBC 调用过程的方式,一种是方便开发人员和测 试人员阅读的,另一种是用于回放 JDBC 调用过程的。
第一种方式主要是为了让开发人员和测试人员能够了解 Java 应用调用 JDBC 的详细信息,当应用程序较为复杂——例如进行了多表查询,采用这种记录方式 可以让开发人员和测试人员一目了然的看到应用程序访问数据库的过程。
第二种方式是为测试程序准备数据的关键步骤之一。为了回放 JDBC 调用过程 ,JdbcProxy 分别处理应用程序对数据库的每个请求 (request) 与响应 (response),并在指定目录下生成一系列 XML 文件,这些文件是回放 JDBC 调用 过程的基础。这些 request/response 文件并不能直接被 JdbcProxy 调用, JdbcProxy 还提供了一个 StubTraceMerger 工具,用来将这些 request/response 文件整合在一个文件中,这个整合的文件就是我们测试 Java 应用所需要的数据文件。
JdbcProxy 提供了一种通过 HTTP 服务器发送请求并接收响应的机制,这些请 求和响应都按照应用程序的 JDBC 调用顺序记录在整合文件中,当 Java 应用试 图通过 JDBC 连接数据库时,JdbcProxy 会通过 HTTP 服务器从整合文件中读取 相应的数据,模拟调用数据库的过程,使用户得以在脱离数据库的情况下进行 Java 应用的测试。
因此要想利用 JdbcProxy 测试 Java 应用程序,首先需要生成用于回放 JDBC 调用过程的 request/response 文件,然后将这些 request/response 文件整合 在一个文件中,最后将这个整合的数据文件提供给 HTTP 服务器,这样 JdbcProxy 就可以通过 HTTP 服务器访问到数据文件,实现脱离数据库进行测试 的目的。
下面将对 JdbcProxy 提供的每个功能做详细的介绍。
记录方便开发人员和测试人员阅读的 JDBC 调用过程
JdbcProxy 可以跟踪 JDBC 调用过程,生成方便开发人员和测试人员阅读的文 件格式。在普通的数据库调用中,如果开发人员和测试人员想了解 JDBC 的调用 过程,或者需要完整的查看某个 SQL 语句,则需要手工将这些信息打印出来或者 记录在日志中。 JdbcProxy 的这个功能就像为 JDBC 的调用过程自动记录了一个 日志,开发人员和测试人员可以从日志中获得被调用的每一个方法,以及调用方 法的参数和返回值。这样便于开发人员和测试人员发现由于 SQL 语句拼写错误而 导致的数据库访问失败,或是由于数据库中没有数据而导致的空指针异常,使应 用程序的数据库访问过程更加直观。可以根据清单 1中的示例代码生成 JDBC 调 用过程。
清单 1
import java.sql.Statement;
public class JdbcProxyDemo {
public static void main(String args[]) throws Exception {
String driver = "nl.griffelservices.proxy.jdbc.oracle.StubTracerDriver";
String url = "jdbc:tracer::COM.ibm.db2.jdbc.app.DB2Driver:jdbc:db2:SAMPLE";
Class.forName(driver);
Connection connection = DriverManager.getConnection (url);
Statement stmt = connection.createStatement();
stmt.executeUpdate("DELETE FROM greetings WHERE greeting='Good Night'");//delete
stmt.executeUpdate("INSERT INTO greetings VALUES('Good Evening')"); //insert
stmt.executeUpdate("UPDATE greetings SET greeting = 'Good Night'
WHERE greeting = 'Good Evening'"); //update
ResultSet rs = stmt.executeQuery("SELECT * FROM greetings");//select
while (rs.next()) {
System.out.println(rs.getString("greeting"));
}
rs.close();
stmt.close();
connection.close();
}
}