您好,欢迎来到帮我找美食网。
搜索
您的当前位置:首页正文

Clean Code 中文版

来源:帮我找美食网
整洁代码中文版(由K084 和K075翻译,不足之处,请参看原版:Clean-Code-V2.11!)

什么是整洁代码

如果代码很容易被团队的每个人读懂的话就称作整洁代码。伴随着可理解化 发展了代码的可读性与可理解性,可变性,可扩展性和可维护性。在没有积 累大量的技术债务情况下需要所有的东西来保持项目长时间的工作

特点刚性

该软件是很难改变的。一个小小的改变,会导致后续变化级联反应。

常规

按照标准公约

字段非定义状态+

编码,建筑,设计指南(检查工具)

最佳响应

高响应变化

技术债务

实际 CoC

固定性

脆弱性

由于一个单一的变化,会使得软件很多地方遭到破坏。

高您不能重复使用代码在其他项目中,因为关系到风险和高精力。

––

保持简单,愚蠢

简单的总是更好。尽可能地降低复杂性。

童子军规则

离开营地比你发现它要清洁。

粘度的设计

响应

变动成本(CoC)

抄近路和引进技术债务更能够事半功倍。

根本原因分析

总是寻找一个问题的根本原因。否则,它将让你一遍又一遍。

+ +

+–

F字段保存数据并不属于实例状态,但用于保存临时数据。使用局部变量或提 取一类抽象执行的动作。

可配置性–

防止可配置性,因为没有人能决定它应该如何。否则,这将导致过于复杂不 稳定的系统。

微层

不要在上面添加功能,但整体需要简化。

粘度环境

在一个源文件的多国语言版

C#, Java, JavaScript, XML, HTML, XAML, English, German …

最佳 CoC

构建,测试和其他任务需要很长的时间。因此,每个人都没能将这些活动正 确执行技术债务引入。.

环境

项目建设只需要一步。执行测试只需要一步源控制系统持续集成

依存性

实体逻辑相依存

+

高度增加复杂性–

退出只需然后建立一个单一的命令。

时间

低低该设计中包含的元素,目前没有用到。增加的复杂性,使代码更难理解。因 此,扩大和改变代码结果需要投入较高的精力。

运行所有的单元测试,只需要一个单一的命令

通常使用源代码控制系统

一个项目开始编写干净的代码是一个软件产品的整个生命周期中使变化成本 保持尽可能恒定的一项投资。因此,当写干净的代码(灰线)时最初的变化 成本比快速和肮脏的编程(黑线)稍高,但支付却相当快。尤其要记住的在 软件维护过程中大部分费用需要支付。随着时间的推移,如果不重构干净的 代码,不洁代码会导致技术债务增加。还有其他原因导致技术债务,如坏流 程和缺少文件,但不洁的代码是一个主要驱动因素。造成结果的是,响应变 化的能力在下降(红线)。

代码中包含大量重复的代码:精确的代码重复或设计重复(以不同的方式做 同样的事情)。重复一段代码更改更昂贵,更容易出错,因为变化在几个地 方,需要面临一个地方没有相应改变的风险。

保证完整性与持续集成

重写的安全装置

透明度

不要重写警告,错误,异常处理-他们会抓住你。.

+ + + –

++

I如果一个模块依赖于另一个,那应该是实体依赖,而不只是逻辑。不需要作 出假设。

单身/服务定位

使用依赖注入。单身隐藏的依赖关系。

基类取决于它们的派生类

基类可以与任何派生类工作。不必要的重复信息过多

减少接口耦合以致降到最低

特征排斥

代码是很难理解的。由于不理解的副作用,因此,任何变化都需要花费额外 的时间来重新设计代码,并更可能导致缺陷,。

依赖关系注入

从运行系统中解耦构建

类的方法应该是用在属于该类的类变量和函数中产生作用的,而不是作用于 其他类别的变量和函数。当一个方法使用一些其他的对象来操作该对象内的 数据的访问器和存取器时,那么它排斥其他对象类。它希望它里面的其他类 以便可以直接访问变量操纵。

– – –

在运行时完全解耦构建阶段,有助于简化运行时的行为。

人工耦合

在整洁代码中,错误不能隐藏

类的设计 单一职责原则开闭原则

当改变现有的代码时,许多软件缺陷被引入。原因是开发商不能完全掌握改 变代码时产生的影响。通过编写尽可能容易明白的代码,干净代码使引入缺 陷的风险降至最低。

一个类应该有一个,且只有一个理由去改变。

原则

松散的耦合

类,组件,模块中的至少有一个使用了其它的,则两个类,组件或模块将会 耦合。这些项目了解对方之后,会实现宽松耦合。一个组件仅能够松散地耦 合到它的环境,这样使得比强耦合的组件更为容易地改变或替换

高内聚

依赖倒置原则 接口隔离原则 类应尽量小 +

Liskov 替换原则+

必须替代其基类的派生类依赖于抽象而不是结核。使客户特定的细粒度的接口。

在不修改它的情况下,你能够有扩展一个类的行为。

内聚(Cohesion)是一个模块内部各成分之间相关联程度的度量。在类中

的一个组件、类的方法和字段应该应具有较高的内聚力。高内聚在类 和组件中能生成较为简单,易理解的代码结构和设计。。

较小的类是比较容易把握的。类应小于约100行的代码。否则,它是很难发现 类如何做它的工作,它可能不超过一个单一的作业。

+ + + + +

+

设计

较高水平的配置数据

不依赖于对方不应该被人为地加上。

隐性时态耦合

+

例如,一些方法调用的顺序是非常重要的,然后确保他们不能被称为在次序 错误

I如果你有一个如拖欠或配置恒定的值,具有已知和抽象化预计的高水平,不 要把它埋没在一个低级别的功能上。作为一个参数揭露它,从高层次的功能 上调用低级别的功能。

可传递导览

又名迪米特法则,写的关于害羞代码。 一个模块只需要知道它的直接依赖

不具随意性

+

拥有一个原因来构建你的代码,并拥有各原因来确保代码的结构是可传达。 如果结构出现任意性,别人就会有权去改变它。

命名

选择描述性/正确的名称

+

精确性

尊随公约结构

名称必须能够反映变量,字段,属性代表。名称必须是精确的。

+

在你的代码中做出决策,确保你把它用得恰当。知道你为什么用它,你将如 何处理任何例外。

选择适当的抽象级别名称 +

选择合适的名称,反映抽象化的类或方法进行工作

+

按照约定的结构来执行设计决策。命名规范要求要好,但当他们处于劣势时 会强制遵从。.

功能抽象化后命名接口 +

一个接口的名称应该来自其使用的客户端,如 istream的。

局部变化+

包装凝聚力

发布重用等效原理

重用的颗粒释放该颗粒。

一个软件系统必须保持,延长和改变很长一段时间,局部改变降低了参与成 本和风险。保持局部变化意味着有设计变化不交叉的边界。

共同封闭原则

一起改变的类被打包在一起。

容易删除+

共同重用原则

使一起用的类被打包在一起。

我们构建软件通常通过添加,延长或改变功能。然而,移除元素很重要,这 样可以保持整体设计尽可能的简单。当一个块变得太复杂,它可以移除并替 换一个或多个简单的块。

包装耦合无环依赖原则

稳定依赖原则

取决于稳定的方向

+ +

+

偏向多态性if / else或Switch/Case +

名称类别后,他们如何实现他们的接口

类的名称应该反映它是如何满足其接口(S)如MemoryStream的IStream 的命名方法。

“一个switch”:对于一个给定类型的选择有可能是不超过一个switch语句。 switch语句的使用情况,必须在系统其余部分的地方创建关于switch语句的 多态对象。.

对称/类比

命名之后他们做些什么

方法的命名应该说明做了什么,而不是它是如何做。

+

包的依赖关系图,必须没有周期。

稳定抽象原则

抽象稳定增加

+ +

+

