java - 如何改进我的junit测试

标签 java unit-testing spring junit

是的,我的 junit 测试看起来很长:

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

优势: 测试非常有效(非常擅长检测错误)并且非常稳定,因为它们只使用 API,如果我重构代码,那么测试也会被重构。由于我不使用诸如在给定状态下保存和重新加载数据库之类的“肮脏技巧”,因此我的测试忽略了架构更改和实现更改。

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

您将如何改进我的测试?

最佳答案

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

即类与外部系统(或其他类)紧密耦合。为了能够做到这一点,您需要以这样一种方式构建类,即您实际上可以避免在单元测试期间触及外部系统。

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

我建议:

  • 逐渐在您的系统中加入真正的单元测试。您可以在进行更改和开发新功能时执行此操作,并进行适当的重构。
  • 在执行上述操作时,请在适当的情况下加入重点集成测试。确保您能够运行与集成测试分开的单元测试。
  • 考虑到您的测试接近于对整个系统进行测试,因此与自动化验收测试的不同之处仅在于它们在 API 的边界上运行。鉴于此,请考虑与 API 对产品的重要性相关的因素(例如是否将在外部使用),以及自动化验收测试是否具有良好的覆盖率。这可以帮助您了解在您的系统上安装这些的值(value)是什么,以及为什么它们自然需要这么长时间。决定您是在接口(interface)级别上测试整个系统,还是同时在接口(interface)+api 级别上进行测试。

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

关于java - 如何改进我的junit测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/589603/

相关文章:

python - 如何在单个 html 文件中获取 django 覆盖率报告

带有 Java 高级 rest 客户端的 Spring 数据 Elasticsearch

java - Apache Ignite 应用程序无需重新平衡即可部署

Java 删除 -> 编译时类型对齐 - 或 Java 库/框架代码转换为应用程序逻辑

Python将随机数注入(inject)测试

java - 示例代码的编译问题

java - 有没有办法在不使用 Thread.sleep 的情况下对 ScheduledExecutorService.scheduleAtFixedRate 进行单元测试?

java - 为什么使用@Transactional注解时数据没有保存?

java - 解决 Java 项目之间依赖关系的最佳方法是什么?

java - 在 Shutdownhook 上使用 JavaFX Application.stop() 方法