怎样编写测试类测试分支_编写干净的测试–从配置开始

怎样编写测试类测试分支

很难为干净的代码找到一个好的定义,因为我们每个人都有自己的单词clean的定义。 但是,有一个似乎是通用的定义:

简洁的代码易于阅读。

这可能会让您感到有些惊讶,但我认为该定义也适用于测试代码。 使测试尽可能具有可读性是我们的最大利益,因为:

  • 如果我们的测试易于阅读,那么很容易理解我们的代码是如何工作的。
  • 如果我们的测试易于阅读,那么如果测试失败(不使用调试器),很容易发现问题。

编写干净的测试并不难,但是需要大量的实践,这就是为什么如此多的开发人员为此苦苦挣扎的原因。

我也为此感到挣扎,这就是为什么我决定与您分享我的发现的原因。

这是本教程的第一部分,介绍了如何编写干净的测试。 这次,我们将学习如何以简单干净的方式配置测试用例。

问题

假设我们必须使用Spring MVC Test框架为Spring MVC控制器编写“单元测试”。 我们要测试的第一个控制器称为TodoController ,但是我们还必须为应用程序的其他控制器编写“单元测试”。

作为开发人员,我们知道重复的代码是一件坏事。 在编写代码时,我们遵循“ 不要重复自己(DRY)”原则 ,该原则指出:

每条知识都必须在系统中具有单一,明确,权威的表示形式。

我怀疑这是开发人员经常在其测试套件中使用继承的原因之一。 他们将继承视为重用代码和配置的廉价且简便的方法。 这就是为什么他们将所有通用代码和配置放在实际测试类的基类中的原因。

让我们看看如何使用该方法配置“单元测试”。

首先 ,我们必须创建一个抽象基类, 该基类可以配置Spring MVC Test框架,并通过实现setUpTest(MockMvc mockMvc)方法来确保其子类可以提供其他配置。

AbstractControllerTest类的源代码如下所示:

import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {WebUnitTestContext.class})
@WebAppConfiguration
public abstract class AbstractControllerTest {private MockMvc mockMvc;@Autowiredprivate WebApplicationContext webAppContext;@Beforepublic void setUp() {mockMvc = MockMvcBuilders.webAppContextSetup(webAppContext).build();setupTest(MockMvc mockMvc)}protected abstract void setUpTest(MockMvc mockMvc);
}

其次 ,我们必须实现实际的测试类,该类创建所需的模拟和新的控制器对象。 TodoControllerTest类的源代码如下所示:

import org.mockito.Mockito;
import org.springframework.test.web.servlet.MockMvc;public class TodoControllerTest extends AbstractControllerTest {private MockMvc mockMvc;@Autowiredprivate TodoService serviceMock;@Overrideprotected void setUpTest(MockMvc mockMvc) {Mockito.reset(serviceMock);this.mockMvc = mockMvc;}//Add test methods here
}

这个测试类看起来很干净,但是有一个主要缺陷:

如果我们想了解测试用例的配置方式,我们必须阅读TodoControllerTestAbstractControllerTest类的源代码。

这似乎是一个小问题,但这意味着我们必须将注意力从测试用例转移到基类(或多个类)上。 这需要精神上的上下文切换,并且上下文切换非常昂贵

您可能当然会争辩说,在这种情况下使用继承的精神代价很低,因为配置非常简单。 的确如此,但是要记住,现实生活中的情况并非总是如此。

上下文切换的实际成本取决于测试类层次结构的深度和配置的复杂性。

解决方案

我们可以通过配置测试类中的所有测试用例来提高配置的可读性。 这意味着我们必须:

  • 将所需的注释(例如@RunWith )添加到测试类。
  • 将设置和拆卸方法添加到测试类。

如果我们遵循以下规则修改示例测试类,则其源代码如下:

import org.junit.Before;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {WebUnitTestContext.class})
@WebAppConfiguration
public class TodoControllerTest {private MockMvc mockMvc;@Autowiredprivate TodoService serviceMock;@Autowiredprivate WebApplicationContext webAppContext;@Beforepublic void setUp() {Mockito.reset(serviceMock);mockMvc = MockMvcBuilders.webAppContextSetup(webAppContext).build();}//Add test methods here
}

在我看来,我们的测试用例的新配置看起来比旧的配置简单且干净得多,旧的配置分为TodoControllerTestAbstractControllerTest类。