华丰对称设计(例如 Load – Save)和遵循类比的设计(例如.NET框架中 相同的设计)

为长作用域使用长文件名

领域->参数->局部变量->循环变量->长->短

+

+

独立的多线程代码 +

不要将代码混合使用来处理多线程方面其余的代码。将他们分为不同的类别。 名称描述的效果

误置职责

一些代码放错了地方。

抽象错误级别的代码

功能处于抽象错误级别的,如一个PercentageFull物业中一个通用 的ISTACK

名称必须反映整个功能。

在可能的情况下进行标准命名

有一个标准的时候不要用你自己的语言

编码名称

没有前缀,没有类型/范围信息

+ –

+

可理解性一致性

+

在小步骤里更改系统,从一个运行状态到另一个运行状态。 I如果你想以一种特定的方式来做某些事情,那么将这些事情的处理方式一致 if(this.ShouldBeDeleted(定时器))优选于if(&& timer.HasExpired!timer.IsRecurrent)。

相同的变量名称对应相同的概念,相应的概念对应相同的命名模式 ts.

条件语句

条件式封装条件语句

+

使用解释性变量

使用区域变量来定义算法名称

封装边界的条件 +

边界的条件是很难跟踪到的,将它们放在一个地方进行处理,如下一级= 该级+1

+

++

在一个单一的工作站两个开发人员一起解决问题。一个是驱动器,另一个 是导航器。该驱动器是负责编写代码。导航器是负责按照编码准则来维持解

1) 识别功能决方案与架构,,并着眼于下一步到去哪里(例如写下一步的测试)。既挑 +积极的条件语句 在您的代码里确定现有的功能,,并根据有关它们未来的发展(变化的可能 战他们的思路以及解决问题的方式

– 积极的条件比消极的条件语句容易阅读。 性和风险)再来优先考虑他们。

从遗留代码到干净的代码。

总是有一个正在运行的系统

+

++

如何了解干净的代码 结对编程 +

无用的东西

死注释,代码

删除未使用的东西。您可以在版本控制系统中找到他们。

相对于原始数据类型选择专用值对象

使用专用的基本类型取代像字符串,整数这样的原始类型,如,用绝对路径 代替字符串。

杂乱

不是死代码但不添加任何功能

差评

不适当的信息

评论不添加任何值(冗余代码),格式不正确,不正确的语法和拼写。

注释比不同的系统信息要好:产品积压,源代码控制。仅使用代码注释的技 术说明

2) 引入边界接口可测性 –

3) 写功能验收测试 –

4) 识别组件 –

5) 重构组件之间的接口 –

重构的界限,你的系统接口,以便可以模拟环境测试的双精度(假货,嘲笑,

开发人员与并同开发人员通过所有代码变更前的提交(或推动)到版本控制

存根,模拟器)。

系统的变化。同行开发人员针对干净的代码的指引和设计对代码进行检查。

提交评论 +

+

覆盖功能验收测试,以建立一个安全网重构。

编码道场 +

+

模糊的意图

过于密集的算法会失去所用的表现形式。

明显的行为方式不能执行

违反了“最小惊奇原则”,你所期望的就是你想得到的。

––

可维护性杀手 复制

消除重复。违反了“不要重复自己”(DRY)原则。

在一个特征中,确定所使用的组件提供的功能。根据未来发展的相关性(可 能性和风险的变化)的优先次序来排列组件。

一组开发人员在编码道场走到一起,锻炼他们的技能。两个开发人员解决问 题(形比赛)的结对编程。其余的人员一起观察。 10分钟后,该组旋转建 立一个新的对。观察员可以批判当前的解决方案,但只有当所有的测试都是 绿色的。

+参考书目

隐藏的逻辑依赖

一个调用方法的正确与否取决于同一个类的其它东西,如调用删除,能删除 返回真,否则失败。

幻数/字符串

当有意义的命名不能来自本身的价值时,将幻数和字符串替换命名常量,给 他们一个有意义的名字。

