(void)testUrlencode
{
GHAssertEqualStrings([self.toBeEncode urlencode], self.encoded,
@"URLEncode Error.",
self.toBeEncode, self.encoded);
GHAssertEqualStrings([self.encoded urldecode], self.toBeEncode,
@"URLDecode Error.",
self.encoded, self.toBeEncode);
}

 

  代码5,URLEncode测试用例
  在进行这个测试之前,urlencode的实现忽视了对“~”的编码,正是由于单元测试用例所取的特殊字符是单独列举,并非从实现枚举中获取,检查出了这个错误。
  引入匹配引擎,使用匹配引擎默认规则
  前文提到过匹配引擎可以使测试用例中的断言更加丰富,URLManager的用例中也使用了匹配引擎:OCHamcrest。
  在此前的介绍中提到,引入OCHamcrest可以通过定义“HC_SHORTHAND”来开启匹配引擎的简写模式。因为开启简写模式后匹配规则中的“containsString”规则和上述例子(代码5)中的“containsString:”方法命名冲突,导致测试程序无法正常运行,所以这个工程直接使用了类似“HC_asserTaht”这样带有HC前缀的完整命名。
  我建议使用匹配引擎的开发者谨慎开启简写功能,OCHamcrest的匹配规则简写通常是很常见的单词,非常容易与工程中的类定义或方法定义重名。即使当下没有规则和方法名发生冲突,随着工程代码量的增加,一旦出现命名冲突的情况,重构的成本将非常高。
  匹配引擎可以提供更丰富的断言,简单的例如,URLManager的UMURL扩展支持向一个URL上添加参数,对这个方法测试断言用到了匹配某个字符串是否包含某子串的规则(代码6)。
  #pragma mark - UMURL
  - (void)testAddParams
  {
  NSURL *queryUrl = [self.noQueryUrl addParams:@{@"p1":@"v1",@"p2":@"v2"}];
  HC_assertThat(queryUrl.absoluteString, HC_containsString(@"p1=v1"));
  HC_assertThat(queryUrl.absoluteString, HC_containsString(@"p2=v2"));
  }
  代码6,URL参数测试用例
  匹配规则中的陷阱
  由于匹配规则的粒度较细,所以对于某些运行结果需要考虑到多种情况,否则正常的结果也可能会断言失败。
  例如测试用例期望得到一个空容器(例如:NSArray),而SDK则认为这个容器已经没有存在的必要而释放了他,返回的是一个nil。对removeAllSubviews的测试中,对一个view调用removeAllSubviews方法,期望view.subviews为空。在SDK 6.x甚至SDK 7 DP1之前,都是没问题的,但在SDK 7 DP3中,SDK会把所有清空的容器和对象释放,以回收系统资源。在这种条件下view.subviews返回的是nil,如果只是做类似HC_empty()这样的匹配,断言会失败,所以在断言之前做一个subviews属性的空判断(代码7)。

 

(void)testRemoveAllSubviews
{
UIView *subViewA = [[UIView alloc] init];
UIView *subViewB = [[UIView alloc] init];
[self.view addSubview:subViewA];
[self.view addSubview:subViewB];
HC_assertThat(self.view.subviews, HC_containsInAnyOrder(subViewA, subViewB, nil));
[self.view removeAllSubviews];
if (nil != self.view.subviews) {
HC_assertThat(self.view.subviews, HC_empty());
}
}

  代码7,removeAllSubviews用例
  另外,在默认匹配规则中会有一些容易产生歧义的命名,以collection的containsInAnyOrder为例:匹配对象是一个collection对象(也是遵循NSFastEnumeration协议的对象,NSArray等),给出若干个匹配规则或元素。期待这个规则匹配该对象是否包含给出的若干元素,且不关心顺序。但在实际测试过程中会发现,这个规则要求给出的元素必须是该collection对象的完备集,也是说要求给出的元素列表和要匹配的容器对象中的元素必须是相等的结合,但允许不关注顺序。
  对UMNavigationController的测试中,需要判断增加一项URL Mapping是否生效,如果使用该匹配规则,不能单纯判断config是否包含增量的URL,要断言成功必须连同此前config属性初始化写入的值一起考虑,使用一个完整的元素集合进行匹配(代码8)。