不幸的是,没有什么是免费的。

这是一个权衡

每个软件设计决策都需要权衡利弊。 这不是该规则的例外

在测试类中配置我们的测试用例具有以下好处:

  1. 我们无需阅读测试类的所有超类就可以了解测试用例的配置。 这样可以节省大量时间,因为我们不必将注意力从一堂课转移到另一堂课。 换句话说, 我们不必付出上下文切换的代价
  2. 当测试失败时,可以节省时间。 如果为了避免重复的代码或配置而使用继承,则很可能我们的基类将包含与某些但不是全部测试用例相关的组件。 换句话说,我们将弄清楚哪些组件与失败的测试用例相关,这可能不是一件容易的事。 在测试类中配置测试用例时, 我们知道每个组件都与失败的测试用例有关

另一方面,这种方法的缺点是:

  1. 我们必须编写重复的代码。 这比将所需的配置放到一个或多个基类上花费的时间更长。
  2. 如果任何使用的库以迫使我们修改测试配置的方式进行更改,则我们必须对每个测试类进行必要的更改。 这显然比仅对基类(或多个基类)进行这些操作要慢得多。

如果我们唯一的目标是尽可能快地编写测试,那么很明显,我们应该消除重复的代码和配置。

但是,这不是我唯一的目标。

我认为这种方法的优点胜于缺点的原因有两个:

  1. 继承不是重用代码或配置的正确工具 。
  2. 如果测试用例失败,我们必须尽快找到并解决问题,并且干净的配置将帮助我们实现该目标。

我在这件事上的立场是明确的。 但是,仍然存在一个非常重要的问题:

您会做出其他折衷吗?

翻译自: https://www.javacodegeeks.com/2014/05/writing-clean-tests-it-starts-from-the-configuration.html

怎样编写测试类测试分支

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/341325.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python 数据处理----读取txt 一列数据写入excel 文件

将txt数据从某一行开始写入excel文件中(例子为从Appthroughput写至excel_result1.xlsx中) import sys import random import time import xlwt import codecsdef Txt_to_Excel(wb,inputTxt,start_row,start_col):fr codecs.open(inputTxt,r)line_numbe…

CCF CSP 201403-1 相反数(C++)

题目 问题描述 有 N 个非零且各不相同的整数。请你编一个程序求出它们中有多少对相反数(a 和 -a 为一对相反数)。 输入格式 第一行包含一个正整数 N。(1 ≤ N ≤ 500)。   第二行为 N 个用单个空格隔开的非零整数,每个数的绝对值不超过1000,保证这些整数各不相同。 输出…

硒等待:内隐,外显,流利和睡眠

Selenium等待页面加载在Selenium脚本中起着重要的作用。 它们有助于使它们不易剥落,更可靠。 Selenium提供多次等待,以根据某些条件在脚本执行中提供足够的等待或暂停。 从而确保您在使用Selenium执行自动化测试时不会导致脚本失败。 在本教程中&#xf…

python多个变量的for循环

当for循环有两个需要迭代的对象时,要用zip对这多个变量封装,否则会报错“too many values to unpack” 错误的例子: starts [0,1,2,3,4]ends [5,6,7,8,9]for start, end in starts, ends:print((start, end)) 正确的例子: sta…

1040 有几个PAT(PAT乙级 C++)

题目 字符串 APPAPT 中包含了两个单词 PAT,其中第一个 PAT 是第 2 位(P),第 4 位(A),第 6 位(T);第二个 PAT 是第 3 位(P),第 4 位(A),第 6 位(T)。 现给定字符串,问一…

在win10+Ubuntu双系统下,完美卸载Ubuntu

本文为转载博客,亲测有效 背景 机器:惠普 暗影精灵3 win10与Ubuntu16.04均为UEFI分区 清除ubuntu系统 使用软件:diskgenius   删除Ubuntu系统使用的几个分区(包括EFI分区),注意不要删除Windows的EFI分…

1048 数字加密(PAT乙级 C++)

题目 本题要求实现一种数字加密方法。首先固定一个加密用正整数 A,对任一正整数 B,将其每 1 位数字与 A 的对应位置上的数字进行以下运算:对奇数位,对应位的数字相加后对 13 取余——这里用 J 代表 10、Q 代表 11、K 代表 12&…

在浏览器中在线尝试无服务器框架项目!

