#
摘要: 对于mock对象上的mock方法的调用,easymock支持指定次数,默认为1.同时easymock提供了其他的方法,用于指定具体调用次数或者放宽调用次数检验。
阅读全文
摘要: easymock并不是万能的,在使用easymock时有一些限制需要注意。
阅读全文
摘要:
前面教程中有个章节讨论到mock和stub的概念差别,一般来说easymock如其名所示,主要是用来做mock用的,但是easymock中也提供有对stub的支持, 主要体现在andStubAnswer(),andStubDelegateTo(),andStubReturn(),andStubThrow()和asStub()等方法的使用上。
阅读全文
大家都知道sonar是个好东东,在有CI支持的情况下,使用好了可以非常好的控制代码的质量,诸如代码覆盖率,代码规则检查等。
而解决violation的办法,除了正统的修改代码来满足规则外,还有一个变通的方法, NOSONAR。这个标记本意是在一些特殊情况,有不得已的理由不得不违反规则,为了避免sonar继续报错而不得已做了一个"变通"。
NOSONAR本意虽好,但要是有人滥用,变通就会变成取巧,因为解决sonar violation的最简单的方法,就是直接NOSONAR!
当问题很简单时,一般人都会选择正常的方式修改代码,如果只是举手之劳基本上还是能遵守规则的。但是当问题复杂时,或者说当解决问题不再是举手之劳时,每个人都要受到NOSONAR的诱惑。而NOSONAR的底线在哪里?没有人定义,没有人检测,自然不会每个人都坚守,NOSONAR的底线随着一个一个的NOSONAR慢慢的在降低。退五十步的人,是没有资格笑百步的。
返回到现实代码中,不知道是大家都没有顶住诱惑,还是说我们开启的规则不大合理,总之越来越频繁的在代码中看到NOSONAR了,虽然还没有到泛滥的地步,但是已经让我有些不安了。简单搜索了一下刚才让我感觉到很多NOSONAR的project,结果是58个。
更糟糕的是,每个NOSONAR后面都不会带有注释说明为什么要NOSONAR,因此一个个飞舞的NOSONAR就变成了一个个谜团。想知道为什么要NOSONAR吗?恩,你猜......
我没有办法去检查这个58个NOSONAR是不是都合理的,都站得住脚的。出于程序员的习惯,对于一切不可确认性都报以怀疑的眼光和质疑的姿态,我总觉得这58个NOSONAR让我总是没有底,每次我看到sonar上100%的规则检测通过率时,我总是禁不住在心里浮现NOSONAR的字样。
好吧,我承认,我是个心里有些阴暗的家伙......
摘要: 在easymock的使用过程中,当创建mock对象时,我们会遇到 strict mock和nice mock的概念。上述的测试案例验证了strict mock和nice mock的基本使用,对于同一个mock对象,strict模式下多个方法之间的调用顺序在record阶段和replay阶段下是需要保持一致的。但是故事并不是到此结束,更有意思的内容在后面:如果出现多个mock对象,那么这些不同mock对象的方法之间,他们的调用顺序是否检测?普通mock和nice mock模式下自然是不会检测顺序,但是strict模式下呢?
阅读全文
摘要: IMocksControl接口容许创建多个mock对象,这些创建的对象自动关联到这个mocksControl实例上,以后再调用replay()/verify()/reset()时就不需要逐个列举出每个mock对象。当mock对象比较多,尤其是原有代码上新增mock 对象时非常方便。
阅读全文
摘要: 前面的例子中,mock的对象都是基于interface,虽然说我们总是强调要面对接口编程,而不要面对实现,但是实际开发中不提取interface而直接使用class的场景非常之多。尤其是一些当前只有一个明确实现而看不到未来扩展的类,是否应该提取interface或者说是否应该现在就提取interface,总是存在争论。
这种情况下,我们就会面临主要测试对象依赖到一个具体类而不是interface的情况,easymock中通过class extension 来提供对class mocking的支持。
阅读全文
摘要: 关于easymock的典型使用方式,在easymock的官网文档中,有非常详尽的讲解,文档地址为 http://easymock.org/EasyMock3_0_Documentation.html,文档的开头一部分内容都是easymock中最基本的使用介绍,虽然是英文,但是非常容易看懂,适用新学者入门。
这里只罗列一些简单的常用功能。
阅读全文
摘要: record-replay-verify 模型容许记录mock对象上的操作然后重演并验证这些操作。这是目前mock框架领域最常见的模型,几乎所有的mock框架都是用这个模型,有些是现实使用如easymock,有些是隐式使用如jmockit。
record-replay-verify 模型非常好的满足了大多数测试场景的需要:先指定测试的期望,然后执行测试,再验证期望是否被满足。这个模型简单直接,易于实现,也容易被开发人员理解和接受,因此被各个mock框架广泛使用。
阅读全文
摘要: 在单元测试中,通常我们都会有一个明确的测试对象,我们测试的主要目的就是为了验证这个类的工作如我们预期。
阅读全文
摘要: easymock是目前java mock 工具中比较流行的工具,这个教程将系统的介绍easymock的使用。
主要内容来自easymock的官网教程,针对日常使用进行了一些筛选和补充,另外增加一些个人的理解和认识。
另外考虑到网络上已有不少分散的教程,我将适当的链接进来。
教程的内容将在随后逐渐添加,目前计划的目录如下,相应内容完成之后我将逐个更新此文的链接。
阅读全文
近期发现一个问题,hudson执行任务时,经常不能获取到最新的代码,从而导致出现各种问题。
日常开发中的典型例子:发现一个bug,修改代码,本地测试通过,提交代码到subversion,手工激活hudson构建,原本期望hudson获取到刚刚提交的代码并测试/打包/发布。结果事与愿违,测试的结果发现刚刚做出的修改似乎没有生效。正费解之时,再执行一次hudson构建,又成功了...
经历过几次上述蹊跷遭遇之后,发现这个问题不是偶然。之后检查hudson的日志,发现问题的发现在最开始update / check out subversion代码时,明明已经提交的代码,hudson做update / check out时,居然没有update / check out下来!显示的subversion版本号也和subversion上实际的最新版本不一致,hudson总是要小一些,换言之,hudson update / check out的代码要比当前最新代码老一些。
google一番,发现这个问题之前就有人遭遇过,hudson上甚至已经有了好几个关于这个问题的bug,比如 http://issues.hudson-ci.org/browse/HUDSON-1241 "force using HEAD SVN version for build"。问题的根源在于hudson 获取subversion代码的方式,hudson是通过时间戳的方式来获取代码,而不是我们一般认为的"最新代码"即"HEAD"。这种方式通常没有问题,因为获取当前时间戳,然后要求update / checkout这个时间戳前的代码,理论上也是可以拿到最新代码的。
但是,如果hudson所在的服务器和subversion服务器时间不一致,这个机制就会出现问题:
我们假设subversion服务器的时间是准确的,再假设当时时间是15:10分,开发人员A提交代码,subversion上当前这个最新提交的代码时间戳为15:10:00。然后开发人员A手工激活hudson进行构建。hudson在15:10:20时开始check out代码。如果hudson时间无误,则hudson会发出请求说要求获取时间戳在15:10:20之前的代码,这样这个实际提交时间为15:10:00的新代码就可以如期的被check out。但是如果hudson的时钟有误,由于某些原因导致时钟偏慢2分钟,即在hudson上,"当前时间"为"15:08:20",则hudson获取代码的请求为:获取时间戳为15:08:20之前的代码,此时时间戳为15:10:00的新代码就无法checkout。
几分钟之后,疑惑的开发人员A再次激活hudson再次构建,假设此时时间时间是15:15:00,hudson慢两分钟为15:13:00。此时hudson发出请求: 获取时间戳为15:13:00之前的代码, 因此实际提交时间为15:10:00的新代码可以正常checkout,问题又在不知不觉被回避了。
总结说,hudson 获取代码的机制不是我们直觉中的获取最新代码(即subversion中HEAD checkout),而是基于时间戳。由于这个方式通常如HEAD般工作,因此我们总是容易误解为是获取最新代码。当hudson的时钟晚于subversion时,悲剧就出现了。
对这个问题,有几点疑惑:
1. 不明白为什么hudson不采用最直接最简单最容易被人理解最不容易出误解的HEAD checkout,而要基于时间戳
2. 这个问题很早就发生了,上面提到的bug 08年就被人提出, "Created: 31/Jan/08 05:37 AM Updated: 01/Jul/10 11:06 AM",三年了类似的bug被多次提出,但是就是始终没有修复。
修复的方式很简单,就改一个类的一行代码
in Class: hudson.scm.SubversionSCM
line 377:
final SVNRevision revision = SVNRevision.create(timestamp);
replace to:
final SVNRevision revision = SVNRevision.HEAD;
hudson拒绝修复的理由是什么?
Maven 3.0 的第一个RC版本终于发布了,下面是sonatype给出的发布信息:
Maven 在apache上的页面目前还没有放出RC1版本。下面是关于mavne3.*版本相对于2.* 版本的改进列表:
https://cwiki.apache.org/confluence/display/MAVEN/Maven+3.x+Compatibility+Notes
PS: 坦言说,改进很少,尤其没有大的功能改进,有点失望。
修订:上面的URL是兼容性列表,因此看起来和2.*差别不大,是我理解错了,抱歉。
摘要: 最新版本的confluence 3.3.1 linux 安装笔记。
阅读全文
摘要: 之前安装的fisheye2.2.1,破解不是很好用,最近看到fisheye2.3.6版本有出新的破解方式,特地尝试了一下,成功安装。现在将过程简单分享给大家。
阅读全文
摘要: 作为测试的基本概念,在开发测试中经常遇到mock和stub。之前认为自己对这两个概念已经很明白了,但是当决定要写下来并写清楚以便能让不明白的人也能弄明白,似乎就很有困难。
试着写下此文,以检验自己是不是真的明白mock和stub。
阅读全文
讲个笑话吧,关于"keep it simple"
这其实是个真实的故事,发生在两年前,当我从上一家公司离职时。
当时我移交了一个重要模块,后来不久,记不清了,大概一两个月后吧,有关系不错的同事告诉我说:某某人大肆宣扬,***模块我只找个了***的人,*天就接手了,云云。
言下之意自不必说。
而我,则将上述评论视为对自己的嘉奖,深以为荣。
*******************************************************************************
为了大家能看懂这个笑话,罗嗦一点介绍两个背景故事:
1. 最骄傲的事
工作9年了,回首看最令自己骄傲的事情,就是在07年的夏天,加班加点的工作了1个半月,将上述模块的新需求完成。开发模式是我最喜爱的TDD + 持续重构,完备的unit测试案例覆盖。后面测试中,3位负责测试同事用了三天的时间,测试完成所有的测试案例,全部一次性通过,没有一个bug,哪怕是小bug。
此记录本人之后两年中一直试图复制,至今没有成功。
2. 荒谬的问题
发生在离职做上述模块移交时,被接收人问了一个问题:项目代码里面,test目录下是什么东西啊?
import junit.***, extends TestCase...
无言以对。
摘要: Tokyo Tyrant基本规范,翻译自Tokyo Tyrant官网。
本节为Tokyo Tyrant的基础教程。
阅读全文
摘要:
Tokyo Tyrant基本规范,翻译自Tokyo Tyrant官网。
本节介绍Tokyo Tyrant的远程数据库API,Lua扩展和协议。部分细节内容没有翻译。
阅读全文
摘要:
Tokyo Tyrant基本规范,翻译自Tokyo Tyrant官网。
本节介绍Tokyo Tyrant的客户端程序。
阅读全文