此前,我们在《iOS开发中的单元测试(一)&(二)》中介绍了从使用者的角度对比当下比较流行的两款单元测试框架OCUnit和GHUnit,这篇文章中我们将介绍一款导航控件URLManager。
  URLManager是一个基于UINavigationController和UIViewController,以URL Scheme为设计基础的导航控件,目的是实现ViewController的松耦合,不依赖。
  准备框架,定义基类
  首先按照之前的两篇文章介绍的方法导入单元测试框架和匹配引擎框架,建立好测试Target,并配置编译选项。
  定义测试用例基类:UMTestCase(代码1),其他用例全部继承自UMTestCase。
  #import
  @interface UMTestCase : GHTestCase
  @end
  代码1,UMTestCase,用例基类
  构建用例
  URLManager工具类(UMTools)测试用例(UMToolsTestCase)。UMTools中扩展了NSURL,NSString和UIView,方法涉及到给URL添加QueryString和从QueryString中读取参数,对字符串做子串判断,进行URL的编码和解码,对UIView的x,y,width和height的直接读写等。需要在用例中定义测试过程中会使用到属性(代码2), 并在setUpClass中初始化他们(代码3)。
  代码2,定义属性// 普通字符串,带有字母和数字

 

@property   (strong, nonatomic)     NSString    *string;
// 普通字符串,仅带有字母
@property   (strong, nonatomic)     NSString    *stringWithoutNumber;
// 将被做URLEncode的字符串,含有特殊字符和汉字
@property   (strong, nonatomic)     NSString    *toBeEncode;
// 把 toBeEncode 编码后的串
@property   (strong, nonatomic)     NSString    *encoded;
// 普通的URL,带有QueryString
@property   (strong, nonatomic)     NSURL       *url;
// 去掉上边一个URL的QueryString
@property   (strong, nonatomic)     NSURL       *noQueryUrl;
// 一个普通的UIView
@property   (strong, nonatomic)     UIView      *view;
(void)setUpClass
{
self.string                 = @"NSString For Test with a number 8848.";
self.stringWithoutNumber    = @"NSString For Test.";
self.toBeEncode             = @"~!@#$%^&*()_+=-[]{}:;"'<>.,/?123qwe汉字";
self.encoded                = @"%7E%21%40%23%24%25%5E%26%2A%28%29_%2B%3D-%5B%5D%
7B%7D%3A%3B%22%27%3C%3E.%2C%2F%3F123qwe%E6%B1%89%E5%AD%97";
self.url                    = [NSURL URLWithString:@"http://example.com
/patha/pathb/?p2=v2&p1=v1"];
self.noQueryUrl             = [NSURL URLWithString:@"http://example.com
/patha/pathb/"];
self.view                   = [[UIView alloc] initWithFrame:CGRectMake(10.0f,
10.0f, 100.0f, 100.f)];
}

 

  代码3,初始化属性
  使用单元测试框架中的断言处理简单用例
  单元测试是白盒测试,要做到路径覆盖(代码4)。 对“ContainsString”的测试进行正向和反向两种情况(即YES和NO两种返回结果)。

 

#pragma mark - UMString
- (void)testUMStringContainsString
{
NSString *p = @"For";
NSString *np = @"BAD";
GHAssertTrue([self.string containsString:p],
@""%@" should contains "%@".",
self.string, p);
GHAssertFalse([self.string containsString:np],
@""%@" should not contain "%@".",
self.string, p);

 

  代码4,字符串测试用例
  同时单元测试又要对功能负责,因此在路径覆盖之外还要尽量照顾到完整的功能。例如,对URLEncode的测试(代码5),要对尽量全面的特殊字符进行测试,而不是从源码实现中取出枚举的字符。