首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何改进我的junit测试?

如何改进我的junit测试?
EN

Stack Overflow用户
提问于 2009-02-26 08:08:05
回答 9查看 2.8K关注 0票数 10

对,我的junit测试看起来像是一个很长的故事:

  • 我创建了4个用户
  • 我删除1个用户
  • 我尝试使用已删除的用户登录,并确保它失败。
  • 我用剩下的三个用户中的一个登录,并验证我可以登录。
  • 我从一个用户向另一个用户发送一条消息,并验证它是否出现在发件人的发件箱和接收者的收件箱中。
  • 我删除这条消息
  • ..。
  • ..。

优点:测试非常有效(非常擅长检测bug),并且非常稳定,因为它们只使用API,如果我重构代码,那么测试也会被重构。由于我不使用“脏技巧”,例如在给定状态下保存和重新加载db,所以我的测试忽略了模式更改和实现更改。

Disadvantages:测试变得很难维护,测试中的任何更改都会影响到其他测试。测试运行8-9分钟,这对于持续集成非常好,但对开发人员来说有点令人沮丧。测试不能孤立运行,最好是在您感兴趣的测试运行之后停止--但是您绝对必须运行前面的所有测试。

你会如何改进我的测试?

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2009-03-03 06:24:53

单元测试(理想情况下)应该是独立的,并且能够以任何顺序运行。所以,我建议你:

  • 打破你的测试成为独立的
  • 考虑使用内存中的数据库作为测试的后端。
  • 考虑将每个测试或套件包装在最后回滚的事务中。
  • 分析单元测试,看看时间在哪里,并集中精力于此。

如果创建几个用户并发送一些消息需要8分钟,那么性能问题可能不在测试中,而是系统本身的性能问题的一个症状--只有您的分析器才知道!

注意:我不认为这类测试是“集成测试”,尽管我可能是少数;我认为这类测试是特性的单元测试,是la TDD。

票数 5
EN

Stack Overflow用户

发布于 2009-02-26 08:15:00

首先,了解您拥有的测试是集成测试(可能访问外部系统并命中广泛的类)。单元测试应该更加具体,这对于已经构建的系统来说是一个挑战。实现这一目标的主要问题通常是代码的结构方式:

例如,与外部系统(或其他类)紧密耦合的类。要做到这一点,您需要构建类,这样才能真正避免在单元测试期间命中外部系统。

更新1:阅读了以下内容,并考虑到最终的设计将允许您在不触及文件/数据库的情况下实际测试加密逻辑-- http://www.lostechies.com/blogs/gabrielschenker/archive/2009/01/30/the-dependency-inversion-principle.aspx (不是在java中,但是很好地解决了这个问题).还请注意,您可以为读者/作者进行真正有重点的集成测试,而不必将其全部测试在一起。

我建议:

  • 逐步在您的系统上包括真正的单元测试。您可以在进行更改和开发新特性时,适当地进行重构。
  • 在做前面的工作时,酌情包括集中的集成测试。确保您能够运行与集成测试分离的单元测试。
  • 假设您的测试接近于整个系统的测试,因此与自动化验收测试不同的是,它们只在API的边界上运行。鉴于这一点,请考虑与API对产品的重要性相关的因素(比如它是否将在外部使用),以及您是否对自动验收测试有很好的覆盖率。这可以帮助你理解在你的系统上拥有这些东西的价值,以及为什么它们自然要花这么长时间。决定是在接口级别测试整个系统,还是同时测试interface+api级别。

更新2:基于其他答案的,我想澄清一些关于做TDD的事情。假设您必须检查某个给定的逻辑是否发送电子邮件、将信息记录在文件中、将数据保存在数据库中并调用web服务(我不知道所有这些,但您开始为其中的每个逻辑添加测试)。在每个测试中,您不想访问外部系统,您真正想要测试的是逻辑是否会调用您期望它执行的那些系统。因此,当您编写一个测试来检查在创建用户时是否发送了电子邮件时,您所测试的是如果逻辑调用了这样做的依赖项。请注意,您可以编写这些测试和相关逻辑,而不必实际实现发送电子邮件的代码(然后必须访问外部系统才能知道发送了什么.)。这将帮助您专注于手头的任务,并帮助您得到一个解耦的系统。它还将使测试发送到这些系统的内容变得简单。

票数 11
EN

Stack Overflow用户

发布于 2009-03-01 15:12:50

现在,您正在一种方法中测试许多东西(违反每个测试的一个断言)。这是一件坏事,因为当这些事情发生变化时,整个测试都失败了。这导致测试失败的原因和需要修复的问题还不清楚。另外,当您有意更改系统的行为时,您需要更改更多的测试来对应更改的行为(即测试是脆弱的)。

要知道什么样的测试是好的,可以阅读更多关于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秒,那么每次更改之后,您都会犹豫地运行它们,并且会失去运行测试所提供的一些快速反馈。(如果它与数据库对话,它不是一个单元测试,而是一个系统或集成测试,它们有其用途,但速度不够快,无法持续执行。)您需要通过嘲弄或固执打破测试中类的依赖关系。此外,从您的描述中可以看出,您的测试并不是孤立的,而是依赖于以前的测试所造成的副作用--这是不可能的。好的测试是第一

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/589603

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档