基于测试概念进行代码设计的七条基本原则(转帖)

2024-02-16 01:18

本文主要是介绍基于测试概念进行代码设计的七条基本原则(转帖),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

当设计大型程序的时候,您必须时刻留心不同设计选项对诸如性能和可扩展性这样的特征的影响。随着软件产品的日渐复杂及其无所不在的部署,软件的“可测试性”也成了更重要的考虑事项。

彻底测试代码的重要性是显然的。花在编写测试和测试代码上的时间和精力给您带来的回报是维护成本的大幅降低。

然而,除非您很小心,否则您花在测试代码上的精力可能会首先达到花在编写代码上的精力的几倍!我曾看到程序员们齐心协力地对他们的全部代码进行单元测试,结果花在上面的时间使大多数人都以沮丧而告终。

幸运的是,没有必要这样。在您设计软件的时候应用一些基本原则,编写易于测试、甚至使测试成为乐趣的代码是可能的。

跟其它编码原则一样,这些原则也不是不容置疑或不可改变的教条。有时候打破这些规则也是必要的。因此,理解每条原则背后的动机和判断何时这些动机不适用(或应让位给更关心的问题)的能力是很重要的。

原则1:到GUI视图的外面去

尽可能把代码移到GUI视图的外面。然后各种GUI动作就能成了模型上的简单方法调用。为什么您需要这样做呢?

对GUI测试者来说,通过方法调用测试功能比间接地测试功能容易的多。

另一个好处是它使修改程序功能而不影响视图变的更容易。

当然,视图中也可能存在错误。在理想情况下,对程序的测试将同时检查模型和视图。

原则2:使用类型进行错误检查

类型是您的朋友 — 尽可能多地用类型系统自动检查错误。

类型能在程序运行之前自动捕捉程序中的错误。没有静态类型检查的话,类型错误将作为破坏者逗留在您的程序中,直到恰当的执行路径碰巧把它揭露出来为止。

最大限度地发挥使用类型的长处是棘手的。通常,一组数据结构可以在一个抽象级别上一起使用,或者被分出,成为一个单一的、更高抽象级别的一个新的相关数据类型。

事实上,编程语言自身的历史可以看成是可以编程的抽象级别的逐渐提高。汇编语言提供了比特到整数和浮点数的抽象。接下来是记录和函数抽象,然后又是诸如对象、类、线程以及异常这样的抽象。

在每一抽象级别上,达到与更高级别抽象一致的功能是可能的,但那实质上仅仅是耗费更多精力,冒更多的错误风险。

在面向对象语言(其它现代语言也一样)中,一个程序员在设计抽象上有很大的灵活性。在哪个抽象级别上设计程序就成了基于折衷的决定,比如由抽象级别提供的更多的健壮性和由于不能在更低抽象级别上工作而带来的表达性(有时是性能)的损失。

通常,高级别抽象带来的健壮性和简单性的价值很少被其它考虑事项超过。

原则3:使用调节器避免“故障线路”(fault line)

我用“故障线路”来指独立组件之间的接口,独立组件之间和组件与其相应子组件之间相比,很少有交互。这种故障线路的一个典型示例是 GUI 视图和它的模型之间的接口。其它示例包括在编译器中处理的不同阶段之间的接口或操作系统的内核和用户界面之间的接口。

找出程序的故障线路,然后用具有转发功能的调节器快速访问聚合组件。

沿着故障线路隔离测试每个组件通常更容易。但如果每个组件暴露的对象有很多,或者组件中您想测试的一些对象只有通过多个嵌套引用才能访问,那么测试就会变的很乏味。

不用隔离测试,而是拥有您在它上面调用您想测试的各种方法的单个调节器对象通常是有帮助的。这个对象然后能把这些方法调用转发到适当的地方。

沿着相同线路,设计和自己的测试代码串联在一起的程序组件接口是有益的。这将使您把注意力集中在使这些接口尽可能简单上。

原则4:方法:小型签名和缺省参数

使用小型方法说明和重载带缺省方法参数的方法将使您在测试中调用这些方法变的愉快的多。否则,在测试这些方法时您将不得不构造额外参数。如果参数很大,那么将很快导致代码膨胀。更糟的是,它会诱使您编写比在其它情况下更少的测试。

原则5:访问器不应修改内存状态

请在您的测试中使用不修改内存状态的访问器来检查对象状态。