重构(或引进)之间的接口组件,以便每个组件都可以在隔离的环境中测试。 干净代号:由罗伯特·马丁敏捷软件大师手册

+

6) 写组件的验收测试

覆盖功能由组件的功能与验收测试提供。

+

枚举(持续或定义行为) –7) 决定每个组件:重构,流程再造,保留

决定是否要重构,再造或保留它的每个组件。

方法

一种方法做一件事情

异常处理。

捕捉特定的异常

方法应该下降1个抽象级别 +

+

循环,异常处理,...封装在子方法

声明在同一个语句中的方法都应该写在同一个抽象层中,它应该是低于描述 功能函数的名称。 – .

他们要坚持使用的参考代码,而不是枚举。他们定义的行为使用多态,而不 是枚举

8a)

+

捕获异常要尽可能具体。捕获的异常,可以以一种有意义的方式反应。

内重新设计类组件和重构一步步骤(见重构的格局)。添加单元测试的每一 个新设计的一类

重构组件

+

++

8b)

你可以以有意义的方式反应捕捉的地方 +

使用ATDD和TDD(见清洁ATDD/ TDD小抄)的重新实现组件

重新设计组件

方法与参数太多

参数较少最好。功能可能被外包给含有字段信息的专用的类中

捕获异常时,你可以以一种有意义的方式反应。否则,让别人调用堆栈中的 反应它。

8c)

使用异常,而不是返回代码或空 +

OUT/ REF参数的方法 –

在特殊情况下,抛出一个异常时,你的方法不能完成其工作。不接受或返回 null。不要返回错误代码。

如果你预计未来只有少数的变化到一个组件,并且该组件在过去很少有缺陷 ,可以考虑保留它

保留组件

+

防止使用。返回复杂对象所持有的所有值,再分成几种方法。如果你的方法 必须改变事物的状态时,它被称为改变对象的状态。

故障快速切换

+

重构模式

调解分歧——统一类似的代码

更改的代码逐级两条,直到它们是相同的。 隔离变更

首先,隔离的代码从剩余部分进行重构。然后重构。最后,撤消隔离。

选择器/标志参数

异常应尽早抛出后检测一个特例。看着异常的堆栈跟踪,这有助于查明确切 位置的问题

全局整数符(布尔标志)分割成几个独立的方法,可以从客户端调用无标志 为控制流使用异常

的方法。 – 控制流使用异常:有坏的表现,难理解,导致较难处理的真实异常。

不适当静态

静态方法应该是一个实例方法 –

误吞的异常

源代码结构垂直分离

异常可以被吞噬,只有在特殊情况下完全解决后离开catch块。否则,系统留 在不一致的状态e.

– –

+

++

迁移数据

移动从一个表示到另一个暂时性重复数据结构。

Legend:

临时并行实现 +

+

“重构”通过引入临时并行的算法实现。后一个调用者切换等。当不再需要 时,删除旧的解决方案。 .

变量和方法应接被用来定义在他们关系密切的地方。局部变量应该声明略高 于他们的第一次使用,并有一个小的垂直范围。

非军事区的组件 +

嵌套

+

嵌套代码应比非嵌套的代码更具体,或能够处理可能性较小的情况。

介绍了内部组件边界和一切不必要的内部边界外推到组件接口和内部边界之 间的非军事区。重构组件接口与内部边界相匹配并消除非军事区。

DO DON’T

+–

命名空间功能的代码结构 +

保持所有属于相同的特性。不要使用命名空间通信层。一个特性可能会使用核心功能,如记录。

Urs Enzler June2013 V2.1

自动检测的种类

ATDD – 验收测试驱动开发

先指定一个特征测试,然后实现.

DDT –缺陷驱动测试

TDD – 测试驱动开发

红 – 绿 –代码重构. 写一点代码,测试一点.

编写一个重生产缺陷的单元测试 – 修改代码 – 测试成功 –缺陷永久修复.

+ +

++

伪造 (存根, 伪装, 侦查, 模拟 …)环境隔离

伪装框架

使用伪装模仿被测试对象的所有依赖.

