Chen Jian

Jester的独特之处

Jester是一款用来检查测试覆盖性的工具,它与其它类似工具的不同之处在于:其它测试工具的检测指标是每行被测代码是否被执行,而Jester则是通过一种奇怪的模式:改变一下被测代码的逻辑,执行一下测试用例,如果仍能全部通过,则表示测试有遗漏。 这种逻辑很古怪,但仔细想想就会发现它的合理之处,本文就不提了。 但是这种逻辑比起传统逻辑,即检测每行被测代码是否被执行的逻辑,到底强在哪里呢?一般来说,如果每行代码都被执行到了,那测试自然就完备了。 我被这个问题几乎搞得睡不着觉。由于智商太低,数理逻辑也不扎实,怎么想也想不出来。就当我要放弃的时候,灵感终于来了,我终于明白: 传统工具虽然可以找到未被测试的代码,但未必能找到未被测试的程序逻辑;为什么呢?因为有的逻辑是隐式的,而不是通过代码显式声明的。 举一个例子就能说明这个问题: 测试用例: List resultList = ….; testee.do(3,resultList); assertTrue(resultList.size() == 1) 被测代码: //Testee public void do(int index,Collection resultList){ if(index >= 3){ resultList.add(new Object()); } } 被测代码只有一个If/Then逻辑。如果用传统检测工具来检查,那覆盖率肯定是100%,一切都很好。 但用jester来检查,jester就会报错。因为把  if(index >= 3) 变成  if(true || (index >= 3))后,测试用例仍然可以绿色通过。 这是为什么? 因为jester期望测试用例能够考虑到 index < 3的情况。只有考虑到了index < 3的情况,在 if(index >= 3) 变成  if(true || (index >= …

Jester的独特之处 Read More »

[TDD] About Jester?

Go to http://www.ibm.com/developerworks/library/j-jester/ 一句话概括:Jester changes the source code, recompiles it, and runs the test suite to see if anything breaks 今天试玩了一下,我觉得它功能很强大很有意义,但是可用性太差了! 具体原因我以后再说!

[TDD]如何提高单元测试的质量

这里的质量,指的是功能点的覆盖性。 Kent Beck说有两种基本方法:    1.写更多的测试代码,最大可能穷尽所有的输入组合    2.或者把代码写得尽量简单,代码简单了IF/ELSE就少了,需要的测试用例也就少了。 他还推荐了一个工具用于检测测试代码的覆盖性: Jester

奇妙的Visitor模式: 从树遍历说起

   最近在项目中反复使用了Visitor模式,觉得它真的很奇妙。    很多人用Visitor模式可能都和我一样,初衷是为了遍历一棵树,但其实在“树遍历”市场上还有其它方案可以选择,这些方案可能还更简单。那为什么还要用Visitor模式?难道它的方案更优?如果更优,它的优点有更高的意义?    我的答案是: Visitor是高性能高价格的方案,而且它的优点是“Sepration of Concern”。因为这个优点,它不但可用于树遍历,还可在任何需要多态的场合,提供比“子类直接实现”更低的耦合。    1.Visitor 可用于树遍历,visitorFather(), visitorSon()什么的,这没什么可说的。    2.其实不用Visitor也可以实现树遍历,而且还更直观。让Father和Son都实现一个visitTree()方法,Father.visitTree()在visit自己之后再调用所有Son的visitTree()方法,这种方案更符合直觉,而且不需要引入新类,比Visitor模式更简单。我们不妨把这种方案称作 直觉模式。    3. 那为什么说Visitor更优?        a. 直觉模式的算法是死的,而Visitor模式的算法不是。虽然 Father.visitTree() 跟 Son.visitTree() 的实现可以不一样,但是算法是死的,只能先序遍历,并且不能跳过节点。Visitor类可以任意组合自己的visitXXX()方法和决定这些方法的调用顺序,想先序就先序,想广度优先就广度优选,想跳过节点就跳过节点。        b. 直觉模式不方便处理与各节点无关的操作,而Visitor模式可以。比如要在访问Father和访问Son之间打印N个空格,用直觉模式就不好做:这个倒底算Father的职责还是Son的职责?用Visitor模式就没有这个问题,因为Visitor本身是肮脏的,你尽可以往里面塞入各种操作。而且Visitor类还可以设定一些成员变量作为上下文,为树遍历提供必要的背景信息。        c. 最关键的一点,直觉模式只能有一种遍历操作,而Visitor模式可以有多种,并且它们可以互不干涉地同时运行。这是因为Father.visitTree()只能写一个,运行时只能执行这一个方法;而一套Visitor可以有多个Visitor子类,各个子类可以同时实例化,同时运行。        d. 把这个结论推而广之,可以发现任何多态的场合都可以用Visitor模式。要实现多态,一般是让各子类分别实现指定的抽象方法;但就像前面说的,这种方法只能写一个; 在直觉模式中,父类被多态掉了,而子类却是死的。而在Visitor模式中,由于我们可以在运行时动态选择,以致于子类也多态掉了!        e. 再深入一步,我们可以发现直觉模式只在实现某种特定契约时使用了多态,契约本身是固定的;而Visitor模式却对契约本身也进行了抽象。比如说在直觉模式中,大家可以有“买菜”这种契约,可以有“去银行”这种契约,契约的种类是具体的,虽然Father.买菜()和Son.买菜()时的还价方式不同;而在Visitor模式中,大家只有一种契约,即“做”,“做”本身是抽象的,直到我们创建“买菜Visitor”,“去银行Visitor”时,这个契约才被具体化。这就是更高层次的“Separation of Concern”,对不对?     4. 最后,说一下Visitor模式的高代价(如果你还有耐心继续看)         a.不直观,很古怪的一种思维方式。并且Visitor与Visitable要频繁互调,别人跟你的代码时会很费劲。         b.要新加一个Visitor接口和N个具体类,并且这个接口要定义对所有“被访问类”的访问方法,这很麻烦         c.虽然可以引入Context作为Visitor的成员变量,但这个Context只是全局的。如果要在访问Son时拿到Father的相关信息,用Visitor模式就远远不如直觉模式好用。我的做法是为每个visitor方法都引入一个subContext参数,把父结点的信息保存在里面,再调用子结点的visitor方法。这是一种弱类型的方案,使用时要小心

