如何在单元测试中引入容器?

发表于:2022-5-27 09:25

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:Carleslucky    来源:稀土掘金

  单元测试是一个令人头疼的话题,懒的写永远是一大理由,这段时间趁业务迭代的间隙想去补上项目代码的单测,经过这几天的折腾,我发现,懒可能排不上第一理由,这玩意是真的搞不清楚原理,乱七八糟的注解,残缺不全的文档,敷衍的博客,几乎没人能给一个完整可用的配置。折腾完三天之后,我并不是不想写,真的是没办法配置出一个可用的单测环境。
  为什么会这样呢
  单元测试需要有一个原则,就是不能污染测试环境的数据,它需要有一个即插即用的内存数据库,单测启动时初始化schema,单测结束时自动销毁。如果不遵从这个原则,虽然也可以跑一些代码的覆盖测试,但个人觉得已经失去了单元测试的意义。现在问题就出在这,对应的内存数据库有h2,mariaDB等等。redis也有类似的embedded-redis这样的开源工具。这些工具在配置时经常出现奇怪的错误,embedded-redis最近的一次更新在2020年1月,一共也就发布过4个版本,目前也才0.7.3。同样的问题也可能出现在h2上,这些工具的使用都不会被写进spring官方的文档中,出了问题只能自行解决,使用体验很差。
  新的希望
  可能你会觉得是我能力不行,这点简单的问题都搞不定。这些问题其实已经超出了技术问题的范畴,如何解决黑盒问题?大部分时候就靠猜,靠碰。高度封装化的时代,软件开发者的用户体验也很重要,毕竟没有多少人能从头研读所有工具的文档,然后总结出一些关联问题的解法,底层的问题就应该闭环在底层,就像一个建筑师不应该去解决水泥质量的问题,高度的社会分工是高效的体现,这在软件工程领域也是同理。
  废话有点多,这个希望就是Testcontainers,名字简单易懂,就是在单元测试时启动一些你需要的容器。有容器,其实可以解决一切外部依赖的问题,这个容器可以是官方预制的容器,也可以是自定义的,随着单测开始启动,随着单测结束销毁。听上去很内存数据库一样的美好,会有复杂的注解和配置吗?并没有。
  简单就是美
  有多简单:
  private static final MySQLContainer MY_SQL_CONTAINER = new MySQLContainer(“mysql:latest”);

  就这样一行,即可启动。你可以不加任何注解,它的生命周期是整个单元测试,如果加了注解:
  @Container
  private static final MySQLContainer MY_SQL_CONTAINER = new MySQLContainer(“mysql:latest”);

  那只在当前类的所有测试方法生效。如果更狠一点,每个测试方法的执行都单独启动一个容器:
  @Container
  private MySQLContainer MY_SQL_CONTAINER = new MySQLContainer(“mysql:latest”);

  去掉static即可,这样做有点奢侈,但在某些场景下可能会有用。

  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号