在Oracle上测试包含远程数据库的SQL查询

时间:2009-05-27 14:54:23

标签: java sql oracle unit-testing mocking

我们的开发数据库(Oracle 9i)使用远程数据库链接到远程共享数据库。

这个决定是在几年前做出的,当时将一些数据库模式放在开发机器上是不切实际的 - 它们太大了。

我们在开发机器上有一些模式,我们通过使用Oracle的数据库链接以及开发机器上的一些同义词使远程模式看起来是本地的。

我遇到的问题是我想测试一段SQL,它连接数据库链接两侧的模式中的表。

e.g。 (简化案例):

   select a.col, b.col
   from a, b
   where a.b_id = b.id
  • a位于本地数据库
  • b位于删除数据库
  • 我在语言环境DB上有一个同义词,所以'b'实际指向b @ remotedb。

由于链接,在开发环境中运行查询需要很长时间。查询在生产中运行良好(我不认为基于Oracle成本的优化器可以很好地处理数据库链接)。

我们过去一直不善于为这些类型的查询编写单元测试 - 可能是由于性能不佳 - 所以我想开始为它们创建一些测试。

有没有人为这样的查询编写单元测试的策略,以避免使用数据库链接的性能问题?

我通常会考虑尝试模拟远程服务的方法,但由于所有这些都在SQL查询中,我无论如何都无法轻易地模拟删除数据库。

4 个答案:

答案 0 :(得分:4)

您应该从开发中的生产中创建所需的所有模式的精确副本,但不包含所有数据。您应该使用足够的数据填充模式,以便进行适当的测试。您还可以通过从生产服务器导出统计信息并将它们导入到要复制的模式的开发数据库中来操作优化程序,使其在测试系统上的行为与生产类似。这样,查询将使用您创建的数据集运行,但查询将使用与生产类似的计划进行优化。然后,您可以从理论上估计它将如何在生产中进行扩展。

答案 1 :(得分:2)

将相关数据复制到开发数据库中并在本地创建表。

理想情况下,只需构建一个测试用例,告诉您:

  1. SQL是正确的(它解析)
  2. 使用几行测试数据正确运行
  3. 不要因为“让我们复制一切”而堕落,因为这意味着你不再知道你正在测试什么(以及你缺少的东西)。

    如果有疑问,请创建一个只有一条记录的表b。如果您在此区域中收到错误,请在了解失败时添加更多行。

    如果要将其置于边缘,请在单元测试中创建测试表(包含所有数据)。这样,您就可以记录您正在使用的测试数据。

    [编辑]你需要的是一个测试数据库。不要对可以更改的数据库运行测试。理想情况下,测试应该拆除整个数据库并从头开始重新创建它(表,索引,数据,所有内容)作为第一步。

    在这个测试数据库中,只保留定义良好的测试数据,这些测试数据只能通过定义新的测试来改变(而不是由某人“正在做某事”)。如果可以,请尝试针对内存数据库运行测试。

答案 2 :(得分:0)

我会建议具体化的观点。这些是在本地存储远程数据的视图。

答案 3 :(得分:0)

理论上,要进行单元测试,您可以使用基于测试用例创建和设计的任何受控数据集。它不一定是您的实时或开发系统。这是假设您的单位足够便携。当您进行集成测试时,您可以使用当前的数据库/应用程序对其进行测试,无论如何都可能在实时系统上进行测试(因此不需要数据库链接 - 我了解您的实时数据库在一个地方)。

我想说的是,您可以/应该在一组受控数据上测试您的单位(即您的组件,查询或任何您定义的单位),这些数据将模拟不同的“用例”和一次您完成测试以获得满意的结果,然后您可以继续进行集成+运行集成测试。

集成测试 - 您可以在实时环境中运行它,但只有在您通过单元测试证明您的组件是“防弹”之后(如果您的公司的方法/理念可以正常):) - sys admin's反应:“你是不是很狡猾?!”)

如果你想回到过去并测试已经实施的单位,那么为什么要这么麻烦?如果他们已经在生产中使用了一段时间没有任何事件,那么我会说他们没问题。但是,您的单位/查询总是有可能在侧面产生一些“缓慢滴答的定时炸弹”效果(随着时间的推移累积效应)。那么,分析影响就是答案。