在不同测试场景中用来显示不同行为的伪装使用动态伪装框架 (少量行为重复使用).

手工编写伪装

POUTing –普通旧单元测试

也被称为后测试.编写单元测试来检查已存在的代码. 你不可能想测试驱动的 一切.使用 POUT 来增加健全.

用于TDDing测试后添加额外的测试(比如:边界条件).

可测试性的设计构造器 – 简单的

混合存根和期望公告

极端伪装用法

+

++

不属于主机测试工具的测试

可以检测与测试工具中其他测试完全不同的测试对象的测试 .

红色栏模式单步测试

+

过时的测试

使用手工编写伪装当他们被用于多个测试时,同时他们只有几个行为变化 在这些场景中(行为重用).

一个测试检查该系统不再要求的内容. 甚至可能妨碍清理的生产代码, 因为它仍引用.

选择一个你最有信心的测试,你可以最大限度地提高学习效果 (如:对设计的影响).

部分测试

隐藏测试功能

测试功能隐藏在设置方法,基类或辅助功能类.只通过检查测试方法测试 应该清楚别的有没有初始化或断言的地方

编写一个测试,它不完全检查被所有要求的行为, 只是让你更进一步接近, 然后用下面的扩展测试.

+

扩展测试

为更好匹配现实世界场景,扩展现有的测试.

确保你遵循AAA (arrange, act, assert)语法当使用模拟时.

在同一代码块中,不要混合设置存根(可以是对象运行)具有这样的期望 (测试对象应该在的).

臃肿的设置

+

对象必须可以容易塑造.否则, 不能实现容易、快速的测试

构造器 –生命周期

+

+

测试伪装取代测验对象

被测试对象调用的依赖和参数的结构使测试很难读懂.提取到帮助方法可以

重复使用.

另一个测试

如果想到新的测试,然后写进人物列表,不会失去当前测试聚焦.

+

++

不清楚的错误原因条件测试的逻辑

Tests测试不检测测对象 但通过伪装返回值. 通常取决于极端伪装用法 的量.

拆分测试或使用断言消息.

通过依赖关系和配置/参数传入构造器,具有等同或长于被创造对象的生命 周期.为其他值使用方法和属性.

如果你的测试需要许多模拟或模拟设置, 然后考虑将测试对象分成几个类, 或在你的测试对象和他的以来对象之间提供一个附加的抽象

测试不应该有任何条件测试逻辑,因为其很难阅读.

代码编写时的测试逻辑不稳定测试

测试依赖于代码编写时的特殊逻辑.

系统边界的抽象层

在系统边界(数据库, 文件系统, 网络服务, COM接口 ...) 中使用抽象层, 通过允许模拟来简化单元测试.

单元测试原则快速

有时通过, 有时不通过并依赖于环境.

结构

安排 – 执行 – 断言测试程序集 (.Net)

为了经常执行单元测试不得不快速. 快速意味着远小于秒这级别.

通常通过AAA来对测试结构化. 切勿混淆这三个模块.

测试命名空间

为每个产生的程序创造测试组件,并且以产生的程序名+ “.Test”为每个

产生的程序命名.

具有相关联测试对象的测试放在同一个命名空间.

+

+

独立的

+

TDD 原则

一个测试检查一个特征

– – –

–+

学习测试

编写针对外部元件的测试确保它们达到符合预期.

绿色栏模式

假设 (直到成功)

返回一个获得一一个测试运行的常数. 然后重构.

三角化 – 驱动抽象化

+

++

编写一个至少有两组简单数据的测试. 抽象的执行它们.

显著性性执

如果实现是显而易见的,那么只是落实一下,看看如果测试运行. 如果没有,那么退后一步,只是试运行和重构.

清除错误发生的地方. 测试集之间独立(随机顺序).

+

一个测试检查被测物体的一个特点.这意味着,它测试此功能中包括所 有的东西,但不多.这可能包括多个呼叫被测物体. 通过这种方式,测试作为被测物体的用法示例和文档.

一对多 – 驱动收集操作+

