XCode6 中XCTest支持异步的单元测试

过去因为每个测试是相互独立、顺序执行的,因此单元测试都是同步执行的。为了支持各种异步调用,XCode可以用来新的API和 XCTestExpectation 对象支持block,现在测试方法会等待调用完成或者超时。
一般的过程是,测试用例进行异步操作,并注册回调,然后等待expectation被满足。当异步操作结束时,通常会进入回调函数或者Block,测试案例在这里需要主动告知expectation已经被满足,从而结束run loop的等待,然后可以进行后续断言或操作。

Read More

javascript 单元测试覆盖率工具,及Grunt集成

js单元测试Unit Test的工具包括Jasmine, Mocha, NodeUnit, JsTestDriver等。

Jasmine最为流行,因为其良好的语义和丰富的Mocking机制。

无论使用Grunt.js或是Maven来作为项目构建工具,Jasmine都有良好的插件支持。

js单元测试其实并不为前端开发者重视,近年开始node.js以及单页面web app流行起来后,越来越多的js项目也开始采用了单元测试,至于单元测试覆盖率,对于很多js开发者还很新鲜。

笔者所在项目采用grunt.js作为项目工具。之前使用了grunt.js v0.3,采用grunt-jasmine-runner插件来运行测试,但一直苦于没有合适的覆盖率插件,后来发现了grunt-istanbul,然而两者不能够直接集成,需要对源代码进行改动,以使运行测试的浏览器(比如phantomjs)将生成的覆盖率数据,从内存中传递到grunt的上下文中。

于是,笔者在github上fork了项目,自行将两者整合成为完整的一步式插件grunt-jasmine-coverage,并发布到NPM上。

近期,grunt升级到v0.4, 官方的jasmine插件也换成了grunt-contrib-jasmine。经过笔者一番探索和讨论,发现该插件支持模板系统用于扩展功能,而且已有热心人制作了用于覆盖率的模板grunt-template-jasmine-istanbul。经过与其作者的讨论,现在该模板已经可以很好的支持同时生成多份覆盖率报告。比如,cobertura格式的报告,可以用于Jenkins集成,而lcov格式的报告,可以用于Sonar集成(需要sonar-javascript插件)

有一个小技巧,项目中除了包括自己的源代码,肯定也会包含其他第三方的库,比如jquery。而对于计算覆盖率,我们可能希望将第三方代码踢除出去。这时,在grunt-contrib-jamine的配置中,记得将第三方代码置入vender一节中,这样grunt-template-jasmine-istanbul在做instrument时会忽略掉这些代码。

此外,grunt.js对于nodeunit也有很好的支持

每日站会说什么?

经常听到有人抱怨说,敏捷实践中会议太多,形式主义严重。在真实了解实际情形后,我们会发现并非这些敏捷实践本身没有价值,而是因为没有正确地领会会议的目的,采取了不恰当的会议形式,或其它深层次的问题,导致会议不能产生预想的结果。每日站会就是一个例子。

首先必须明确,每日站会的目的:基于迭代目标的团队协作和快速反馈。更详细点地说,每日站会提供了在达成迭代目标过程中的团队协作同步点,以及快速反馈循环中的检查和调整点。它的目的不是汇报状态,不是要知晓每个团队成员昨天把时间花在了哪里,不是要知道每个人将要把时间投入在什么地方,而是对目标的跟踪和校准,以及加强在达成目标过程中的协调和合作。

Read More

用户故事使用中的十大错误

1) 在用户故事中,将开发中的相关人员作为系统用户角色

比如 As a po/apo/ppo/developer/tester/manager/integration engineer, I want 。。。

必须注意,As a 中的role是运行时实际使用该系统的用户角色,不是开发时干系人的角色

包括客户文档相关的用户故事,也要以实际使用该文档完成某项任务的视角来描述:什么角色,什么情况下使用该文档用来做什么,达到什么样的可衡量的目标等,而不是某经理要求该文档。

2) 把系统的发布版本放入用户故事标题中

Read More

Python中的注解:Decorator (Annotation)

python’s decorator is like Java’s annotation, but more flexible and easy to implement because of python’s syntax. Both is to use a time way to realize AOP, to insert job of other aspect and make you class/func concentrate to bussiness logic.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

def anna(fn):
def new_func(*args):
print 'by anna args=%s' % args
return fn(*args)
return new_func

def annie(ar):
print 'by annie1 ar=%s' % ar
def _A(fn):
def new_func(*args):
print 'by annie2 args=%s' % args
return fn(*args)
return new_func
return _A

class ccc():
@anna
def __init__(self):
print 'ccc'
@anna
def ff(self, a):
print a

 

@anna
def test1(a):
print a

@annie('hi')
def test2(a):
print a

test1((1,2))
test2((3,4))

Scrum忘记的土地- The Land that Scrum Forgot

Scrum is a starting point. In fact, it’s a great starting point. But, as a framework rather than a full-blown methodology, Scrum is deliberately incomplete. Some things—such as the best technical practices to use—are left for individual teams to determine. This allows a team to create the best fit between their project and environment and an assortment of technical practices.

Scrum是一个起点。事实上,这是一个很好的起点。但是,作为一个框架,而不是一个成熟的方法论,Scrum故意是不完整的。一些措施——例如使用最好的技术实践——留给每个团队自己来决定。这允许一个团队在他们的项目和环境和各式各样的技术实践之间创建最适合自己的方式。

Read More

源代码就是设计 (Source code is the design)

至今,我仍能记起当我顿悟并最终产生下面文章时所在的地方。那是1986年的夏天,我在加利福尼亚中国湖海军武器中心担任临时顾问。在这期间,我有幸参加了一个关于Ada的研讨会。讨论当中,有一位听众提出了一个具有代表性的问题,“软件开发者是工程师吗?”我不记得当时的回答,但是我却记得当时并没有真正解答这个问题。于是,我就退出讨论,开始思考我会怎样回答这样一个问题。现在,我无法肯定当时我为什么会记起几乎10年前曾经在Datamation杂志上阅读过的一篇论文,不过促使我记起的应该是后续讨论中的某些东西。这篇论文阐述了工程师为什么必须是好的作家(我记得该论文谈论就是这个问题——好久没有看了),但是我从该论文中得到的关键一点是:作者认为工程过程的最终结果是文档。换句话说,工程师生产的是文档,不是实物。其他人根据这些文档去制造实物。于是,我就在困惑中提出了一个问题,“除了软件项目正常产生的所有文档以外,还有可以被认为是真正的工程文档的东西吗?”我给出的回答是,“是的,有这样的文档存在,并且只有一份——源代码。”

Read More