无服务器框架是无服务器工具的一致领导者。 但是,没有简单的方法可以在线试用无服务器框架项目。 您确实需要一个体面的开发人员设置,并且需要一些工作来设置sls , npm等。 确切地说,您做到了 –直到现在。 无服务器项目–在您的…

Dev C++源代码未编译

从DevC官网下载的编译器,结果编译程序没问题,但是运行程序时显示源文件未编译。 尝试很多方法。(官网下载不一定最佳)最后通过在其他网站下载重装DevC问题得以解决。 后一个DevC下载网址: https://pc.qq.com/detail/1…

1051 复数乘法(PAT乙级 C++)

题目 复数可以写成 (ABi) 的常规形式,其中 A 是实部,B 是虚部,i 是虚数单位,满足 i​2​​ −1;也可以写成极坐标下的指数形式 (Re​(Pi)),其中 R 是复数模,P 是辐角,i 是虚数单位&…

java se/ee_嗨,您好 。 。 ! 您如何评价Java / Java EE技能?

java se/ee要知道,就是要知道你一无所知。 那就是真正知识的含义。 苏格拉底 这篇文章旨在为读者提供Java生态系统及其技术堆栈的快速概述。 老实说,从Java EE 7,Java SE 8到Java Embedded 8…,Java平台进行了许多革命性的更改…

SystemC在Ubuntu16.04上安装测试

使用SystemC进行硬件仿真 环境 linux-x86-64bashg 下载解压SystemC SystemC下载地址 解压下载的包 tar zxvf systemc-2.3.3.tar.gz 进入解压出来的目录,准备编译安装 cd systemc-2.3.3 编译安装 打开安装说明文件INSTALL vim INSTALL 按照步骤安装 Create a tem…

1053 住房空置率(PAT乙级 C++ 坑点分析)

题目 在不打扰居民的前提下,统计住房空置率的一种方法是根据每户用电量的连续变化规律进行判断。判断方法如下: 在观察期内,若存在超过一半的日子用电量低于某给定的阈值 e,则该住房为“可能空置”;若观察期超过某给…

Java:从Java 8开始受益于内联类属性

希望在几年内,Java将具有“内联类”功能,该功能可以解决Java当前状态下的许多挑战。 阅读本文并学习如何立即使用Java 8或更高版本,并且仍将受益于即将出现的内联对象数组的一些优点,例如; 没有间接指针,消…

1054 求平均值(PAT乙级 C++)

题目 本题的基本要求非常简单:给定 N 个实数,计算它们的平均值。但复杂的是有些输入数据可能是非法的。一个“合法”的输入是 [−1000,1000] 区间内的实数,并且最多精确到小数点后 2 位。当你计算平均值的时候,不能把那些非法的数…

ubuntu16.04下安装ibus拼音

按照网上给的安装方法,没成功,在切换ibus的时候总是报错,记录下解决办法。 安装语言包 System Settings–>Language Support–>Install/Remove Languages 选中chinese,点击Apply应用即可,等待下载安装完成。 …

1057 数零壹(PAT乙级 C++实现)

题目 给定一串长度不超过 10​5 的字符串,本题要求你将其中所有英文字母的序号(字母 a-z 对应序号 1-26,不分大小写)相加,得到整数 N,然后再分析一下 N 的二进制表示中有多少 0、多少 1。例如给定字符串 P…

解决Ubuntu中sublime无法输入中文的问题

主要目的: 安装 Sublime Text 3 安装 Fcitx 输入法 皮肤 修复 Sublime Text 3 在 Ubuntu(Debian) 系统下的无法输入中文(CJK 字符)输入法的问题 注意: 这个修复仅当在终端中使用 subl . 调用 Sublime Text 的时有效, 具体原因请看源代码src/s…

java编程访问hdfs_以编程方式访问Java基本类型的大小

java编程访问hdfs许多不熟悉Java的开发人员首先要了解的一件事是Java的基本原始数据类型 ,其固定(与平台无关)的大小(以位或字节为单位用二进制补码表示 )以及它们的范围(Java中所有数字类型都是带符号的&a…

1059 C语言竞赛(PAT乙级 C++)

题目 C 语言竞赛是浙江大学计算机学院主持的一个欢乐的竞赛。既然竞赛主旨是为了好玩,颁奖规则也就制定得很滑稽: 0、冠军将赢得一份“神秘大奖”(比如很巨大的一本学生研究论文集……)。1、排名为素数的学生将赢得最好的奖品 —…