+

可重复性

单元测试方法显示全部真相

只对基础构造设置/清除 测试方法命名 单方案中的每个测试 资源文件 命名

命名被测系统测试变量

一个测试检测一个方案.

单元测试方法显示测试所需的所有部分. 不要使用设置方法或基类来执行 测试对象或者依赖对象的操作.

只对单元测试需要的基础构造进行设置/清除.不要在进行其他任何的测试 时使用它.

名字反应什么被测试, 例如:FeatureWhenScenarioThenBehaviour.

+

++

不假设初始状态, 没有什么留下, 没有外在服务的依赖对象,可能导致不 可获取(数据库, 文件系统 …).

+

微小步伐

首先,实施单个元素的操作,然后,逐步加到多个元素.

自我校正及时性

不需手动测试解释或干预. 不论红栏还是绿栏测试!

测试被及时写出 (TDD, DDT, POUTing)

+

+

做微小步骤操作.只有一点点测试代码之前编写所需的生产代码. 然后重复.只添加一个断言每一步.

保持测试简单

验收测试驱动开发

使用验收测试驱动你的TDD测试用户功能测试 自动的 ATDD

+

+

用验收测试检查所需功能,并指导你的TDD测试.

每当一个测试变得复杂,检查是否可以被测物体分割成几类 (单一职责原则)

如果没有状态校正则使用行为校正.

偏向状态校正而不是行为校正 测试领域专业语言

测试和资源一致: FooTest.cs, FooTest.resx

对拥有正在测试的系统的变量使用相同的名字 (例如:testee or sut).

清楚识别被测系统,反重构的强健性.

结果值的命名

测试需要极端测试 +

+ 太大的测试 / 多个方案的断言

+

内部检查

+

+

单元测试缺陷

测试并不检测所有

通过测试第一眼看上去有效但没有测试测试对象.

一个测试需要数十行代码来设置环境. 这些噪声使我们很难发现什么 被测试.

一个有效的测试太大了. 原因是这个测试检测不止一个功能或者测试 对象不止一个 (违反单一职责原则).

––

使用 DSLs 简化阅读测试: 辅助方法, 类.

+

+–

+

验收测试是一个从顶到底的完整用户功能的测试并提供商业价值.

使用自动化的验收测试驱动开发,回归测试和可执行的规范.

TDD 过程缺陷

使用代码覆盖率作为目标

+

一个测试直接访问测试对象内部(私有/受保护成员) (反射). 只是代码重构杀手.

测试只在开发人员的机器上运行

对拥有测试方法结果的变量通常使用同样的名字(例如: result).

一个测试依赖于测试环境的改变和其他地方的错误 . 尽快使用连续不断的 集成环境来获取他们.

超过必要的测试+

匿名变量

一个测试检测比他目标更多. 测试出错当检测不必要的东西发生改变. 尤其是 无需假设, 检查. 如果很容易, 那测试就更容易.包含伪装或有序检测项在无序集合中.

通常,对拥有被测方法无兴趣参数的变量使用相同的名字 (例如: anonymousText).

不相关的信息

不要假设理解算法

只是理解能工作不够, 确保理解为什么能工作.

边界的错误行为

经常测试边界. 不要对行为假设.

+

测试包含不相关理解的信息

重复测试

测试使用文本填满控制台 –可能曾使用国手动检测.

– 测试编写要在代码产生之前

– 重构时间不足

– 跳过容易测试的部分

跳过很难测试部分 –

围绕方法组织测试, 而不是行为 –

最后没有绿色栏~10 分钟

使用较小的步骤获得快速和频繁的反馈.重构是一种对未来的投资. 可读性,可变性和可扩展性都会回报回来.

使它更简单, 不然 bugs会隐藏在那并影响可维护性.

组建验收测试+

使用代码覆盖率查找缺失测试,但不把它当做驱动工具.否则,结果可能是 测试的代码覆盖率,但不是确定性.

为单个组件或子系统编写验收测试,因此这些部分可以去自由组合而 部丢失覆盖率的.

