2012-07-16 82 views
5

我最近参与了一些使用PHPUnit的TDD。 我必须测试一个数据库驱动的应用程序,并阅读我计划在未来几周内研究和实现的DbUnit扩展。但是,我自己也碰到过这个人 - Sebastian Bergmann - 他有一张幻灯片,题目是“如果可以的话,避免对MySQL进行测试”,这对我的冒险行为产生了一些疑问。为什么我应该避免使用DbUnit来测试MySQL?

有人可以解释为什么我不应该针对MySQL测试的原因吗?

感谢

+0

链接的演示文稿不再可用。 :( – SDC 2012-11-06 10:41:01

+0

@SDC:演示文稿PDF可在[幻灯片共享框下面的非风格链接](http://en.oreilly。COM/mysql2008 /公/资产/附件/ 1980)。 (咆哮:这就是为什么我说[链接应该看起来像一个链接](http://web.archive.org/web/20100713205344/http://my.opera.com/CrazyTerabyte/blog/web-design -tip-a-link-should-look-like-a-link)) – 2014-06-06 22:30:25

回答

6

两个原因:

  • 它是缓慢的(和单元测试需要要快)
  • 它增加了额外的故障点,超出你的控制(没有测试真正失败当数据库连接失败?)

相反,作为建议你应该测试你的DAL与内存数据库,如SQLit即这消除了上述问题。

然而,这种方法也有它的缺点太 - 你可能有从一个数据库方言SQLite的移植SQL的问题。这自然意味着你将无法测试你的DAL的MySQL特定部分。与往常一样,这是一把双刃剑 - 你会得到单元测试的速度和隔离,但是你失去了可信度(如果我们可以这样调用它) - 如果它通过SQLite,你能100%确定它在MySQL上工作吗?

它可能并不坏主意离开你的DAL/DAO测试,集成测试阶段,在那里你会测试他们的核心agains使用,离开了单元测试的小东西真正的数据库引擎;例如映射(如果你使用的是ORM)。

编辑:在快速绝非严格的要求 - 这是一个好的一般建议。在做TDD的开发人员运行单元测试很多(这样的想法,每次提交到本地回购/每重要代码变化将需要通过运行单元测试代码库的完整性检查) - 也许不是所有的人,但肯定一些。你希望这个过程很快。

现在,有慢测试通常结尾是这样的:

  • “伙计,这东西跑这么慢......”
  • “也许我可以运行只是少数人...我要跑剩下的以后”
  • 在这一点上,我们知道以后还没有出现
  • ‘嘿,我上次提交没有破坏任何东西,我没有运行在所有的任何测试!’
  • “为什么我要运行它们呢?”

编写没有运行的测试,几乎杀死了写它们的目的。

这件事发生在与我一起工作的朋友身上;他的团队测试套件运行+/- 20分钟(DAL测试做得不好,参与测试的IoC容器),开发商开始运行一些测试,不一会儿“当前构建断路器”的电子邮件成为日常用品。他们有相当大的套件,但打破测试是没那么差

总体而言,您的方法似乎是正确的 - 我不会将测试移动到SQLite。就像我建议的那样,使用集成测试套件对数据库层进行测试(以便它可以与普通的单元测试套件分开运行)。

+0

感谢您的明确回答。我们遇到的问题是我们正在尝试尽可能进行单元测试(例如,每个新的错误修复/增强都应该有一个与之相关的单元测试)。当错误修复/增强仅仅是一个新的和改进的SQL查询时,这是否合理可行?如果DbUnit不推荐用于Mysql,那么测试这些修补程序的标准过程是什么(不使用SQLite方法)?将所有东西移植到SQLite似乎有点矫枉过正。 – user1027562 2012-07-17 11:17:12

+0

另外,为什么单元测试**需要**快速?我们没有当前的要求来优化我们的单元测试流程,而且我不明白为什么这会非常重要? (我是TDD的noob,因此任何启发都会被赞赏) – user1027562 2012-07-17 11:47:00

+0

当你运行他们很多。每次提交时,都应该尽可能多地运行自动化测试。理想情况下(和“构建”不是一个构建,直到所有的自动化测试运行并通过)。如果这需要不到10分钟,那么它是令人讨厌的,但可以接受,但超过十分钟,并停止被接受。 – 2012-07-17 16:20:25

2

我使用DbUnit来测试我的模型(说到MVC,包括ORM模型),因为它们与数据库密切相关。对于其他任何东西(主要是控制器),我使用模拟对象。

单元测试的基本思路是,以测试只是其中的一个应用程序代码单元(这是一个类)的时间,所以最好避免使用DB除非代码直接使用它。

当然,性能很重要。例如,我对模型进行了500次测试,几乎所有的测试都使用DB和灯具。在一台非常快的计算机上执行所有这些测试需要大约30-40秒。代码覆盖率报告生成大约需要一分钟。

3

我完全不同意Sebastian Bergmann写的幻灯片33的标题。

(因为从幻灯片上的信息可以很容易地被误解,我 肯定,在他的讲座中,他解释了真正意义)

正如在他的介绍调试吮吸说,但测试岩石

如果真实环境使用mySQL你必须对mySQL进行测试。否则,你会发现自己正在调试SQLite和mySQL之间的区别。

我相信,他的方向给开发商,而不是单元测试,在这个意义上我也建议开发人员可以保持他们的代码数据库中和成为可能需要的任何努力。它将改善项目整个生命周期的质量,而不仅仅是单元测试人员。它甚至可以保护mySQL本身的功能。 (过去有很多问题)。

但是,当测试使用SQL的单一代码时,无论您已经做了哪些其他测试,您必须必须对真实的东西进行测试。

我的做法是创建一个数据库连接的抽象层,并进行测试以与该层作出反应。随后,我为每个要测试的数据库服务器创建不同的具体类。

按照给定的,我们可以测试frequenlty对SQLite的这个环境,但真正的测试将每天至少运行一次。

相关问题