fly*_*ire 10 java junit spring unit-testing
我的junit测试看起来像一个长篇故事:
优点:测试非常有效(非常擅长检测错误)并且非常稳定,因为它们只使用API,如果我重构代码,那么测试也会被重构.由于我不使用"脏技巧",例如在给定状态下保存和重新加载数据库,我的测试无视模式更改和实现更改.
缺点:测试变得难以维护,测试中的任何更改都会影响其他测试.测试运行8-9分钟,这对于持续集成非常有用,但对开发人员来说有点令人沮丧.测试不能孤立运行,你可以做的最好的事情是在你感兴趣的测试运行后停止 - 但是你绝对必须运行之前的所有测试.
你会如何改进我的考试?
egl*_*ius 11
首先,了解您所拥有的测试是集成测试(可能访问外部系统并访问各种类).单元测试应该更加具体,这对已经构建的系统来说是一个挑战.实现这一目标的主要问题通常是代码的结构方式:
即类紧密耦合到外部系统(或其他类).为了能够这样做,您需要以这样的方式构建类,以便您可以在单元测试期间实际避免命中外部系统.
更新1:阅读以下内容,并考虑最终设计将允许您实际测试加密逻辑,而无需访问文件/数据库 - http://www.lostechies.com/blogs/gabrielschenker/archive/2009/01/30/ the-dependency-inversion-principle.aspx(不是在java中,但是很好地说明了这个问题)...还要注意你可以为读者/编写者做一个非常集中的集成测试,而不是一起测试它们.
我建议:
更新2:根据其他答案,我想澄清一些关于做TDD的事情.让我们说你必须检查一些给定的逻辑是否发送电子邮件,将信息记录在一个文件上,将数据保存在数据库中,并调用一个Web服务(不是我所知道的,但你开始为每个服务添加测试) .在每次测试中,您不想访问外部系统,您真正想要测试的是逻辑是否会调用您期望它执行的那些系统.因此,当您编写检查在创建用户时发送电子邮件的测试时,您测试的是逻辑是否调用依赖性来执行此操作.请注意,您可以编写这些测试和相关逻辑,而无需实际发送电子邮件的代码(然后必须访问外部系统以了解发送的内容...).这将帮助您专注于手头的任务,并帮助您获得分离的系统.它还可以简化测试发送到这些系统的内容.
现在,您正在一种方法中测试很多东西(违反每次测试一次断言).这是一件坏事,因为当这些事情发生变化时,整个测试都会失败.这导致它不能立即明显为什么测试失败以及需要修复的内容.此外,当您有意更改系统的行为时,您需要更改更多测试以对应更改的行为(即测试是脆弱的).
要知道什么样的测试是好的,有助于阅读有关BDD的更多信息:http ://dannorth.net/introducing-bdd http://techblog.daveastels.com/2005/07/05/a-new-look- at-test-driven-development/ http://jonkruger.com/blog/2008/07/25/why-behavior-driven-development-is-good/
为了改进您提到的测试,我将使用这些上下文和测试方法名称将其拆分为以下三个测试类:
创建用户帐户
在登录
发送消息
您还需要提高测试速度.你应该有一个覆盖良好的单元测试套件,它可以在几秒钟内运行.如果运行测试花费的时间超过10-20秒,那么每次更改后您都会犹豫不决,并且会丢失一些运行测试的快速反馈.(如果它与数据库对话,它不是单元测试,而是系统或集成测试,它们有其用途,但速度不够快,不能连续执行.)你需要通过模拟来打破被测试类的依赖关系.或stub他们.同样根据您的描述,您的测试似乎不是孤立的,而是测试取决于先前测试引起的副作用 - 这是禁忌.好的测试是第一次.
单元测试应该 - 理想情况下 - 是独立的,并且能够以任何顺序运行.所以,我建议你:
如果创建一些用户并发送一些消息需要8分钟,性能问题可能不在测试中,而这可能是系统本身性能问题的症状 - 只有您的探查器确切知道!
[告诫:我不认为这些类型的测试是'整合测试',尽管我可能属于少数; 我认为这些类型的测试是功能的单元测试,一个TDD]