怎样编写测试类测试分支_编写干净的测试–从配置开始
怎样编写测试类测试分支
很难为干净的代码找到一个好的定义,因为我们每个人都有自己的单词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
}
这个测试类看起来很干净,但是有一个主要缺陷:
如果我们想了解测试用例的配置方式,我们必须阅读TodoControllerTest和AbstractControllerTest类的源代码。
这似乎是一个小问题,但这意味着我们必须将注意力从测试用例转移到基类(或多个类)上。 这需要精神上的上下文切换,并且上下文切换非常昂贵 。
您可能当然会争辩说,在这种情况下使用继承的精神代价很低,因为配置非常简单。 的确如此,但是要记住,现实生活中的情况并非总是如此。
上下文切换的实际成本取决于测试类层次结构的深度和配置的复杂性。
解决方案
我们可以通过配置测试类中的所有测试用例来提高配置的可读性。 这意味着我们必须:
- 将所需的注释(例如@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
}
在我看来,我们的测试用例的新配置看起来比旧的配置简单且干净得多,旧的配置分为TodoControllerTest和AbstractControllerTest类。
不幸的是,没有什么是免费的。
这是一个权衡
每个软件设计决策都需要权衡利弊。 这不是该规则的例外 。
在测试类中配置我们的测试用例具有以下好处:
- 我们无需阅读测试类的所有超类就可以了解测试用例的配置。 这样可以节省大量时间,因为我们不必将注意力从一堂课转移到另一堂课。 换句话说, 我们不必付出上下文切换的代价 。
- 当测试失败时,可以节省时间。 如果为了避免重复的代码或配置而使用继承,则很可能我们的基类将包含与某些但不是全部测试用例相关的组件。 换句话说,我们将弄清楚哪些组件与失败的测试用例相关,这可能不是一件容易的事。 在测试类中配置测试用例时, 我们知道每个组件都与失败的测试用例有关 。
另一方面,这种方法的缺点是:
- 我们必须编写重复的代码。 这比将所需的配置放到一个或多个基类上花费的时间更长。
- 如果任何使用的库以迫使我们修改测试配置的方式进行更改,则我们必须对每个测试类进行必要的更改。 这显然比仅对基类(或多个基类)进行这些操作要慢得多。
如果我们唯一的目标是尽可能快地编写测试,那么很明显,我们应该消除重复的代码和配置。
但是,这不是我唯一的目标。
我认为这种方法的优点胜于缺点的原因有两个:
- 继承不是重用代码或配置的正确工具 。
- 如果测试用例失败,我们必须尽快找到并解决问题,并且干净的配置将帮助我们实现该目标。
我在这件事上的立场是明确的。 但是,仍然存在一个非常重要的问题:
您会做出其他折衷吗?
翻译自: https://www.javacodegeeks.com/2014/05/writing-clean-tests-it-starts-from-the-configuration.html
怎样编写测试类测试分支
怎样编写测试类测试分支_编写干净的测试–从配置开始相关推荐
- Java编写学生类student程序_编写一个JAVA程序片断定义一个表示学生的类student.docx...
编写一个JAVA程序片断 定义一个表示学生的类student,包括域"学号","班级","姓名","性别"," ...
- 怎样编写测试类测试分支_编写干净的测试–天堂中的麻烦
怎样编写测试类测试分支 如果我们的代码有明显的错误,我们很有动力对其进行改进. 但是,在某些时候,我们认为我们的代码"足够好"并继续前进. 通常,当我们认为改进现有代码的好处小于所 ...
- 怎样编写测试类测试分支_编写干净的测试-被认为有害的新内容
怎样编写测试类测试分支 很难为干净的代码找到一个好的定义,因为我们每个人都有自己的单词clean的定义. 但是,有一个似乎是通用的定义: 简洁的代码易于阅读. 这可能会让您感到有些惊讶,但我认为该定义 ...
- 对编写的代码进行单元测试_编写数据访问代码测试–单元测试是浪费
对编写的代码进行单元测试 几年前,我是为我的数据访问代码编写单元测试的那些开发人员之一. 我正在孤立地测试所有内容,我对自己感到非常满意. 老实说,我认为自己做得很好. 哦,男孩,我错了! 这篇博客文 ...
- java测试类写三角形_软件测试实验一——使用junit判断三角形
一.简单描述下安装 junit, hamcrest and eclemma的过程 ①当然,有了eclipse软件,安装的过程会显得比较轻松 对于安装junit和hamcrest来说需要在官网(或者其它 ...
- 监听器内加了测试类导致测试类无法运行:java.lang.ClassCastException: 测试类 cannot be cast to 监听器
正常是可以运行的 如果加了测试类到监听类中,就报下面的错误 SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder&qu ...
- java测试类生成对象,java编写student类 用Java编写一段测试程序,生成student类的两个对象,并输出每个对象基本信息?...
java中怎么创建对象数组?比如我创建了一个学生类Student,怎么用这个类创建一个对象数组,麻烦给个例子? 学生类:classA{privateStringnameprivateintagepub ...
- guava集合操作类的使用_使用Guava进行测试集合的实现
guava集合操作类的使用 我目前正在为LibFX添加一项新功能,为此我创建了一些类似于Java Collections Framework的自定义集合. 我一直在寻找可以与之对抗的测试,并很高兴发现 ...
- java请编写公共类继承抽象类_(Java相关)怎么理解抽象类,继承和接口?
著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 作者:海子 来源:博客园 一.抽象类 在了解抽象类之前,先来了解一下抽象方法.抽象方法是一种特殊的方法:它只有声明,而没有具体的 ...
最新文章
- 聊一聊:开源社区应该用中文吗?
- Linux中的gdb调试方法总结
- C#调用WebService实例和开发
- 人人都是 DBA(V)SQL Server 数据库文件
- 适合入门代码审计之熊海cms
- python matplotlib数据可视化_Python - matplotlib 数据可视化
- HTTP 错误 403.6 - Forbidden 解决方案
- thinkphp 个别字段无法更新_ThinkPHP setField 方法更新个别字段的值
- oracle错误代码及解决办法整合
- python+Selenium之操作滚动条
- 上位机与西门子PLC通信协议
- Java1.8开始为什么用元空间替换永久代
- 微信小程序加入购物车效果动画
- 基础会计习题集(第五版-樊
- 16S测序 生物信息数据处理
- Chrome 去掉“该网站的安全证书不受信任!”的提示
- MIUI13来了,米粉们还期待吗?
- 昆石VOS2009/VOS3000 2.1.6.00 操作指南
- 阿里达摩院开源DAMO-YOLO:兼顾速度与精度的新目标检测框架
- OpenCV每日函数 图像处理模块 applyColorMap颜色映射函数