在某些方面,测试和实验室试验相似。它们都想证明特定假设有效。如果特定检查动作改变了该领域的状态,那么要这样做会变得困难的多。

与量子力学领域不同,计算机进程的状态可以不修改就被检查。使用这种原则对您有好处。

原则6:用接口说明外部程序组件

用接口说明外部程序组件使得我们可以容易地在测试案例中模拟这些组件。

这条原则能节省大量时间,特别是当外部组件的实现还未完成时。通常,大多数基本组件都不能准时可用。如果这些组件不在适当位置您就不能测试您自己的代码的话,那么您就在朝灾难走去。您的客户不会关心您只有两个小时来集成迟到了两周的组件。他们知道的全部就是整套产品被延期了和这是违约的。

原则7:优先编写测试代码

优先编写测试代码。这是标准的XP方法,但却总有一种忽视它的诱惑。

每次我屈服于这种诱惑时,我都感到后悔。假设您正努力生产正确的代码,那么您好象能从推迟编写测试代码中节省的时间其实只是一个幻想。

注意:这不是说您应该一次性编写全部测试代码后,再一次性全部实现。编写一些测试代码,实现它们,再编写一些测试代码,再实现它们等等是个更好的办法。设计以这种方式得以进展;在实现阶段捕捉错误并在下一组测试中改正它。以这种方式编写测试也更少会使人畏缩。

代码比您需要的还多?

只需一点点努力,就可能容易地对任何程序进行彻底的测试。当然,不可避免存在这些原则不适用的情况;于是,看起来好像不可能对功能进行测试。

当出现这些情况时,我尽力退一步地看这个问题,“我怎样才可能测试这种代码?”相反地,我问自己,“我怎样才能以可测试方式编写这些代码呢?”这种想法上的改变的结果经常是增加了大量 仅仅服务于简化测试的功能。

什么?别担心!出现这种情况完全正常。

就象很多现有的设计模式,它们只是为了增加程序的可扩展性就往程序中添加很多类(例如 visitor、decorator 等等),开发简化测试的新模式是可以接受的。实际上,面向对象语言的很多特征都是为了简化扩展而包含进去的;为什么语言的未来版本(或全新的语言)不应包含简化测试的特征。

对 Java 语言来说,这已经开始。人们计划在未来版本中包含很多更强大的类型系统、断言(assertion)等等。就象面向对象的语言已经增加了我们重用和扩展现有代码的程度,将来,面向测试的设计和特征将帮助我们增强新老代码的健壮性。

这篇关于基于测试概念进行代码设计的七条基本原则(转帖)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/713096

相关文章

Python Faker库基本用法详解

《PythonFaker库基本用法详解》Faker是一个非常强大的库,适用于生成各种类型的伪随机数据,可以帮助开发者在测试、数据生成、或其他需要随机数据的场景中提高效率,本文给大家介绍PythonF... 目录安装基本用法主要功能示例代码语言和地区生成多条假数据自定义字段小结Faker 是一个 python

SpringSecurity6.0 如何通过JWTtoken进行认证授权

《SpringSecurity6.0如何通过JWTtoken进行认证授权》:本文主要介绍SpringSecurity6.0通过JWTtoken进行认证授权的过程,本文给大家介绍的非常详细,感兴趣... 目录项目依赖认证UserDetailService生成JWT token权限控制小结之前写过一个文章,从S

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

Python使用自带的base64库进行base64编码和解码

《Python使用自带的base64库进行base64编码和解码》在Python中,处理数据的编码和解码是数据传输和存储中非常普遍的需求,其中,Base64是一种常用的编码方案,本文我将详细介绍如何使... 目录引言使用python的base64库进行编码和解码编码函数解码函数Base64编码的应用场景注意

用js控制视频播放进度基本示例代码

《用js控制视频播放进度基本示例代码》写前端的时候,很多的时候是需要支持要网页视频播放的功能,下面这篇文章主要给大家介绍了关于用js控制视频播放进度的相关资料,文中通过代码介绍的非常详细,需要的朋友可... 目录前言html部分:JavaScript部分:注意:总结前言在javascript中控制视频播放

Java进行文件格式校验的方案详解

《Java进行文件格式校验的方案详解》这篇文章主要为大家详细介绍了Java中进行文件格式校验的相关方案,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、背景异常现象原因排查用户的无心之过二、解决方案Magandroidic Number判断主流检测库对比Tika的使用区分zip