虚拟座谈会:代码测试比率、测试驱动开发及行为驱动开发-2

上一篇 / 下一篇  2012-09-27 16:45:27 / 个人分类:杂谈

(Djoa$YV0  问题:一直以来,TDD被公认为是一种(代码)设计准则、测试准则或沟通工具。然而,在TDD方法中,作为这些准则和工具的目标会如何影响设计?在测试方面,TDD现在与未来的价值又是怎样的?51Testing软件测试网[4V@D |y9]FP

9^AD`0U"h1rxSs0  JB:我认为这很大程度上取决于方法的实践 者。当我实践TDD的时候,发现最有价值的部分是测试规范这块,这可能是因为我期望在这个方面有所提高。而只有当我的错误数大幅度地减少时,我才注意到 TDD是如何帮助和指导自己改进设计。在你实践TDD的时候,所有这些都指向对测试的当前价值的个人感受:你可能期望从其他测试中获益。

'I5x9FR K!p051Testing软件测试网\;W4t~G2kP.d

  我觉得测试的当前价值远比未来价值要高得多。虽然从未这样试过,但我曾经打算在几个月后把测试都扔掉,仅当我需要改进某些东西的时候才去重写测试。51Testing软件测试网/ZzL[ t*R

51Testing软件测试网C+?,bo;sgRd

  我从未在不是我编写的测试上获益,我也不认为这会对我所工作的项目有什么样的帮助,或是对TDD实践者的基本规范有什么样的贡献。对此我有所顾虑,就好象合同工走进要装修的房间,然后对之前的装修出言不逊。

Q8D eyj0hav |051Testing软件测试网_([T,gtU

  我曾经宣称, TDD风格的测试会起到变更探测器的作用(引用Cem Kaner的术语),用来减少代码变更的代价。我也听到过有人像我这么宣称。尽管没有仔细地度量过,但的确见识过TDD所带来的益处。我甚至听说有人宣 称,这些测试可以为从未了解系统和API的人,讲述清楚其中的内容。对我而言,这些益处仍旧是理想化和理论上的。51Testing软件测试网0Ee&g3?As SsJ`

B*`w/A&~j0  Dan:TDD是一种设计规范,每样东西都有 两面性。在 “测试驱动”这个词组中,“测试”这个词很不幸。 你所写的用来描述行为的实例并不是测试,你所写的代码也只是简单的实例。这些实例只有当与类似持续集成等实践联系在一起时,才成为一套的回归测试。但这些 无法代替测试的需求,特别是代替类似Brian Marick和James Marcus Bach所倡导的有技巧的、直接的探索性测试。TDD测试的另一个特性就是它的决定性。在回归测试中,这是一个优势,但在发现阴暗角落方面(译注:指不易 发现或重现的Bug/Defect)做得却不怎样。随机化的测试技巧能够帮复杂的系统找出许多细微之处,然后你就可以利用TDD逐个解决。Haskell 和Scala的QuickCheck工具就是个很好的例子。

1i6tnD;k?-WN:c0

0p?IlU e0  关于沟通,这是TDD的主要目的之一。特别是在你需要向其他程序员讲述你的代码意向的时候。在文章《Introducing BDD》中,我描述了有含义的命名方式对测试起到了多么大的帮助。否则,你就无法得知你的测试用例失败时所揭示的真相。你必须能够像读故事一样地去理解 TDD测试用例,而出色的测试命名则决定了功能文档的易用程度。51Testing软件测试网jK]!j'lt7TRg!A

51Testing软件测试网U*F` U Z#P7~

  Gojko:我认为答案总是位于这些因素的平衡点上。为了将TDD作为一种规范,我们必须找到一种方法来完成所有事情。好的单元测试,能够指引设计。但也必须能够帮助我们缓解关键技术难题带来的风险,并且告诉人们设计的代码应该怎样表现。

#|M h];OhBmRz G0

E7Q`'Hd;|.Cw0  Ron:TDD会用到测试,但不仅仅是测试而 已。它是我们开发系统的方式,是所有测试和程序的骨架。TDD以及其他相关实践让我们逐步地、一个特征接一个特征地开发系统。从始至终,它保证了代码的活 性,以及可塑性。这让我们更清楚地了解我们究竟完成了什么,也让产品负责人或管理者清楚下一步要做什么,不论是通过揭露代码满是缺陷,或者设计是错误的, 或者我们不能太快地改进。这也极大地减少了在项目最后阶段才了解到坏消息的可能性。

R(R|.B%e0

~*q[5LS/\4A`.BC(H0  我不认为这些目标是“独立的”。好的软件开发,需要整合很多想法,也需要我们平衡很多目标。我们并不想放弃这些,相反,我们希望能够找到一种方法服务于所有的目标。而这一切,让开发产品变得更快捷。51Testing软件测试网3`;K9}9l"`:j#X,`2p

51Testing软件测试网W,M]7zd/]2o@7g6k

  Steve:当发觉沟通决定着其他方面的结果 时,我必须强调所有级别测试中的沟通因素。例如:如果我致力于把一个测试用例写得可读性很高,这真的也能帮我发现对象引用的不恰当。 我见过很多团队陷入过维护性很差的测试用例的泥塘,而从拖累了整个进程。特别是在新的理解或概念出现的时候,你必须像对待生产代码一样(甚至超过)谨慎地 对待测试代码。51Testing软件测试网4hp S)U.r ]Y8`#@~

51Testing软件测试网u TE$?6T

  问题:关于单元测试、集成测试以及验收测试比率的自动化以及相应的维护成本,有哪些准则可以告诉大家?51Testing软件测试网*Z9\oKi*w4}+{

T;F(njI6aK7?0  JB:在团队实践TDD一到两年的时候,我不 停地接到团队的消息,向我倾诉测试成本与收益的不平衡。每次这种情况发生,往往是因为团队尝试用较大的测试集(集成测试,系统测试以及端到端测试)去检验 较小的事情(独立对象的具体行为)。这往往会导致更大的测试套件,更频繁地运行测试套件(一个失败意味着23个测试失败),也会降低程序员维护测试用例的 信心和兴趣。这样的测试,反而会给项目带来负面影响。51Testing软件测试网Bk#Mq)f ee"P&d.@

51Testing软件测试网u3]n s-Nq

  在这种情况下,我建议为微行为编写微测试,然后合并微测试。契约式测试是通过连接相邻层(adjoining layer)的接口,来检查这个层,不会再深入。这就意味着从集成测试及系统测试转移到检查我所指的“基本对错”上——例如:在无限的时间与空间的条件 下,这个对象是否能得到正确的计算结果?我所说的“集成测试是骗局”就是这个意思。51Testing软件测试网V[/Ym+n0dU

51Testing软件测试网xf9u*u({

  尽管对于不同的项目,不同的团队,要具体事件具体分析,但我还是强烈地建议程序员们从集成测试和系统测试转向微测试。

'x:JP2G'^-rs!io$a051Testing软件测试网4f1UAAo5{ N

  Dan:我不认为对于比率的建议会行之有效, 对我而言,这甚至会有风险。如果某个错误出现的可能性较高,或某个错误的影响较大,我会花更多的时间去解决。举例说明,我曾希望以测试驱动的方式编写转换 数据的代码,因为我知道把转换数据搞糟是多么容易,而发现错误又是多么的困难。类似地,如果我在为系统的外围交互模块写代码,我会非常非常小心需要传送和 接受的数据。一旦发现Bug,我就会编写一段测试用例来隔开这个Bug,并且用测试驱动的方式去修复它。其他时候,我会用REPL(一种命令行接口的语 言)来实践,并找出Bug。

*h*E5LB bO.q&p051Testing软件测试网 e^5P Z#nza

  Gojko:我想这个问题过于宽泛,没有一个具体的项目,我没法给你答案。

~!K8^{U Q n^[L0

)p G iVS v0  Ron:比起“把这些事情做起来”,我并没有 更好的答案。运用TDD及相关的实践方法进行编码,花费的成本会更少,结果也会更好。有些人或团队认为,如果他们运用TDD,搭上的时间会更多,这也是解 释得通。也许会存在一些真实的开发情况,但我并没有找到。通常来说,这些人比较简单,也并不喜欢TDD。这样做的后果是,他们认为自己会很快速,但得到的 只是不停增长的缺陷数。这些缺陷必须消除,却使设计变成恶梦,反过来又增加了缺陷,使缺陷不易被发现和修复,从而拖慢整个进程,让进程变得异常困难,造成 恶性循环。往往在项目最后的几周,他们最后只能收到坏消息。51Testing软件测试网$K4fXXq,}#E ^'O

51Testing软件测试网'?C,x:o*F*D,c*rV

  这就是“死亡行军”(译注:越做错越多,越无法收拾)。当然,有些人或产品也能侥幸“活”下来。但遗憾的是,花如此大的时间和精力“活”下来, 会让团队以为,所有项目都必须这样完成。(译注:感触颇深,同时有过3个项目,我带2个,另一个PM带一个,我的项目成员几乎不用在UAT前加班,氛围也 非常好;另个项目天天加班,士气低落,民不聊生)。这才是大错特错!在有更好、更简单的选择的时候,他们几乎将自己逼进绝路。51Testing软件测试网MSV:cp8t

].S BS}9oL0  Steve:我没法给出答案,除非你已经为相同的团队搭建了可辨识的系统。敏捷方法的基本要领就是对应已发生的情况。同样重要的一点是这些比例会随着项目进程而改变。

v(M9Md+Ih$Zhx051Testing软件测试网$d5I,m A/[ vn |

  问题:除了至关重要的系统,现在似乎比较统一的说法是100%的测试覆盖不能作为一个目标,也是不实际的。你是否认为代码/测试比率能提升测试的注意力和效率吗?

$t(e8uhdp9J051Testing软件测试网:H.QHrv3c

  JB:正相反,如果组织重点关注在这些目标, 那么就无形中创造出灾难的、会受到炮轰的“成熟模式”。你懂的:级别1表示“我们写测试”;级别2表示“我们为所有新代码写测试”;级别3表示“我们对系 统做50%的覆盖”;我假设级别5表示“我测试故我在”。我认为这是没有意义的事情,我可以做这些,但结果还是交付了垃圾的产品。我觉得这是对我所教和我 所崇尚的实践的一种嘲讽。51Testing软件测试网US'q:I@9Ts:p7R l

]'nWd4@c Yj!SV0  当我有我自己的“网络瞬间(Network moment)”时,我开始关心起这些事情了——你知道的,“我像个疯子,我再不会接受这些!”我尝试让人们学会有自己的“网络瞬间”,然后给他们建议如何去解决问题。我相信比起目标式的测试覆盖率,这更有效。51Testing软件测试网8fwZ!|X k

-q2F'e+Gcp&K0  Dan:我认为教条式的代码测试比率恰巧有着 相反的作用。这意味着所有的代码都是同等重要,具有相同的风险,这样的想法是错误的。相反,我提倡对不同的代码,采用不同关注程度及审查力度的测试。任何 企图达到代码统一的测试覆盖率的机会成本都是疯狂的,特别在用户接口测试方面。把时间和精力放到改进需要重点关注的代码的质量上,会更加行之有效,立竿见 影。

jlfYVP051Testing软件测试网4N-Cb m6fr8J'JN[!v?

  Gojko:只关注代码覆盖率很可笑。关注在 10%的风险最高的代码比关注99%可忽略风险的代码,收益要多得多。我认为风险覆盖比起测试覆盖要重要得多。我偏好使用属性构架能力矩阵 (Attribute Component Capability Matrix),然后决定什么需要覆盖及怎样去覆盖。(详见James Whittaker的《How Google Tests Software》一书——译注:好书一本!)51Testing软件测试网| I)H_9wy6\}

51Testing软件测试网:W"Z5["]3S

  Ron:测试覆盖率永远都不该成为我们的目标。如果我们的测试很棒,那么我们势必能找到缺陷,这是显而易见的。那缺陷还会在哪里呢?在我们没有测的地方。因此覆盖率并不需要做得美好,只要“够用”就足够好了。我们需要做两件事情:51Testing软件测试网d2s{3q,F

K#gs5p&]3F!Is0  首先,我们需要不停地提升我们的测试技巧,那样我们测不到的地方就会越来越少。如果我们仅仅做TDD的教条是没有意义的——“为得到失败而写测试(译注:为了找到错误而拼命地写更多的测试)”。我们会自然而然地得到完整的代码覆盖,以及很好的路径覆盖。51Testing软件测试网$r1z$U8}+S?

3s$[N['y'_2l0  第二,我强烈建议团队分析测试覆盖和这类信息,这样才能更好地决定什么需要改进。人无完人,但我们必须警觉,如果发现了缺陷,那么我们就需要回顾所发生的情况,补充漏掉的测试用例,保证将来不再发生。

nE;@$J!c:o.x7\0

Mh`0u%r(BR0  Steve:我还是认为,在数据和划分不清楚之前,这是评价会有失精准。代码覆盖率有用,但作为外部的、过分强调的目标,也会影响团队应有的关注程度。51Testing软件测试网}v?y,p:AGF6hm