仿真系统边界+

只有测试失败, 新的代码才需要. 另外, 如果测试结果令人惊讶但不是失败, 要确保测试正确.

––

仿真系统边界,如用户界面,数据库,文件系统和外部服务,加快验收测试 并能检查异常情况 (例如,一个完整硬盘). 使用系统测试检查边界.

验收测试狂潮

不要编写处理每一种可能性的验收测试. 只为几个这是场景编写验收测试. 特殊的和理论性事例可以用更容易的单元测试覆盖.

––

吞吐异常测试–

测试捕获异常并且通过测试.

这些测试很脆弱且是重构杀手. 测试完全迷你使用这样的事例,它反应现实 世界里特征如何运行.不要孤立的测试setters和getters, 测试使用它们场景.

持续整合预提交检查

在提交到代码资源库之前,运行覆盖当前运行在代码上的所有单元和 可接受测试.

+

ATDD, TDD周期

为用户填写验收准则

这个团队都为用户填写验收准则.

定义示例

整个团队定义用于显示代码项目验收标准的示例.

编写验收测试框架

在验收测试框架中把示例映射到映射到一个空的规范 / 测试

后提交检查

+

对每一个向在持续集成上的版本控制系统提交的测试运行所有的单元 和可接受测试.

面向团队的沟通失败的整合

当一个阶段的持续整合服务失败, 通知整个团队尽快解决阻塞情况.

+ 构建分段

+

把完整的持续整合工作流分成几个阶段以缩短反馈时间.

自动构建和安装测试系统

+

在测试系统上测试软件尽可能自动生成和安装程序 (用手工测试, 用实际硬件测试 ).

持续调度+

每次提交或手动请求,将系统安装到测试环境.部署到生产环境也是自动的.

测试金字塔

DDTA约束测试 = 非功能需求测试.

参考文献

Test Driven Development: By Example by Kent Beck

ATDD by Example: A Practical Guide to Acceptance Test-DrivenDevelopment by Markus Gärtner

The Art of Unit testing by Roy Osherove

xUnit Test Patterns: Refactoring Test Code by Gerard Meszaros

Legend:

DODON’T

+–

(Gherkin, MSpec 类 和它的声明 …)

需要构建知识来执行验收测试.

有足够的知识来执行验收测试.

探索设计

初步设计

实现一个尖峰来收集足够的知识,因此你可以一个

粗略设计你如何实现新功能,尤其是验收测试的接 可能的解决方案.

(如何访问和验证功能).

重构

重构现有代码为简化新功能. 运行所有测试保持代码可以工作.

成功,但未全部执行完

编写验收测试

成功且所有示例检测完

将准备、执行、断言部分添加到验收测试框架(Given,When, Then or Establish, Because, It …).运行接收测试

失败

明晰错误原因

错误的测试应该说明出错的地方,因此你不需要调试代码.

没有类的设计理念

有类的设计理念

成功,

整洁代码, 尖峰解决方案

初始化或更新类的设计

TO DO 实施一个尖峰使验收测试运行,因此得到一个 设计你想要实现新的功能.

任务表为空

初始设计.

任务清单

运行每个类

•添加缺失测试当想到的时候

当写的时候删除测试我们把任务清单写入相同的文件,

如‘单元测试名’+// ‘TODO’:

编写测试

增加一个小的测试或者对现有的测试做小范围改动抽样测试:

1)证明代码是一个硬编码的假设. (< 10 minutes).

2) 证明某些错误. 3) 证明某些缺失.

TDD

成功,

运行测试

整洁代码,

TO DO 任务表

不为空

明晰错误原因

失败

失败

错误的测试应该说明出错的地方,因此你不需要

成功

运行所有测试

调试代码.

编写代码

编写尽可能少得代码使测试通过

成功,代码没清理

清理代码

应用整洁代码准则

. 重新设计所需的类. (< 10 minutes).

Urs Enzler June 2013 V2.1

因篇幅问题不能全部显示,请点此查看更多更全内容

Top