作者NDark (溺於黑暗)
看板Soft_Job
标题[闲聊] How to Write 3v1L Untestable Code 翻译
时间Wed Oct 3 22:11:07 2012
纯粹看这篇
#1FS87xEJ (Soft_Job) 认真看了一下
How to Write 3v1L Untestable Code 这份文件,感觉真是超恶搞的.
原文
http://googletesting.blogspot.tw/2008/07/
how-to-write-3v1l-untestable-code.html
http://tinyurl.com/95fhyh5
有些翻的不好就请见谅啦
How to Write 3v1L Untestable Code(如何写出邪二的不可测试程式码)
本文章列出那些会帮助你写出不可能可以测试程式码的守则,或是可以避免那些技术来测
试你的程式。
# Make Your Own Dependencies
使用自己的相关引用物件,在程式运作间实体化物件,而不是从外界传进来。当我们这样
作的时候,外界就必须被迫使用我们实体化的物件。也就是说要验证目前模组,必须先创
造那些引用物件的内容。不能建立一个假的或伪装的物件来协助我们制造例外情形。
# Heavy Duty Constructors
建构子中作大量的运作。在建构子中作越多工作,就越难把物件控制到想要测试的状态。
假如建构子可以创造出外界难以创造的状态,就更棒了。这种递移的依赖各种建构子的行
为会越来越庞大,庞大的东西就难以测试。
# Depend on Concrete Classes
直接把模组绑在使用的类别上,而不是依赖一个中继介面。(那些介面可以把使用的类别
取代为一个我们真的使用的类别或他们想要实体化却具有相同介面的类别,别给他们这样
方便的辔头来测你的程式)
# Conditional Slalom
把判断式写成滑雪比赛,每次写程式时不要忘记把if判断式与switch写的又臭又长。这样
会增加需要执行的路线,而测试必须全部涵盖它们。条件式的复杂度越高,就越难测试。
当某人建议用多型的方式取代判断式,嘲笑他们的多虑。分支要写的又深又宽广:如果没
有至少写出五层,你根本就是邀请那些测试狂人来测试你的程式码。
# Depend on Large Context Objects
依赖大型的资料物件,传递大量的资料物件(或是很难另外制造的小内容)进来。这样会
降低函式的清晰度,譬如说使用myMethod(Context ctx)就比myMethod(User user,
Label label)不清楚。为了要测试,那些资料物件必须先创造出来。
# Use Statics
使用静态,到处都布满静态。这会让测试之路颠簸不已。那些静态不能特地仿造,也不能
隔离出来。物件导向狂战士会说静态函式的变数必须只作用在那个函式里面,但怎麽可能
,我们可是专搞破坏的恶魔党。
# Use More Statics
更多的静态,静态根本是一把让测试工程师跪下的权杖。静态函式不能在子类别中覆写。
当你使用静态函式,他们就不能使用那些专门仿造的函式库来仿造
# Use Global Flags
使用全域旗标。何必要把函式的参数明确标出来,效法L. 罗恩贺伯特(山达基的创始人
),依据"意识决定了物体",在程式里面设定一些旗标,然後会作用到整个系统上(特别
有趣的是把这件事写在不同的执行绪上)。测试员会疯狂地想要搞清楚为什麽系统前一步
正确,下一步却坏掉。
# Use Singletons Everywhere
到处使用独体。可以使用独体的时候,何必要传入依赖的管理器。当模组依赖於其他管理
器时,就更难测试了。
# Be Defensive - They're out to Get Your Code!
防御性地不断使用assert来阻止那些参数传进函式与建构子。假如你让别人传进一个NULL
,那等於是放下防御罩。那些测试怪咖就是想在外面恶搞你的物件。侵略性地用铁腕避免
这些事情发生。(切记,他们想抓到你这件事绝对不是偏执的幻想)
# Use Primitives Wherever Possible
尽量使用原始资料结构,而不是使用一个整理过後的资料结构。把资料用原始资料结构传
进来,每次需要一个值的时候就自己解析。原始资料让人们难以了解,也难以存取。我们
才不用那些可能是伪装,空的,甚至是封装过的物件。
# Look for Everything You Need
尽可能取得全系统的状态,尤其是取得那些可以让你的物件看到全系统的掌控权。这会让
测试员不好过,尤其是他想要制造一个测试环境的时候。别害怕取得尽量多的物件,越多
越可以制造测试员的麻烦。假如模组叫InvoiceTaxCalculator,就把程式写成
invoiceTaxCalculator.getUser().getDbManager().getCaRateTables().getSalesTaxRate()
这样。别理那些测试维尼告诉你关於置换依赖物件或是最小依赖其他模组的故事。
# Use static initializes
使用静态的初始值。尽可能在初始化时把事情都作完。想想测试呆头只是读入你的类别就
把系统搞停会多麽沮丧。
# Couple functional code directly to the external systems it depends on
把程式码与外部依赖的系统紧密连结。假如程式使用到外部系统,如资料库,档案系统,
或是网路。确保程式尽量接触底层。这可以避免其他人以你不想要的方式使用你的程式。
(像是只执行2微秒的动作却必须花上5分钟)
# Mix Object Lifecycles
混合的物件生命周期,尽量把物件周期搞得长短不一,而且互相依赖。这种会让人搞不清
楚物件是否还存在的事特别邪恶。
# Side Effects are the Way to Go
最好是在运作时制造大量的副作用,越不清楚越好。偏门又明显不理性的副作用更好。就
像增加一层糖衣在上面一样,让物件有机会变成不合法的状态,没有初始化的成员资料。
一旦到达这种境界,别忘记让人有机会可以呼叫这制造"不合法存取记忆体"或"存取空値"
的流程。何必这麽麻烦,乾脆不要使用副作用,直接故意取误导性的函式名称来搞混那些
聪明的书呆子。
# Create Utility Classes and Functions/Methods
制造一批家族函式,例如假如要处理网址路径,我们就用字串物件(请回想尽量使用原始
资料结构一节)。创造一个用静态方法的类别如isValidUrl(String url)。别让物件导向
新警察告诉你该另外作一个URL物件。确保你的家族函式还会使用到外部模组更好。
# Create Managers and Controllers
制作一堆管理器与控制器来操纵其他物件,然後把掌控权拉拢在一起。当想要知道
SomeObjectManager在干嘛的时候,就搞不清楚其他状况了。
# Do Complicated Creation Work in Objects
在物件里面制作复杂的物件产生流程,别理那些使用工厂模式来建立物件的建议,我们比
他们优秀。因为我们的物件有各种不同功能以及数千行程式。
# Greenlight if-branches and switch statements
别怕麻烦尽量使用判断式,当物件导向牛仔想要用多型来解构物件时,阻止他们。当我们
使用判断式来写程式,只消把程式像小说一样全部读过一遍就懂了。假如使用物件导向,
简直就是变成恐怖的互动式童话书,在类别之间翻来覆去。简单点只用if就好。
# Utils, Utils, Utils!
不断写延伸类别,直到程式喷出独特的香水为止。反正这些延伸或协助的类别或函式其他
人也可以用。先提醒你,那些物件导向警察会告诉你要把功能封装在物件里面,就像责任
一样。忘记这些守则,你才是实务上真正解决问题的人,毕竟你有时间压力赶着出货。
# Use "Refactoring" whenever you need to get away with something
当想避开责难时就说自己在重构。假如我们想要作某些困难,包含新功能,又不想测试的
时候,就告诉他们你在重构,这招可以满足那些测试导向跟物件导向的呆鹅。而且每次都
成功。不要管他们说你得在重构前先有测试机制,或是没有测试不能加新功能的杂音,先
作就对了。
C++特典
# Use non-virtual methods
使用不可覆写的函式,避免让自己的函式陷入深度又恐怖的继承螺旋中,不要使用
virtual。这还可以避免测试狂战士覆写你的类别。更好的是让解构子也维持non-virtual
。当测试狂人试着作子类别时就会疯掉。
# Never use pure abstract classes
不要使用纯虚拟介面,依赖这些纯虚拟介面就会让测试疯子到处置放地雷与伪装你的程式
。
# Macros are your friends
巨集是你的好朋友,尽量使用#ifdef PROD与其他编译的定意切换来让测试员无法了解真
正重要的部分在哪里。事实上那些程式不到释出不会真正执行。
--
"May the Balance be with U"(愿平衡与你同在)
视窗介面游戏设计教学,讨论,分享。欢迎来信。
视窗程式设计(Windows CLR Form)游戏架构设计(Game Application Framework)
游戏工具设计(Game App. Tool Design )
电脑图学架构及研究(Computer Graphics)
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 1.164.86.122
※ 编辑: NDark 来自: 1.164.86.122 (10/03 22:12)
※ 编辑: NDark 来自: 1.164.86.122 (10/03 22:13)
1F:推 yauhh:好有故事性的一篇文章. 讲了非常多东西 10/03 22:30
2F:推 SansWord:可是有些事情不是应该做吗?例如be-defensive? 10/04 00:30
3F:推 cobrasgo:超恶搞的XDD 10/04 08:55
4F:推 snaketsai:#define double int //Don't ask ; it's scary 10/07 11:47