PageRenderTime 63ms CodeModel.GetById 32ms RepoModel.GetById 1ms app.codeStats 0ms

/blog/2015/01/29/xctestdan-yuan-ce-shi/index.html

https://github.com/lingzuer/lingzuer.github.com
HTML | 309 lines | 247 code | 58 blank | 4 comment | 0 complexity | deb93ece6c4cb61af25bee12624b43a9 MD5 | raw file
  1. <!DOCTYPE html>
  2. <!--[if IEMobile 7 ]><html class="no-js iem7"><![endif]-->
  3. <!--[if lt IE 9]><html class="no-js lte-ie8"><![endif]-->
  4. <!--[if (gt IE 8)|(gt IEMobile 7)|!(IEMobile)|!(IE)]><!--><html class="no-js" lang="en"><!--<![endif]-->
  5. <head>
  6. <meta charset="utf-8">
  7. <title>XCTest单元测试 - 北武灵尊</title>
  8. <meta name="author" content="lingzuer">
  9. <meta name="description" content="QA的同事说帮他们讲一下OC,我自己都是个搓鸟,还给别人讲,就当是玩笑拒绝了,那么多大牛都在,找我讲?后来又说让我讲,是认真的,那我想,反正他们也不会,忽悠一下他们还是OK的了,简单的写个Hello World还是不成问题的,于是就去讲了,讲到后来才明白他们想的最终需求是:单元测试。 &hellip;">
  10. <!-- http://t.co/dKP3o1e -->
  11. <meta name="HandheldFriendly" content="True">
  12. <meta name="MobileOptimized" content="320">
  13. <meta name="viewport" content="width=device-width, initial-scale=1">
  14. <link rel="canonical" href="http://lingzuer.github.io/blog/2015/01/29/xctestdan-yuan-ce-shi">
  15. <link href="/favicon.png" rel="icon">
  16. <link href="/stylesheets/screen.css" media="screen, projection" rel="stylesheet" type="text/css">
  17. <link href="/atom.xml" rel="alternate" title="北武灵尊" type="application/atom+xml">
  18. <script src="/javascripts/modernizr-2.0.js"></script>
  19. <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  20. <script>!window.jQuery && document.write(unescape('%3Cscript src="/javascripts/libs/jquery.min.js"%3E%3C/script%3E'))</script>
  21. <script src="/javascripts/octopress.js" type="text/javascript"></script>
  22. <!--Fonts from Google"s Web font directory at http://google.com/webfonts -->
  23. <link href="//fonts.googleapis.com/css?family=PT+Serif:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">
  24. <link href="//fonts.googleapis.com/css?family=PT+Sans:regular,italic,bold,bolditalic" rel="stylesheet" type="text/css">
  25. </head>
  26. <body >
  27. <header role="banner"><hgroup>
  28. <h1><a href="/">北武灵尊</a></h1>
  29. <h2>记录一些事情方便查阅</h2>
  30. </hgroup>
  31. </header>
  32. <nav role="navigation"><ul class="subscription" data-subscription="rss">
  33. <li><a href="/atom.xml" rel="subscribe-rss" title="subscribe via RSS">RSS</a></li>
  34. </ul>
  35. <form action="https://www.google.com/search" method="get">
  36. <fieldset role="search">
  37. <input type="hidden" name="sitesearch" value="lingzuer.github.io">
  38. <input class="search" type="text" name="q" results="0" placeholder="Search"/>
  39. </fieldset>
  40. </form>
  41. <ul class="main-navigation">
  42. <li><a href="/">Blog</a></li>
  43. <li><a href="/blog/archives">Archives</a></li>
  44. </ul>
  45. </nav>
  46. <div id="main">
  47. <div id="content">
  48. <div>
  49. <article class="hentry" role="article">
  50. <header>
  51. <h1 class="entry-title">XCTest单元测试</h1>
  52. <p class="meta">
  53. <time class='entry-date' datetime='2015-01-29T22:14:13+08:00'><span class='date'><span class='date-month'>Jan</span> <span class='date-day'>29</span><span class='date-suffix'>th</span>, <span class='date-year'>2015</span></span> <span class='time'>10:14 pm</span></time>
  54. </p>
  55. </header>
  56. <div class="entry-content"><p>QA的同事说帮他们讲一下OC我自己都是个搓鸟还给别人讲就当是玩笑拒绝了那么多大牛都在找我讲后来又说让我讲是认真的那我想反正他们也不会忽悠一下他们还是OK的了简单的写个Hello World还是不成问题的于是就去讲了讲到后来才明白他们想的最终需求是单元测试作为开发我从来没有了解过这一块我说自己回去先写个Demo于是上网各种搜索还是有些收获的昨天晚上到12:40对UI和属性的测试有了点思路完成一个简单的Demo就当是单元测试的Hello World吧今天上午又搞定了异步请求的单元测试结合自己项目方便写登录的请求写了一个Demo这也是列为今天todo list的第一个任务现在记录一下</p>
  57. <p>1新建一个测试的Target</p>
  58. <p><img src="/images/blog/test-target.png" alt="Test Target" /></p>
  59. <p>2设置Search Paths
  60. 保持和项目的Target设置一致不然在引用文件的时候可能会提示有些文件找不到比如LoginManager.h:10:9: fatal error: &lsquo;biz/service/auth/auth_protocol.h&rsquo; file not found</p>
  61. <p><img src="/images/blog/search-paths.png" alt="Search Paths" /></p>
  62. <p>3新建Test Class</p>
  63. <p>见图一</p>
  64. <p>4引入需要的文件开始测试
  65. 比如要写一个登录的单元测试那要引入LoginManager.h之类的文件吧我大概写一下有些是项目的代码不知道写在博文里面好不好</p>
  66. <pre><code>#import &lt;UIKit/UIKit.h&gt;
  67. #import &lt;XCTest/XCTest.h&gt;
  68. #import "LoginManager.h"
  69. #import "LoginCallBack.h"
  70. @interface MyTests : XCTestCase {
  71. XCTestExpectation *_expectation;
  72. }
  73. @end
  74. @implementation MyTests
  75. - (void)setUp {
  76. [super setUp];
  77. [self addListenEvents];
  78. }
  79. - (void)tearDown {
  80. [self removeListenEvents];
  81. [super tearDown];
  82. }
  83. #pragma mark - 通知
  84. - (void)addListenEvents {
  85. extern NSString *kYIXINNotificationLoginResult;
  86. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onGetLoginResult:) name:kYIXINNotificationLoginResult object:nil];
  87. }
  88. - (void)removeListenEvents {
  89. [[NSNotificationCenter defaultCenter] removeObserver:self];
  90. }
  91. #pragma mark - Test Methods
  92. - (void)testUserLogin {
  93. _expectation = [self expectationWithDescription:@"Login request"];
  94. NSString *username = @"userID";
  95. NSString *password = @"111111";
  96. [LoginManager sharedManager].currentLoginData.userName = username;
  97. [LoginManager sharedManager].currentLoginData.userPassword = [XXUtil encytePassword:password];
  98. [LoginManager sharedManager].currentLoginData.type = kAccountYid;
  99. [[LoginManager sharedManager] beginLogin];
  100. [self waitForExpectationsWithTimeout:5
  101. handler:^(NSError *error) {
  102. // handler is called on _either_ success or failure
  103. if (error != nil) {
  104. XCTFail(@"timeout error: %@", error);
  105. }
  106. }];
  107. }
  108. #pragma mark - LoginResultProtocol
  109. - (void)onGetLoginResult:(NSNotification*)aNotification {
  110. extern NSString *kLoginStepKey;
  111. extern NSString *kLoginResultKey;
  112. NSDictionary *data = aNotification.userInfo;
  113. NSInteger step = [[data objectForKey:kLoginStepKey] intValue];
  114. NSInteger errorCode = [[data objectForKey:kLoginResultKey] intValue];
  115. if (step == kLoginStepLogin) {
  116. [_expectation fulfill];
  117. if (errorCode == kResSuccess) {
  118. XCTAssert(YES, @"Pass");
  119. } else {
  120. XCTAssert(NO, @"No Pass");
  121. }
  122. } else {
  123. NSLog(@ "login result: step is %@, code is %@",@(step), @(errorCode));
  124. }
  125. }
  126. @end
  127. </code></pre>
  128. <p>5异步测试要点</p>
  129. <pre><code>_expectation = [self expectationWithDescription:@"Login request”];
  130. [_expectation fulfill];
  131. XCTAssert(YES, @"Pass");
  132. </code></pre>
  133. <p>6其他</p>
  134. <p>其他的异步测试比如BlockDelegate的方式也都如此(采用XCTestExpectation)</p>
  135. <p>7参考资料</p>
  136. <ul>
  137. <li><a href="http://objccn.io/issue-15-2/">http://objccn.io/issue-15-2/</a></li>
  138. <li><a href="http://www.objc.io/issue-15/xctest.html">http://www.objc.io/issue-15/xctest.html</a></li>
  139. <li><a href="http://www.bignerdranch.com/blog/asynchronous-testing-with-xcode-6/">http://www.bignerdranch.com/blog/asynchronous-testing-with-xcode-6/</a></li>
  140. <li><a href="http://blog.dadabeatnik.com/2014/07/13/asynchronous-unit-testing-in-xcode-6/">http://blog.dadabeatnik.com/2014/07/13/asynchronous-unit-testing-in-xcode-6/</a></li>
  141. <li><a href="http://www.pumpmybicep.com/2014/08/22/objective-c-http-stubbing-libraries/">http://www.pumpmybicep.com/2014/08/22/objective-c-http-stubbing-libraries/</a></li>
  142. <li><a href="http://iosunittesting.com/asynchronous-tests-using-xctestexpectation/">http://iosunittesting.com/asynchronous-tests-using-xctestexpectation/</a></li>
  143. <li><a href="http://www.pumpmybicep.com/2014/08/20/asynchronous-unit-testing-with-xctest/">http://www.pumpmybicep.com/2014/08/20/asynchronous-unit-testing-with-xctest/</a></li>
  144. <li><a href="http://nshipster.com/xctestcase/">http://nshipster.com/xctestcase/</a></li>
  145. <li><a href="http://ocmock.org">http://ocmock.org</a></li>
  146. </ul>
  147. </div>
  148. <footer>
  149. <p class="meta">
  150. <span class="byline author vcard">Posted by <span class="fn">lingzuer</span></span>
  151. <time class='entry-date' datetime='2015-01-29T22:14:13+08:00'><span class='date'><span class='date-month'>Jan</span> <span class='date-day'>29</span><span class='date-suffix'>th</span>, <span class='date-year'>2015</span></span> <span class='time'>10:14 pm</span></time>
  152. </p>
  153. <div class="sharing">
  154. </div>
  155. <p class="meta">
  156. <a class="basic-alignment left" href="/blog/2015/01/28/hello-to-myself/" title="Previous Post: Hello To Myself">&laquo; Hello To Myself</a>
  157. <a class="basic-alignment right" href="/blog/2015/01/30/ji-lei-de-jiao-ben/" title="Next Post: 积累的脚本">积累的脚本 &raquo;</a>
  158. </p>
  159. </footer>
  160. </article>
  161. </div>
  162. <aside class="sidebar">
  163. <section>
  164. <h1>Recent Posts</h1>
  165. <ul id="recent_posts">
  166. <li class="post">
  167. <a href="/blog/2015/02/06/yi-xin-nian-hui/">易信年会</a>
  168. </li>
  169. <li class="post">
  170. <a href="/blog/2015/02/05/alassetslibraryxuan-ze-tu-pian-you-hua/">ALAssetsLibrary选择图片优化</a>
  171. </li>
  172. <li class="post">
  173. <a href="/blog/2015/02/02/assetslibraryzi-ding-yi-tu-pian-xuan-ze-qi/">AssetsLibrary自定义图片选择器</a>
  174. </li>
  175. <li class="post">
  176. <a href="/blog/2015/02/01/chang-yong-gong-ju/">常用工具</a>
  177. </li>
  178. <li class="post">
  179. <a href="/blog/2015/01/31/xctestce-shi-shu-xing-bian-hua/">XCTest测试属性变化</a>
  180. </li>
  181. </ul>
  182. </section>
  183. </aside>
  184. </div>
  185. </div>
  186. <footer role="contentinfo"><p>
  187. Copyright &copy; 2015 - lingzuer -
  188. <span class="credit">Powered by <a href="http://octopress.org">Octopress</a></span>
  189. </p>
  190. </footer>
  191. </body>
  192. </html>