单元测试(UT)、功能测试(FT)(转)

纯个人总结:

单元测试(UT)、功能测试(FT)

目的:1、尽量避免写的代码测试人员频繁的来找你其他地方又出问题了;2、提供的接口不可用;3、一个bug修复了引入了其他的bug或者其他用例变红了;

理解:在实现函数功能的时候编写对应的测试代码,尽量保证”输入-输出”的正确性,在测试用例比较多的时候对系统有强身健体的功效,适用的人群是:非大牛者

优点:

保证函数基本功能

修改代码后批量跑UT保证修改的代码对其他逻辑无影响

修复bugs后增加用例代码,更加强壮

有利于代码重构

可以支持nightly build,检验前天代码质量,检查代码覆盖率

测试代码是函数的说明书,轻文档

减少bugs数量和排查修复时间精力

缺点:

需要花时间去搭建一个测试代码平台和维护

前期需要很多的时间维护UT,FT代码(但后期系统越大作用越明显)

 

不适合使用的或者作用微小的场景

小项目,内容少一个人就能把握全部细节

记忆力合理都很棒的牛人,写每句代码都了如执掌,就不用浪费精力写ut了

已经记录好久且项目大的工程,一直没ut,突然闻到理解到ut 的作用就想开始的,晚了

不喜欢敏捷思想的,就算开始了ut工程,后面会因为没维护而成为拖累和一滩项目死水,也别使用,以免成为敏捷的悲观者

 

http://blog.csdn.net/linxuping/article/details/16968141

Java单元测试框架与实践
本文首先在理论上归纳了单元测试在宏观和微观层面要遵循的基本原则,以及测试覆盖率的要求和评价维度。然后具体阐述了笔者实战中总结的基于Junit + Mockito 的单元测试框架和具体实施方法,并给出了相应的demo代码。

本文主要参考和引用了《码出高效:Java开发手册》,Junit5、mockito等官方文档以及若干篇相关博客的内容,具体可见文末参考链接部分。

基本原则
宏观层面:AIR原则
A:Automatic(自动化)
全自动执行,输出结果无需人工检查,而是通过断言验证。
I:Independent(独立性)
分层测试,各层之间不相互依赖。
R:Repeatable(可重复)
可重复执行,不受外部环境( 网络、服务、中间件等)影响。
微观层面:BCDE原则
B: Border,边界值测试,包括循环边界、特殊取值、特殊时间点、数据顺序等。
C: Correct,正确的输入,并得到预期的结果。
D: Design,与设计文档相结合,来编写单元测试。
E : Error,单元测试的目标是证明程序有错,而不是程序无错。为了发现代码中潜在的错误, 我们需要在编写测试用例时有一些强制的错误输入(如非法数据、异常流程、非业务允许输入等)来得到预期的错误结果。
Mock
由于单元测试只是系统集成测试前的小模块测试,有些因素往往是不具备的,因此需要进行Mock。例如:

功能因素。比如被测试方法内部调用的功能不可用。
时间因素。比如双十一还没有到来,与此时间相关的功能点。
环境因素。政策环境,如支付宝政策类新功能,多端环境, 如PC 、手机等。
数据因素。线下数据样本过小,难以覆盖各种线上真实场景。
覆盖率要求
粗粒度覆盖:类覆盖率和方法覆盖率应达到100%。
细粒度覆盖:行覆盖、分支覆盖、条件判定覆盖、路径覆盖等,相应的覆盖率应考虑上述原则与因素。
https://blog.csdn.net/weixin_43098787/article/details/103492636

https://1991421.cn/2019/04/21/71b0d191/

 

准备数据-》Given
执行-》When
验证-》Then

 

JUnit 5 刚出来那时,也就是第一个版本 5.0.0 时,还不能很好的支持 Mockito 的测试,因为 Mockito 没能跟得那么紧密。那时候 JUnit 5 只能试验性的提供了一个极不正式的 com.example.mockito.MockitoExtension, 看那包名就知道不是来真的,所以决定再等。JUnit 5 不再原生支持 JUnit 4 的 Rule,一切都将是 Extension,那也是要求 Mockito 能够与之俱进。现在等来了,JUnit 5 进化到了 5.2.0, Mockito 也早已有了一个单独的模块 mockito-junit-jupiter 来迎接它。

在 Mockito 2.1.0 的 What's new in Mockito 2 中记述了 JUnit 5 为 Mockito 2 开发了一个 MockitoExtension。追溯到 Mockito 2 的 Release Notes, 我们发现 Mockito 2 官方最早引入 MockitoExtension 的版本是 2.16.3(2018-03023)。我对 Mockito 对 JUnit 5 支持的最新更新是从这个 Pull Request MockitoExtension for JUnit5 得知的。

一句话讲就是现在的 Mockito 2 有原生态的 MockitoExtension 来支援 JUnit 5, 可以非常放心可靠的让 JUnit 5 和 Mockito 2 一起稳定工作。因此前面那个包名带 example 字样的 MockitoExtension 链接也就无效了。

下面来体验一下那个 MockioExtension,测试当中需要的依赖包含 junit-jupiter-engine 和 mockito-junit-jupiter

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.2.0</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>2.18.3</version>
    <scope>test</scope>
</dependency>

都取了当前在 Maven 中央仓库的最新版本。

在 IntelliJ IDEA 2018.1.3 版本中运行接下来的测试用例,连 jnit-jupiter-engine 都可以不要,看来 IntelliJ IDEA 自带了 jupiter-api 实现。Maven 命令可不行,而且 Maven 还要插件依赖 junit-platform-surefire-provider 才能执行。

首先我们要有一个被测试类 UserService

public class UserService {
    private List<String> users;
 
    public UserService(List<String> users) {
       this.users = users;
    }
 
    public void addUser(String name) {
        users.add(name);
    }
}

然后创建它的测试用例 UserServiceTest

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
 
import java.util.List;
 
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
 
@ExtendWith(MockitoExtension.class)
public class UserServiceTest {
 
    @Mock
    private List<String> users;
 
    @InjectMocks
    private UserService userService;
 
    @Test
    @DisplayName("Should add a user to list")
    public void shouldAddUserToList() {
        userService.addUser("hello");
 
        verify(users, times(1)).add("hello");
    }
}

JUnit 5 下只能用 @ExtendWith, 找不到 @RunWith 了,虽然 MockitoJUnitRunner 还在,可它是为 JUnit 4 准备的。
一切工作正常,方法被 Mock, Mock 对象自动被注入,@DisplayName 也正常显示

若要用 mvn test 在控制台下运行测试用例,还要为 maven-surefire-plugin 加上一个内部依赖,在 pom.xml 文件中

<build>
    <plugins>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.21.0</version>
            <dependencies>
                <dependency>
                    <groupId>org.junit.platform</groupId>
                    <artifactId>junit-platform-surefire-provider</artifactId>
                    <version>1.2.0</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

然后执行控制台命令

$ mvn test

 

控制台下仍然是不会显示 @DisplayName 指定的描述。

至此为 JUnit 5 与 Mockito 2 工作扫清了一个障碍。可是刚刚偶然间用 Java 10 跑了一下 mvn test 来运行这个例子,出问题了,Java 8, 9 相继被 Oracle 放弃了,离 Java 10 真会越来越远了。

https://yanbin.blog/junit-5-work-with-mockito-2/

项目地址:https://github.com/alibaba/testable-mock
文档:https://alibaba.github.io/testable-mock/

https://www.cnblogs.com/itwild/p/14111830.html

史上最轻量​!阿里新型单元测试Mock工具开源了
https://mp.weixin.qq.com/s/KyU6Eu7mDkZU8FspfSqfMw


实际项目中如何开展单元测试?最后我要跟你聊一下,实际软件项目中如何开展单元测试?并不是所有的代码都要进行单元测试,通常只有底层模块或者核心模块的测试中才会采用单元测试。
你需要确定单元测试框架的选型,这和开发语言直接相关。比如,Java 最常用的单元测试框架是 Junit 和 TestNG;C/C++ 最常用的单元测试框架是 CppTest 和 Parasoft C/C++test;框架选型完成后,你还需要对桩代码框架和 Mock 代码框架选型,选型的主要依据是开发所采用的具体技术栈。
通常,单元测试框架、桩代码 /Mock 代码的选型工作由开发架构师和测试架构师共同决定。为了能够衡量单元测试的代码覆盖率,通常你还需要引入计算代码覆盖率的工具。
不同的语言会有不同的代码覆盖率统计工具,比如 Java 的 JaCoCo,JavaScript 的 Istanbul。在后续的文章中,我还会详细为你介绍代码覆盖率的内容。
最后你需要把单元测试执行、代码覆盖率统计和持续集成流水线做集成,以确保每次代码递交,都会自动触发单元测试,并在单元测试执行过程中自动统计代码覆盖率,最后以“单元测试通过率”和“代码覆盖率”为标准来决定本次代码递交是否能够被接受。如果你有开发背景,那么入门单元测试是比较容易的。
但真正在项目中全面推行单元测试时,你会发现还有一些困难需要克服:紧密耦合的代码难以隔离;隔离后编译链接运行困难;代码本身的可测试性较差,通常代码的可测试性和代码规模成正比;无法通过桩代码直接模拟系统底层函数的调用;代码覆盖率越往后越难提高。
https://time.geekbang.org/column/article/10275


posted @ 2014-10-24 14:49  沧海一滴  阅读(6094)  评论(0编辑  收藏  举报