【tool】利用测试概念进行代码设计时的七条基本原则

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

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

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

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

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

  当然,视图中也可能存在错误。在理想情况下,对程序的测试将同时检查模型和视图。(想更多了解测试视图,请参阅我关于 Liar View 错误模式的文章或 Jeffries 等人的 Extreme Programming Installed。这两个链接都在参考资料部分。)

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

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

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

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

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

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

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

  通常,高级别抽象带来的健壮性和简单性的价值很少被其它考虑事项超过。(要了解对这个问题的更多讨论,请参阅我关于 Impostor Type 错误模式的文章,在参考资料部分有它的链接。)

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

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

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

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

利用测试概念进行代码设计时的七条基本原则[2]   软件测试

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  代码比您需要的还多?

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

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

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

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

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

时间: 2025-01-14 14:27:15

【tool】利用测试概念进行代码设计时的七条基本原则的相关文章

易于跨引擎和测试的游戏客户端代码设计方法

一.前言 本文讲的设计方法,不涉及算法.优化.接口讲解等技术介绍. 该设计方法基于MVC设计模式(主要是抽出控制类),而且本文主要面向游戏开发的一些问题. 该设计方法样例由python编写,但是实际上都是伪代码,有一点代码基础的问基本看得懂. 该设计方法由师兄教授,在项目使用过之后,感觉确实不错,特地提取一个方法论出来以记录. 二.MVC简介 在游戏开发中,目前用到架构主要分为MVC和ESC架构(这部分如有异议欢迎指正,有其他架构也希望能提出,博主也可以学习). 在一个功能复杂的模块中,通常会有

编写JAVA代码时的几条建议

1) 类名首字母应该大写.字段.方法以及对象(句柄)的首字母应小写.对于所有标识符,其中包含的所有单词都应紧靠在一起,而且大写中间单词的首字母.例如: ThisIsAClassName thisIsMethodOrFieldName 若在定义中出现了常数初始化字符,则大写static final基本类型标识符中的所有字母.这样便可标志出它们属于编译期的常数. Java包(Package)属于一种特殊情况:它们全都是小写字母,即便中间的单词亦是如此.对于域名扩展名称,如com,org,net或者e

进阶学习,如何无代码设计一款美观且实用的网站?

作为一门新兴的边缘性职业,网站设计既要从外观上创意,又要适当结合图形.版面及交互设计等相关原理,使得它成为一门独特且令人神往的艺术.毫无疑问,好的设计能让网站在诸多站点中脱颖而出,优秀的创意和表现方式能给浏览者留下深刻的印象,从而持续间接地增加网站访问流量和转换率.然而,要设计出一款兼顾"颜值和实用性"的个人/企业网站并不容易,更不用说让设计想法落地实现出来对大多数人说更是一项艰巨的任务. 那到底如何才能在时间和技能有限的情况下,设计出一款令人满意甚至网红的网站呢?小编认为,在设计的初

测试——《微服务设计》读书笔记

一.测试象限(Brain Marick) 二.测试金字塔(Mike Cohn)       1.单元测试 通常只测试一个函数或方法调用,通过TDD或者基于属性而写的测试就属于这一类,在UnitTest中,我们不会启动服务,对且对外部文件和网络连接的使用也很有限,通常我们需要大量的单元测试. 单元测试是帮助开发人员,是面向技术而非业务的.       2.服务测试 对于包含多个服务的系统,一个服务测试只测试其中一个单独服务的功能.只测试一个单独的服务可以提高测试的隔离性,这样我们可以更快地定位并解

WPF换肤之四:界面设计和代码设计分离

原文:WPF换肤之四:界面设计和代码设计分离 说起WPF来,除了总所周知的图形处理核心的变化外,和Winform比起来,还有一个巨大的变革,那就是真正意义上做到了界面设计和代码设计的分离.这样可以让美工和程序分开进行,而不是糅合在一块,这样做的好处当然也是显而易见的:提高了开发效率. 原先的设计方式 在我们之前设计的代码中,每当添加一个新的窗体的时候,我总是会在这个新的窗体的XAML文件中加入如下的代码,以便使样式能够应用上去: <Window x:Class="WpfApplicatio

新书《编写可测试的JavaScript代码 》出版,感谢支持

本书介绍 JavaScript专业开发人员必须具备的一个技能是能够编写可测试的代码.不管是创建新应用程序,还是重写遗留代码,本书都将向你展示如何为客户端和服务器编写和维护可测试的JavaScript代码. 从减少代码复杂性的方法,到单元测试.代码覆盖率.调试.以及自动化,您将全面学到如何编写让你和你同事能够轻松修复和维护的JavaScript代码.测试JavaScript代码是一个复杂的过程.本书将在很大程度上帮你简化该过程. 目标读者 本书主要目标受众是那些想成为JavaScript专业开发人

ActiveReports 9实战教程(2): 准备数据源(设计时、运行时)

在上讲中<ActiveReports 9实战教程(1): 手把手搭建环境Visual Studio 2013 社区版>,我们已经结合Visual Studio 2013搭建好了ActiveReports 9的开发环境,并完成了一个Hello World的RDL报表. 在本文,我们通过配置数据源进行报表实战,做过报表开发的报表达人知道,报表中的数据源分设计时数据源和运行时数据源. 如何理解呢? 这2类数据源,表结构是一样的,用途不一样: 1 设计时数据源,用于研发内部.报表小组进行配置.测试报表

Windows 窗体设计器中的设计时错误

在用 VS.NET进行窗体设计的时候,经常会遇到这样的问题:我们需要在构造函数或者在OnLoad事件中进行自己的一些初始化操作,比如连接一个数据库.调用一个资源文件或者后期绑定一个组件.如果代码通过编译,在运行时会执行得相当如你所愿.然而,当我们用窗体设计器打开这样一个窗体或者继承的窗体,IDE环境会抛出非常令人不愉快的异常,比如(NullReferenceException ). 究其原因,主要是窗体设计器在载入窗体时会自动初始化该对象,自动执行诸如构造函数.OnLoad方法和Initiali

概览 Windows Communication Foundation (WCF) 体系结构及其主要概念。代码示例演示 WCF 约定、终结点和行为

摘要:概览 Windows Communication Foundation (WCF) 体系结构及其主要概念.代码示例演示 WCF 约定.终结点和行为. 本页内容 简介 WCF 基础 代码示例 小结 简介 本文档提供 Windows Communication Foundation (WCF) 体系结构的概览.本文旨在阐释 WCF 中的主要概念以及它们如何协调工作.还有几个代码示例对这些概念进行深入阐释,但代码不是本文档的重点. 本文档下面的部分分为以下两个主要内容: WCF 基础:涵盖 WC