单元测试与集成测试.md

2023-10-19  本文已影响0人  iakuil

LLT(Low Level Test)通常由开发人员自测,它包括单元测试(Unit Test)、集成测试(Integration Test)、模块系统测试(Module System Test)、系统集成测试(BBIT),一般我们最关注的是UT(单元测试)和IT(集成测试)。

测试替身

Test Double(测试替身)包含了dummy, fake, mock, stub, spy 五种不同的类型,这里我们引用Martin Fowler的经典论述:

  • Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists.
    Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an in memory database is a good example).
  • Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test.
  • Spies are stubs that also record some information based on how they were called. One form of this might be an email service that records how many messages it was sent.
  • Mocks are what we are talking about here: objects pre-programmed with expectations which form a specification of the calls they are expected to receive.

简单总结一下:

其中,Dummy 和 Fake 好理解,一个是没啥用,只是占位符,另一个是基本上啥都能干,比真实的系统差点意思,但基本上能覆盖大部分场景。而对于 spy,通常我们不太区分它和 stub,可以一起理解。
那么问题来了,Mock 说的是你要明确你对每次调用的 expectation,需要写代码来指明什么情况下要怎么做,而 Fake 好像也是这个意思,区别在于这个代码可能不用你写(因为开源社区有一些现成可用的)。那么它们根本区别是什么呢?
把握住这三点即可:

In state verification you have the object under testing perform a certain operation, after being supplied with all necessary collaborators. When it ends, you examine the state of the object and/or the collaborators, and verify it is the expected one.
In behaviour verification, on the other hand, you specify exactly which methods are to be invoked on the collaboratos by the SUT, thus verifying not that the ending state is correct, but that the sequence of steps performed was correct.

Mock 和 Stub 的区别在于,前者是行为,后者是状态。基于 Mock 做的是 behavior-based verification, 基于 Stub 做的是 State-based verification,这跟验证的方法有关。而 Mock 和 Fake 的区别在于,你在写单测的时候,需不需要构建出一个 working implementation,还是说只要预设一些行为的响应即可。

当然啦,这些概念都是一些阳春白雪的东西,实际工作中,还是需要适当接地气一些,比如:跟普通码农打交道的时候,说Mock就够了,跟普通测试人员就说”打桩“。

常用工具

        <dependency>
            <groupId>org.mock-server</groupId>
            <artifactId>mockserver-netty</artifactId>
            <version>5.15.0</version>
        </dependency>

MockServer就是上文提到的Stub,使用场景举例:模拟一个微信公众号的后台响应。

        <dependency>
            <groupId>it.ozimov</groupId>
            <artifactId>embedded-redis</artifactId>
            <version>0.7.3</version>
        </dependency>

这是一个典型的Fake,能够实现基本的Redis操作,但是某些高阶特性,比如Stream还是无法实现。

        <dependency>
            <groupId>com.wix</groupId>
            <artifactId>wix-embedded-mysql</artifactId>
            <version>4.6.2</version>
        </dependency>

比H2强大不少,可以指定MySQL版本,5.7非常好用,8.0.x貌似有bug,推荐MariaDB4j。

        <dependency>
            <groupId>ch.vorburger.mariaDB4j</groupId>
            <artifactId>mariaDB4j-springboot</artifactId>
            <version>3.0.1</version>
            <scope>test</scope>
        </dependency>

又一个非常好用的一个Fake,目前默认数据库版本是10.2.11,与Flyway等数据库工具配合使用时需要注意版本支持情况,推荐使用8.5.x版本。

        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>testcontainers</artifactId>
            <version>1.19.1</version>
        </dependency>
        <dependency>
            <groupId>org.testcontainers</groupId>
            <artifactId>mysql</artifactId>
            <version>1.19.1</version>
        </dependency>

基于Docker镜像,可以实现各种Fake,有兴趣的童鞋可以自行了解下。

        <dependency>
            <groupId>de.flapdoodle.embed</groupId>
            <artifactId>de.flapdoodle.embed.mongo.spring31x</artifactId>
            <version>4.9.3</version>
        </dependency>

MongoDB的一个老牌Fake了,注意区分2x和3x版本。

知识扩展

参考资料

上一篇 下一篇

猜你喜欢

热点阅读