51Testing软件测试网$O c6{xlj

  问题:TDD、BDD、验收测试驱动开发(ATDD),测试优先等等这些,对不同的人都意味着不同的东西,也容易让人搞浑。我们是否需要一种通用的语言,用以描述我们的软件开发方法并培养一种可达成共识的内容驱动的好实践呢?

DC"V3M%[051Testing软件测试网dfk[Cc

  JB:不,我不这样认为。我想对每个实践,我 们都有足够多的术语来描述。我发现,当我停止担心如何去定义它们、去分享我是如何理解、并鼓励人们分享他们的理解的时候,反而会有意想不到的收获。我还记 得,我最有影响力的一次关于TDD和BDD的定义、意义和目的的讨论,发生在临晨4点半的一家旅馆的房间里。那次讨论,我言辞激励地与人争论Dan North和Chris Matts。如果我们只是推动大家在社区网站上发布某些定义集,而抵制形式上更生动的、有点疯狂的、激烈的辩论,这将是非常遗憾的事情。51Testing软件测试网gS#u+m3On+Y`{ho

51Testing软件测试网}7Ogv2y{&q

  Dan:这只是我们对这块领域发展的理解的一 个征兆。我起初建议把BDD用作辅助传授TDD的目的。我喜欢Gojko Adzic的名言“将规格说明书实例化”,只因它很清晰,没有歧义。很长一段时间中,我在“测试”、“实例”和“规格说明书”这些专用词汇中挣扎,我无法 做出我的选择。有个短语“通用语言”本身就是有误导。“通用”指的是在边界之内的世界。换句话说,我们依据内容对同样的事物做出不同的描述。某人的测试是 另一个实例,也是另一个规格说明书。这关乎你是否能将你的意图很好地传达到你的内容中。

q(dFv w8A+~'? L y0

*r7q yn1_|?0  Gojko:我尝试用实例来定义规格说明书, 将其变得更清晰、有内容边界并把范围缩小,就是为了避免TDD、BDD、ATDD或其他概念的混乱。我认为这个命名对实践的探索很有意义;对我们从业务角 度确定要开发的系统并运用实例和搭建在线文档作为支持,也很有意义。某些建议和实践对此是有用的,有别于当我们用技术测试来驱动设计时所用的那些实践与建 议,他们有自身的价值。51Testing软件测试网1M)v5hQ|;Y9m \N

P[2qU8J0  我不喜欢ATDD或验收TDD这个命名,因为这给人们一种错误的印象,让大家觉得是因为关注在错误的事情上所以才造成失败。我希望人们不要这样思考,但不幸的是近期出版的书籍已经使用了这个名称。

;YGs i7F @051Testing软件测试网+g.a"`n |I1Qz G

  我理解的BDD是,包括了很多不仅仅是规格的实例,并以单元测试驱动技术设计。例如,我考虑特征注入(Feature Injection)、拉动需求、外围设计、定义商业价值的模式以及诸如此类的BDD事件。这些才是Liz Keogh所做的激动人心的事情。当然,除了这些实例化的规格说明书或单元测试,还是有很多其他事情可以做。例如,效果映射(Effect Mapping)是又一项令人激动的、全新的计划与路演的技术。这与整个BDD的系统价值完美地符合,将测试驱动拔高到业务对象的层面,并对任何形式的自 动化都没有关联,也无需去做。

u }&_6z%m9da`-X C3]0]051Testing软件测试网0I%hi#G R

  Ron:好吧,我认为这是人类沟通的方式。这 个世界上并不存在一种每个人听到都能理解的、清晰的语言。在我们边学边成长的商业世界,差异是不可避免的。在我眼中,最重要的差异是人们花很少或不花力气 去理解这是些什么东西。相反,他们要么没有理解就开始诋毁这些建议;要么就是没有真正地去运用这些建议或没有理解地去运用这些建议,只是宣称他们在做这 些。51Testing软件测试网k2L1?/COx

SQ*{ vN0  这样做有两个严重的后果:第一,许多项目和个人不去做他们可以做的。这将导致人员对工作的不满、失败的项目以及糟糕的结果。第二,误解通常会减缓大家对这些好建议的运用。51Testing软件测试网1] g6o BU7xnI4E6~0Sr

51Testing软件测试网 p7tH)dk2aA.^/I0i

  Steve:当我们拥有完美的准则时,就能把它归纳成术语 我认为现在讨论什么技术该运用在什么地方还为时过早。我还认为不同的“领域“该有更宽泛的范围,用来获知他们的不同,但不至于弄个底朝天。

E@.VO/c6Q0

?7tq%p'H*~&V0  问题:关于这些主题有什么最后寄语?51Testing软件测试网{1A$ppr

l-u"m7xQ1j;SGTV0  JB:没什么特别的。多多地实践那些技术吧,因为你希望它们能指导你改进工作。去做吧,因为这能给你“个人成功”。去做吧,只因它能帮助你更好地享受你的工作。总之,无论什么原因,去做吧!51Testing软件测试网R8yf{E ` OE

51Testing软件测试网4LV0c_fD

  Dan:我在这里讲的每个主题,今后我将分享更多我的感受。51Testing软件测试网:@[z^e:nG

51Testing软件测试网;k8y |1wZ e5Z6I

  Ron:尽管我会在项目中运用其他方法,但在半个世纪里,我所用的所有方法中,这些是我见过最好的方法,虽然我不会强迫每个人都去使用。51Testing软件测试网0L^6mtkSR C j+e

51Testing软件测试网,G X6T-C/M0Z

  然而,我将做的是,我会建议关心这方面专业的每个人都能学习如何去运用这些技术……到一个“很好的程度”,然后拥有能够决定何时、何处使用它们的能力。在能够对某种技术进行客观的评测前,你不该去回避这种技术。

wR6kC+M@g$U0

Aj3^1_O JX0e-D0  因此我将要做的是,展示给大家我所要做的软件开发,让大家放心、大胆地去尝试这些技术。并且能够让人们对此类技术有较好的口碑,愿意花足够长的时间去做出一个好的决定。51Testing软件测试网j:FwwG

l!DFY-rl0  对我而言,好的决定是指能够在正确的时间正确地使用这些实践。我希望大家能发现这些技术的价值,并从中获益。

sG.S TR c051Testing软件测试网H&A(jJ:[`

  Steve:较常见的是,我所看到的关于TDD的主要问题,都不是测试难题,而是基本设计技巧的缺憾;人们之所以对测试比较纠结,是因为代码有着错误的结构。类似地,我看到过代码不能表现清楚。我越来越觉得,程序员的面试应该包括一个测试预选者编写一段可读性强的段落的测验。51Testing软件测试网$HAvGO8F.^s


TAG:

 

评分:0

我来说两句

Open Toolbar