1

我最近被要求有效地向我的部门推销单元测试。我无法告诉你这让我有多兴奋,但我确实有一个担忧。我们将 JUnit 与 Spring 和 Maven 一起使用,这意味着每次mvn test调用时,它都会重建数据库。显然,我们不能将它与我们的生产服务器集成——它会杀死有价值的数据。

如何在不告诉 maven 跳过测试的情况下防止重建?

我能想到的最好的办法是分配脚本在测试数据库中运行(添加换行符以提高可读性):

mvn test 
   -Ddbunit.schema=<database>test 
   -Djdbc.url=jdbc:mysql://localhost/<database>test?
        createDatabaseIfNotExist=true&amp;
        useUnicode=true&amp;characterEncoding=utf-8 

我不禁认为必须有更好的方法。

我特别有兴趣了解是否有一种简单的方法可以告诉 Maven 只在特定类上运行测试而不构建其他任何东西? mvn -Dtest=<test-name> test仍然重建数据库。

=======更新=======

我脸上有点鸡蛋。我没有意识到我在两个地方使用了相同的变量,这意味着 POM 使用“skip.test”变量来重建数据库和运行测试......

4

3 回答 3

2

更新:我猜 DBUnit 会重建数据库,因为它在测试设置方法中被告知这样做。如果您更改设置方法,则可以消除数据库重建。当然,您应该这样做,以便在需要时重置数据库,并在不需要时忽略它。我的第一个赌注是使用系统属性来控制它。您可以像使用jdbc.urlet al 一样在命令行上设置属性。然后在 setup 方法中添加一个if来测试该属性并在设置时执行 DB 重置。

如果可以的话,与生产数据库完全分离的测试数据库绝对是最佳选择。您甚至可以使用例如Derby,这是一个可以嵌入在 JVM 中运行的内存数据库。但是,如果您绝对不能拥有单独的数据库,请在该数据库中至少使用一个单独的测试模式。

在这种情况下,我建议您将数据库连接参数放入 pom 中的配置文件中,默认为测试数据库,以及包含生产设置的单独配置文件。这样就永远不会发生您不小心对生产数据库运行测试的情况。

然而,一般来说,理解针对数据库运行的测试并不是严格意义上的单元测试,而是集成测试,这一点也很重要。如果你有一套现有的这样的测试,很好,尽可能多地使用它们。但是,您应该尝试添加更多真实的单元测试,它一次只测试一小部分独立的代码(最多一个方法或类),理想情况下是自包含的(不需要数据库、网络、配置文件等。 ) 所以他们可以跑得快——这是非常重要的一点。如果你有 5000 个单元测试并且每个只需要 5 秒来运行,那么总共需要将近 7 个小时,所以你显然不会经常运行它们。如果一个测试只需要 5 毫秒,您将在不到半分钟的时间内获得结果,因此您可以在提交最新更改之前运行所有测试 - 一天多次。

希望这可以帮助。

于 2010-02-18T21:01:30.070 回答
1

我们将 JUnit 与 Spring 和 Maven 一起使用,这意味着每次调用 mvn test 时,它都会重建数据库。

Maven 本身不会对数据库做任何事情,你的代码会做。无论如何,针对生产数据库运行测试(不是单元测试)是非常不寻常的。

如何在不告诉 maven 跳过测试的情况下防止重建?

很难说没有更多细节(您没有显示任何内容),但配置文件可能是一种方法。

于 2010-02-19T06:29:38.107 回答
0

根据定义,单元测试仅在系统中的单个组件上运行。您不应该尝试编写与任何外部服务(Web、DB 等)集成的单元测试。我对此的解决方案是使用一个好的模拟框架来消除组件所具有的任何依赖项的行为。这鼓励了良好的接口 API,因为大多数模拟框架最适合简单的接口。最好为与数据库的任何交互创建一个存储库模式接口,然后在测试与它交互的类时模拟 impl。然后,您可以单独在功能上测试您的 Repository impl。这还有一个额外的好处,那就是让你的单元测试足够快,以保持你的 CI 的一部分,这样你的反馈周期就尽可能快了。

于 2010-05-21T19:40:05.433 回答