[TDD] 为什么要测一点,改一点;改一点,测一点

为什么不多改一些代码再测?这样效率不会更高吗? 因为代码写多了再测,就会遗漏一些测试点。比如说测试一个“圆”,你只能在圆孤上选择测试点;而这个圆其实是由两个半圆组成的(就像今天的日偏食),你本来还应该分别测试这两个半圆的边! 那我们的测试粒度倒底要小到什么地步?Kent Beck说,看感觉。他用一句很口语化的话来概括:"Are the teeny-tiny steps feeling restrictive? Take bigger steps; Are you feeling a little unsure? Take Smaller steps".

[TDD] Triangulation

1. This is not Triangulation public void testMultiplication(){ Assert.assertEquals(new Dollar(3).times(2),6 ); } public int times(int i) { return 6; } 2. This is Triangulation public void testMultiplication(){ Assert.assertEquals(new Dollar(3).times(2),6 ); Assert.assertEquals(new Dollar(4).times(3),12 ); } public int times(int i) { return amount * i; } 3.A Triangle? Yes //test Assert.assertEquals(new Dollar(3).times(2),6 ); //1 Assert.assertEquals(new Dollar(4).times(3),12 ); …

[TDD] Triangulation Read More »

[TDD] Overview

I’ve been reading this book of TDD, written by Kent Beck Overview   1.Goal: Clean Code that Works   2.Benefit: Manage fear during Programming   3.Three Steps:       a. Write a test case in advance of writing code. Of course it won’t work, so it’s RED       b. Try your best to make your test …

[TDD] Overview Read More »

我所能理解的SOA的好处

SOA的好处有很多种,我绝不否认。但以我的阅历,能体会的只有以下几种。     1. SOA的优点即分布式计算的优点        a. 解决信息孤岛问题,最大限度地利用现存系统        b. 业务层的复用,重用更好,冗余更少        c. 可重用性强,那么添加新功能就快        d. 冗余少,那么可维护性就好,适应需求变化的能力也就强        e. 相比于传统的分布式系统,SOA还提倡采用标准化的互操作性接口,并主张采用更大的业务组件粒度,这是它最大的创新之处。   2.从程序员的角度看, SOA导致了分而治之的开发模式,提高了软件活动的敏捷性。由于一个系统被拆散成多个相对独立的子系统,开发/测试/部署/项目管理/组织管理 的对象都变小很多,应付起来也更容易。比如说,以前开发时要打一个巨大的EAR包,部署一次要10分钟,现在拆散了,1分钟就可以部好了。

SOA的一些术语

先记下来,以后再研究   1.SLA, Sevice Level Agreement   2.Java Business Integration (JBI)   3.EIP, Enterprise Integeration Patterns