我们很容易根据上下文将其提取为Given..When..Then的三段式自然语言
  Given a team, when newly created, it should have a name, and should have 11 players
  很简单啊有木有!在这样的语法下,是不是写测试的兴趣都被激发出来了呢。关于Kiwi的进一步语法和使用,我们稍后详细展开。首先来看看如何在项目中添加Kiwi框架吧。
  在项目中添加Kiwi
  简单和推荐的方法当然是CocoaPods,如果您对CocoaPods还比较陌生的话,推荐您花时间先看一看这篇CocoaPods的简介。Xcode 5和XCTest环境下,我们需要在Podfile中添加类似下面的条目(记得将VVStackTests换成您自己的项目的测试target的名字):
  target :VVStackTests, :exclusive => true do
  pod 'Kiwi/XCTest'
  end
  之后pod install以后,打开生成的xcworkspace文件,Kiwi已经处于可用状态了。另外,为了我们在新建测试的时候能省点事儿,可以在官方repo里下载并运行安装Kiwi的Xcode Template。如果您坚持不用CocoaPods,而想要自己进行配置Kiwi的话,可以参考这篇wiki。
  行为描述(Specs)和期望(Expectations),Kiwi测试的基本结构
  我们先来新建一个Kiwi测试吧。如果安装了Kiwi的Template的话,在新建文件中选择Kiwi/Kiwi Spec来建立一个Specs,取名为SimpleString,注意选择目标target为我们的测试target,模板将会在新建的文件名字后面加上Spec后缀。传统测试的文件名一般以Tests为后缀,表示这个文件中含有一组测试,而在Kiwi中,一个测试文件所包含的是一组对于行为的描述(Spec),因此习惯上使用需要测试的目标类来作为名字,并以Spec作为文件名后缀。在Xcode 5中建立测试时已经不会同时创建.h文件了,但是现在的模板中包含有对同名.h的引用,可以在创建后将其删去。如果您没有安装Kiwi的Template的话,可以直接创建一个普通的Objective-C test case class,然后将内容替换为下面这样:
  #import <Kiwi/Kiwi.h>
  SPEC_BEGIN(SimpleStringSpec)
  describe(@"SimpleString", ^{
  });
  SPEC_END
  你可能会觉得这不是objc代码,甚至怀疑这些语法是否能够编译通过。其实SPEC_BEGIN和SPEC_END都是宏,它们定义了一个KWSpec的子类,并将其中的内容包装在一个函数中(有兴趣的朋友不妨点进去看看)。我们现在先添加一些描述和测试语句,并运行看看吧,将上面的代码的SPEC_BEGIN和SPEC_END之间的内容替换为:

 

describe(@"SimpleString", ^{
context(@"when assigned to 'Hello world'", ^{
NSString *greeting = @"Hello world";
it(@"should exist", ^{
[[greeting shouldNot] beNil];
});
it(@"should equal to 'Hello world'", ^{
[[greeting should] equal:@"Hello world"];
});
});
});

  describe描述需要测试的对象内容,也即我们三段式中的Given,context描述测试上下文,也是这个测试在When来进行,后it中的是测试的本体,描述了这个测试应该满足的条件,三者共同构成了Kiwi测试中的行为描述。它们是可以nest的,也是一个Spec文件中可以包含多个describe(虽然我们很少这么做,一个测试文件应该专注于测试一个类);一个describe可以包含多个context,来描述类在不同情景下的行为;一个context可以包含多个it的测试例。让我们运行一下这个测试,观察输出:
  VVStack[36517:70b] + 'SimpleString, when assigned to 'Hello world', should exist' [PASSED]
  VVStack[36517:70b] + 'SimpleString, when assigned to 'Hello world', should equal to 'Hello world'' [PASSED]
  可以看到,这三个关键字的描述将在测试时被依次打印出来,形成一个完整的行为描述。除了这三个之外,Kiwi还有一些其他的行为描述关键字,其中比较重要的包括
  beforeAll(aBlock) - 当前scope内部的所有的其他block运行之前调用一次
  afterAll(aBlock) - 当前scope内部的所有的其他block运行之后调用一次
  beforeEach(aBlock) - 在scope内的每个it之前调用一次,对于context的配置代码应该写在这里
  afterEach(aBlock) - 在scope内的每个it之后调用一次,用于清理测试后的代码
  specify(aBlock) - 可以在里面直接书写不需要描述的测试
  pending(aString, aBlock) - 只打印一条log信息,不做测试。这个语句会给出一条警告,可以作为一开始集中书写行为描述时还未实现的测试的提示。
  xit(aString, aBlock) - 和pending一样,另一种写法。因为在真正实现时测试时只需要将x删掉是it,但是pending语意更明确,因此还是推荐pending
  可以看到,由于有context的存在,以及其可以嵌套的特性,测试的流程控制相比传统测试可以更加精确。我们更容易把before和after的作用区域限制在合适的地方。
  实际的测试写在it里,是由一个一个的期望(Expectations)来进行描述的,期望相当于传统测试中的断言,要是运行的结果不能匹配期望,则测试失败。在Kiwi中期望都由should或者shouldNot开头,并紧接一个或多个判断的的链式调用,大部分常见的是be或者haveSomeCondition的形式。在我们上面的例子中我们使用了should not be nil和should equal两个期望来确保字符串赋值的行为正确。其他的期望语句非常丰富,并且都符合自然语言描述,所以并不需要太多介绍。在使用的时候不妨直接按照自己的想法来描述自己的期望,一般情况下在IDE的帮助下我们都能找到想要的结果。如果您想看看完整的期望语句的列表,可以参看文档的这个页面。另外,您还可以通过新建KWMatcher的子类,来简单地自定义自己和项目所需要的期望语句。从这一点来看,Kiwi可以说是一个非常灵活并具有可扩展性的测试框架。
  到此为止的代码可以从这里找到。
  Kiwi实际使用实例
  后我们来用Kiwi完整地实现VVStack类的测试和开发吧。首先重写刚才XCTest的相关测试:新建一个VVStackSpec作为Kiwi版的测试用例,然后把describe换成下面的代码: