<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"> <channel><title>Quality Coding</title> <link>http://qualitycoding.org</link> <description>Tools, tips &amp; techniques for building quality in to iOS development.</description> <lastBuildDate>Mon, 13 May 2013 06:06:33 +0000</lastBuildDate> <language>en-US</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.5.1</generator> <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/qualitycoding" /><feedburner:info uri="qualitycoding" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><creativeCommons:license>http://creativecommons.org/licenses/by-nc-sa/3.0/</creativeCommons:license><xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" /><image><link>http://qualitycoding.org/</link><url>http://qualitycoding.org/logo-144x144.jpg</url><title>Quality Coding for iOS developers</title></image><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fqualitycoding" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fqualitycoding" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fqualitycoding" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/qualitycoding" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fqualitycoding" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:browserFriendly>Thanks for subscribing! Now you'll know when I post something new. You can also subscribe by email; start at the blog and go to Subscribe. —Jon</feedburner:browserFriendly><item><title>CocoaConf vs. WWDC</title><link>http://feedproxy.google.com/~r/qualitycoding/~3/KWvgKFbcjSs/</link> <comments>http://qualitycoding.org/cocoaconf-2013/#comments</comments> <pubDate>Tue, 23 Apr 2013 05:01:44 +0000</pubDate> <dc:creator>Jon Reid</dc:creator> <category><![CDATA[Uncategorized]]></category> <guid isPermaLink="false">http://qualitycoding.org/?p=1324</guid> <description><![CDATA[<p>I just wrapped up a great weekend with CocoaConf San Jose. I&#8217;ve gotta say: if you&#8217;re looking to maximize bang for your buck, save the money you&#8217;d spend on WWDC and consider CocoaConf instead! First, there&#8217;s the stress of trying to get a WWDC ticket. Then the expense. Sure, there are all those great talks, [...]</p><p><hr
/><p>You just finished reading "<a
href="http://qualitycoding.org/cocoaconf-2013/">CocoaConf vs. WWDC</a>" on <a
href="http://qualitycoding.org">Quality Coding</a>. I'd love to hear your thoughts about it!</p></p>]]></description> <content:encoded><![CDATA[<p><img
class="aligncenter size-full wp-image-1325" alt="cocoaconf" src="http://qualitycoding.org/jrwp/wp-content/uploads/2013/04/cocoaconf.jpg" width="274" height="450" /></p><p>I just wrapped up a great weekend with CocoaConf San Jose. I&#8217;ve gotta say: if you&#8217;re looking to maximize bang for your buck, save the money you&#8217;d spend on WWDC and consider CocoaConf instead!</p><p>First, there&#8217;s the stress of trying to get a WWDC ticket. Then the expense. Sure, there are all those great talks, but Apple makes the videos available to registered developers. I think the main reason to continue going to WWDC is if you&#8217;re really desperate to get help in the Apple labs.</p><p>I&#8217;d never been to another iOS/Mac developer&#8217;s conference before this past weekend. I was impressed by:</p><ul><li><span
style="line-height: 13px;"><strong>The small size.</strong> With only a hundred developers, there were many opportunities to build relationships, even with the speakers.</span></li><li><strong>The speakers.</strong> This is a class act of experienced people. Many of them are published authors. They&#8217;re there because they&#8217;re passionate about their craft.</li><li><strong>The food.</strong> Remember when WWDC food used to be decent, before the iOS-induced population explosion? This was like that, only better. Much better.</li><li><strong>The duration.</strong> My brain is full by the third day of any conference. CocoaConf wisely stops there.</li><li><strong>The price.</strong> Way cheaper.</li></ul><p>I came away having learned good stuff. But maybe just as important, I made <strong>genuine human connections.</strong> (Good luck doing that at the great cattle-herding of WWDC.)</p><p>CocoaConf is a traveling conference, hitting up several cities in the U.S. You owe it to yourself to <a
href="http://cocoaconf.com" target="_blank">check out the one nearest you</a>.</p><p><hr
/><p>You just finished reading "<a
href="http://qualitycoding.org/cocoaconf-2013/">CocoaConf vs. WWDC</a>" on <a
href="http://qualitycoding.org">Quality Coding</a>. I'd love to hear your thoughts about it!</p></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/qualitycoding?a=KWvgKFbcjSs:IoYHYwTNX2c:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/qualitycoding?i=KWvgKFbcjSs:IoYHYwTNX2c:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=KWvgKFbcjSs:IoYHYwTNX2c:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/qualitycoding?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=KWvgKFbcjSs:IoYHYwTNX2c:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/qualitycoding?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=KWvgKFbcjSs:IoYHYwTNX2c:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/qualitycoding?i=KWvgKFbcjSs:IoYHYwTNX2c:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/qualitycoding/~4/KWvgKFbcjSs" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://qualitycoding.org/cocoaconf-2013/feed/</wfw:commentRss> <slash:comments>2</slash:comments> <feedburner:origLink>http://qualitycoding.org/cocoaconf-2013/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=cocoaconf-2013</feedburner:origLink></item> <item><title>Why #import Order Matters</title><link>http://feedproxy.google.com/~r/qualitycoding/~3/wDSEVS0l-s0/</link> <comments>http://qualitycoding.org/import-order/#comments</comments> <pubDate>Tue, 26 Mar 2013 05:15:03 +0000</pubDate> <dc:creator>Jon Reid</dc:creator> <category><![CDATA[Objective-C]]></category> <guid isPermaLink="false">http://qualitycoding.org/?p=1294</guid> <description><![CDATA[<p>In #imports gone wild!&#160;we looked at&#160;the problems caused by having too many #import directives. But it&#8217;s also possible that you have too few, resulting in bad header files — especially if you don&#8217;t pay attention to #import order in your .m files. Minimal and complete When it comes to imports, header files should satisfy these [...]</p><p><hr
/><p>You just finished reading "<a
href="http://qualitycoding.org/import-order/">Why #import Order Matters</a>" on <a
href="http://qualitycoding.org">Quality Coding</a>. I'd love to hear your thoughts about it!</p></p>]]></description> <content:encoded><![CDATA[<div
id="attachment_1295" class="wp-caption aligncenter" style="width: 580px"><img
class="size-full wp-image-1295 " alt="" src="http://qualitycoding.org/jrwp/wp-content/uploads/2013/03/missing-imports.jpg" width="570" height="355" /><p
class="wp-caption-text">Use good #import order to prevent incomplete headers</p></div><p>In <a
href="http://qualitycoding.org/file-dependencies/">#imports gone wild!</a>&nbsp;we looked at&nbsp;the problems caused by having too many #import directives. But it&#8217;s also possible that you have too few, resulting in bad header files — especially if you don&#8217;t pay attention to #import order in your .m files.</p><h2>Minimal and complete</h2><p>When it comes to imports, header files should satisfy these two conditions:</p><ul><li>They should be <strong>minimal</strong></li><li>They should be <strong>complete</strong></li></ul><p>&#8220;Minimal&#8221; just means a header file should import no more than it needs.<br
/> &#8220;Complete&#8221; means the header file imports everything that needed to compile it. Consider <span
id="more-1294"></span></p><div
class="codecolorer-container objc default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div
class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span
style="color: #6e371a;">#import &quot;foo.h&quot;</span><br
/> <span
style="color: #6e371a;">#import &quot;bar.h&quot;</span></div></div><p>If removing foo.h (or changing the order) causes bar.h not to compile, then bar.h is not complete.</p><h2>Incomplete headers</h2><blockquote
class="pull"><p>Poor #import order masks dependencies</p></blockquote><p>One way to have an incomplete header is by relying on <a
href="http://qualitycoding.org/precompiled-headers/">precompiled headers</a>. In particular, just because the precompiled headers include a particular header doesn&#8217;t mean you can omit it elsewhere.</p><p>Another way to have an incomplete header is with a poor #import order that masks dependencies. In C-based languages, programmers often begin their implementation files by including the most general headers from the largest scope. They work down from there, until they reach the most specific headers:</p><ol><li>system headers</li><li>other headers</li><li>finally, the unit&#8217;s own header</li></ol><p>This is backwards. Consider a header foo.h that depends on &lt;QuartzCore/QuartzCore.h&gt;. If foo.m imports QuartzCore first, then other stuff, then finally gets to its own header, you may not feel the need to import QuartzCore in foo.h.</p><p>…And this will break for the next programmer who comes along and just imports foo.h.</p><h2>Good #import order</h2><p>The solution is simple: reverse the order! Start from the most specific, then work towards the most general. Most importantly, <strong>include your own header first.</strong>&nbsp;<a
href="http://www.amazon.com/gp/product/0201633620/ref=as_li_ss_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0201633620&amp;linkCode=as2&amp;tag=qualitycoding-20">Large-Scale C++ Software Design</a> by John Lakos is the only book I know about &#8220;physical design&#8221; — how to arrange source code into files. The author states,</p><blockquote><p>Latent usage errors can be avoided by ensuring that the .h file of a component parses by itself – without externally-provided declarations or definitions… Including the .h file as the very first line of the .c file ensures that no critical piece of information intrinsic to the physical interface of the component is missing from the .h file (or, if there is, that you will find out about it as soon as you try to compile the .c file).</p></blockquote><p>In other words, by including your own header first… if the header is not complete, you will fail fast!</p><p>Here&#8217;s what I do. If I&#8217;m writing foo.m, I first import foo.h. I keep this separated from other imports by a blank line. All the others follow, in sorted order:</p><div
class="codecolorer-container objc default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div
class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span
style="color: #6e371a;">#import &quot;foo.h&quot;</span><br
/> <br
/> <span
style="color: #6e371a;">#import &quot;abc.h&quot;</span><br
/> <span
style="color: #6e371a;">#import &quot;def.h&quot;</span><br
/> <span
style="color: #6e371a;">#import &lt;Abc/Abc.h&gt;</span></div></div><p>Sorting helps me find duplicates. It also&nbsp;puts angle brackets imports &lt;&gt; after quoted imports, so that the most general headers come last.</p><p>Questions? Comments?</p><div
class="aligncenter"><iframe
style="width: 120px; height: 240px;" src="http://rcm.amazon.com/e/cm?lt1=_blank&amp;bc1=000000&amp;IS2=1&amp;bg1=FFFFFF&amp;fc1=000000&amp;lc1=0000FF&amp;t=qualitycoding-20&amp;o=1&amp;p=8&amp;l=as4&amp;m=amazon&amp;f=ifr&amp;ref=ss_til&amp;asins=0201633620" height="240" width="320" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe></div><p
class="attribute">Photo by <a
href="http://www.flickr.com/photos/jasonjthomas/4828832743/" target="_blank">Jason Thomas</a> (<a
href="http://creativecommons.org/licenses/by-nc-sa/2.0/deed.en" target="_blank">license</a>), adapted by Jon Reid</p><p><hr
/><p>You just finished reading "<a
href="http://qualitycoding.org/import-order/">Why #import Order Matters</a>" on <a
href="http://qualitycoding.org">Quality Coding</a>. I'd love to hear your thoughts about it!</p></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/qualitycoding?a=wDSEVS0l-s0:Vzmr902j54I:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/qualitycoding?i=wDSEVS0l-s0:Vzmr902j54I:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=wDSEVS0l-s0:Vzmr902j54I:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/qualitycoding?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=wDSEVS0l-s0:Vzmr902j54I:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/qualitycoding?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=wDSEVS0l-s0:Vzmr902j54I:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/qualitycoding?i=wDSEVS0l-s0:Vzmr902j54I:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/qualitycoding/~4/wDSEVS0l-s0" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://qualitycoding.org/import-order/feed/</wfw:commentRss> <slash:comments>2</slash:comments> <feedburner:origLink>http://qualitycoding.org/import-order/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=import-order</feedburner:origLink></item> <item><title>iOS Model-View-Controller TDD [Screencast]</title><link>http://feedproxy.google.com/~r/qualitycoding/~3/jAomdnaB4Cc/</link> <comments>http://qualitycoding.org/mvc-tdd/#comments</comments> <pubDate>Fri, 08 Mar 2013 07:42:06 +0000</pubDate> <dc:creator>Jon Reid</dc:creator> <category><![CDATA[TDD]]></category> <guid isPermaLink="false">http://qualitycoding.org/?p=1258</guid> <description><![CDATA[<p>Can't see the video in your RSS reader or email? Click Here! The UIViewController TDD screencast ended with all the code in the view controller. Unfortunately, this is where many iOS programmers leave things! In part 2, we pick up from there and TDD to extract a model class, which the controller observes. You&#8217;ll see it [...]</p><p><hr
/><p>You just finished reading "<a
href="http://qualitycoding.org/mvc-tdd/">iOS Model-View-Controller TDD [Screencast]</a>" on <a
href="http://qualitycoding.org">Quality Coding</a>. I'd love to hear your thoughts about it!</p></p>]]></description> <content:encoded><![CDATA[<p><iframe
title="YouTube video player" width="570" height="360" src="http://www.youtube.com/embed/YTFfNVlYiig" frameborder="0" allowfullscreen></iframe><div
id="tentblogger-vimeo-youtube-message" style="width: 100%; border: 1px solid #e6e6e6; background: #f8f8f4; text-align:center; padding: 0.25em; ">Can't see the video in your RSS reader or email? <a
target="_blank" href="http://qualitycoding.org/mvc-tdd/">Click Here!</a></div></p><p>The <a
href="http://qualitycoding.org/uiviewcontroller-tdd/">UIViewController TDD screencast</a> ended with all the code in the view controller. Unfortunately, this is where many iOS programmers leave things! In part 2, we pick up from there and TDD to extract a model class, which the controller observes. You&#8217;ll see it evolve into true Model-View-Controller, driven by unit tests.</p><p>In particular, you&#8217;ll see how to TDD:</p><ul><li>a model that posts notifications when it changes, and</li><li>a controller that observes those notifications.</li></ul><p>Questions? <span
id="more-1258"></span></p><p>Links:</p><ul><li><span
style="line-height: 13px;">My review of Graham Lee&#8217;s book <a
href="http://qualitycoding.org/test-driven-ios-development-book/">Test-Driven iOS Development</a></span></li><li><a
href="http://whyappcodeisnice.com" target="_blank">Why AppCode is Nice</a></li><li><a
href="http://osherove.com/blog/2010/1/6/tdd-4-questions-that-will-help-you-create-the-simplest-thing.html" target="_blank">TDD: 4 questions that will help you create the simplest thing that could possibly work</a> by Roy Osherove</li></ul><p
class="attribute">&#8220;Do it now&#8221; sound by <a
href="http://www.freesound.org/people/ERH/sounds/30623/" target="_blank">freesound</a></p><p><hr
/><p>You just finished reading "<a
href="http://qualitycoding.org/mvc-tdd/">iOS Model-View-Controller TDD [Screencast]</a>" on <a
href="http://qualitycoding.org">Quality Coding</a>. I'd love to hear your thoughts about it!</p></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/qualitycoding?a=jAomdnaB4Cc:Z4Y4YkN5DC8:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/qualitycoding?i=jAomdnaB4Cc:Z4Y4YkN5DC8:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=jAomdnaB4Cc:Z4Y4YkN5DC8:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/qualitycoding?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=jAomdnaB4Cc:Z4Y4YkN5DC8:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/qualitycoding?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=jAomdnaB4Cc:Z4Y4YkN5DC8:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/qualitycoding?i=jAomdnaB4Cc:Z4Y4YkN5DC8:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/qualitycoding/~4/jAomdnaB4Cc" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://qualitycoding.org/mvc-tdd/feed/</wfw:commentRss> <slash:comments>40</slash:comments> <feedburner:origLink>http://qualitycoding.org/mvc-tdd/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=mvc-tdd</feedburner:origLink></item> <item><title>Is TDD Worth It? A Testimonial</title><link>http://feedproxy.google.com/~r/qualitycoding/~3/M7E5SCIhiF4/</link> <comments>http://qualitycoding.org/tdd-testimonial/#comments</comments> <pubDate>Mon, 18 Feb 2013 20:05:08 +0000</pubDate> <dc:creator>Jon Reid</dc:creator> <category><![CDATA[TDD]]></category> <guid isPermaLink="false">http://qualitycoding.org/?p=1235</guid> <description><![CDATA[<p>Is TDD worth the effort? Andy Dwelly tried applying my TDD screencasts to his iOS coding. Here&#8217;s what he writes in Some notes on Test Driven Development: At first progress was almost painfully slow. Yup. It seems like there&#8217;s a lot to learn. The real barrier, I think, is that there is a lot to [...]</p><p><hr
/><p>You just finished reading "<a
href="http://qualitycoding.org/tdd-testimonial/">Is TDD Worth It? A Testimonial</a>" on <a
href="http://qualitycoding.org">Quality Coding</a>. I'd love to hear your thoughts about it!</p></p>]]></description> <content:encoded><![CDATA[<p><img
class="aligncenter size-full wp-image-1248" alt="TDD thank-you note" src="http://qualitycoding.org/jrwp/wp-content/uploads/2013/02/tdd-thank-you.jpg" width="570" height="382" /></p><p>Is TDD worth the effort? Andy Dwelly tried applying my TDD screencasts to his iOS coding. Here&#8217;s what he writes in <a
href="http://onemantwoblogs.wordpress.com/2013/02/17/some-notes-on-test-driven-development/" target="_blank">Some notes on Test Driven Development</a>:</p><blockquote><p>At first progress was almost painfully slow.</p></blockquote><p>Yup. It seems like there&#8217;s a lot to learn. The real barrier, I think, is that there is a lot to unlearn. And so, when you first get started with Test Driven Development, your productivity will take a big hit. This is normal! But if you&#8217;re willing to press through the learning curve, your productivity will increase again — in ways you may not have experienced before… <span
id="more-1235"></span></p><h2>TDD: Immediate Benefits!</h2><blockquote><p>I would normally expect to write the final line and then fire up the debugger to get it to actually work.</p><p>Except that it did just work.</p></blockquote><p>I experience this fairly regularly, even when I TDD a new view controller.</p><blockquote><p>I think at this point, if I’d been asked anything about the issue of code quality I would have claimed that the actual code produced was marginally better. My TDD code certainly handled errors and failures better, but had poorer information hiding and some dependency injection that I would not normally have bothered with.</p><p>Then my tests found a bug that I don’t think I would have spotted until the code hit the field.</p></blockquote><p>Do the math: What is the cost of a fixing a defect vs. preventing a defect? Even though TDD takes more time up-front (when it&#8217;s just the developer&#8217;s time), it reduces time later (when more people are involved). I think there&#8217;s enough evidence out there to make this claim: <strong>Once you make it over the learning curve, your time-to-market will be the same — but with many more benefits!</strong></p><h2>TDD: Limitations?</h2><blockquote><p>I’m still of the view that trying to do a lot of UX tests using TDD is hard.</p></blockquote><p>What Andy hasn&#8217;t experienced yet is the real powerhouse that TDD enables: <a
href="http://qualitycoding.org/refactoring-book/">refactoring</a>. To me, this is the greatest benefit of Test Driven Development. It&#8217;s a shift of emphasis, from &#8220;prevent bugs&#8221; to &#8220;empower change.&#8221; And that&#8217;s why I&#8217;m vigilant about unit testing view controllers, down to the nib connections. Where some people say, &#8220;I don&#8217;t think that last bit is worth the effort,&#8221; my reply is, &#8220;It&#8217;s often not that hard. Why would you turn down the chance to automatically check your code?&#8221;</p><p>So Andy is still early in his iOS TDD journey. He&#8217;s still approaching it with some skepticism. But it didn&#8217;t take long for him to experience some of the benefits! <a
href="http://onemantwoblogs.wordpress.com/2013/02/17/some-notes-on-test-driven-development/" target="_blank">Go read his account</a>.</p><p>Then I&#8217;d like to hear from you: Is TDD worth the effort? What are your questions / concerns / reservations / experiences?</p><p
class="attribute">Photo by <a
href="http://www.flickr.com/photos/rogercarr/3667924285/" target="_blank">Roger Carr</a> (<a
href="http://creativecommons.org/licenses/by-nc-sa/2.0/deed.en" target="_blank">license</a>), adapted by Jon Reid</p><p><hr
/><p>You just finished reading "<a
href="http://qualitycoding.org/tdd-testimonial/">Is TDD Worth It? A Testimonial</a>" on <a
href="http://qualitycoding.org">Quality Coding</a>. I'd love to hear your thoughts about it!</p></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/qualitycoding?a=M7E5SCIhiF4:yUTja7GuZeM:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/qualitycoding?i=M7E5SCIhiF4:yUTja7GuZeM:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=M7E5SCIhiF4:yUTja7GuZeM:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/qualitycoding?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=M7E5SCIhiF4:yUTja7GuZeM:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/qualitycoding?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=M7E5SCIhiF4:yUTja7GuZeM:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/qualitycoding?i=M7E5SCIhiF4:yUTja7GuZeM:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/qualitycoding/~4/M7E5SCIhiF4" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://qualitycoding.org/tdd-testimonial/feed/</wfw:commentRss> <slash:comments>10</slash:comments> <feedburner:origLink>http://qualitycoding.org/tdd-testimonial/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=tdd-testimonial</feedburner:origLink></item> <item><title>Testability vs. Information Hiding</title><link>http://feedproxy.google.com/~r/qualitycoding/~3/qvzwzOcZtgc/</link> <comments>http://qualitycoding.org/testability-vs-hiding/#comments</comments> <pubDate>Mon, 04 Feb 2013 06:22:24 +0000</pubDate> <dc:creator>Jon Reid</dc:creator> <category><![CDATA[Unit Testing]]></category> <guid isPermaLink="false">http://qualitycoding.org/?p=1160</guid> <description><![CDATA[<p>In my UIViewController TDD screencast, I put IBOutlets and IBActions in the header file. This made them accessible to unit tests, but I knew it would raise questions: @qcoding This seems like it complicates the question of whether or not actions and outlets truly belong in the public interface or not. &#8212; Aengus McMillin (@Wizecoder) [...]</p><p><hr
/><p>You just finished reading "<a
href="http://qualitycoding.org/testability-vs-hiding/">Testability vs. Information Hiding</a>" on <a
href="http://qualitycoding.org">Quality Coding</a>. I'd love to hear your thoughts about it!</p></p>]]></description> <content:encoded><![CDATA[<div
id="attachment_1197" class="wp-caption aligncenter" style="width: 342px"><img
class="size-full wp-image-1197" alt="Lock: Sometimes it's OK to unlock for greater testability" src="http://qualitycoding.org/jrwp/wp-content/uploads/2013/02/lock.jpg" width="332" height="450" /><p
class="wp-caption-text">Sometimes it&#8217;s OK to unlock things for greater testability</p></div><p>In my <a
href="http://qualitycoding.org/uiviewcontroller-tdd/">UIViewController TDD screencast</a>, I put IBOutlets and IBActions in the header file. This made them accessible to unit tests, but I knew it would raise questions:</p><blockquote
class="twitter-tweet" width="550"><p>@<a
href="https://twitter.com/qcoding">qcoding</a> This seems like it complicates the question of whether or not actions and outlets truly belong in the public interface or not.</p><p>&mdash; Aengus McMillin (@Wizecoder) <a
href="https://twitter.com/Wizecoder/status/293600584295145472">January 22, 2013</a></p></blockquote><p><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script></p><p>It&#8217;s a fair question. There&#8217;s a tension between information hiding (don&#8217;t reveal things in the interface) and testability (certain things need to be exposed). Exploring that tension leads me to apply the <a
href="http://www.refactoring.com/catalog/extractClass.html" target="_blank">Extract Class</a> refactoring in places I hadn&#8217;t considered before. <span
id="more-1160"></span></p><p>Objective-C classes don&#8217;t have anything that&#8217;s truly private, but it&#8217;s understood that if something isn&#8217;t published in the header file, hands off. As of Xcode 4, you can define outlets and actions in the implementation file, effectively hiding them. More hiding is good. But my screencast example works against it, what gives?</p><p>There is a way to have it both ways, a technique I used to use. I&#8217;ll show you how, then explain why I stopped using it.</p><h2>How to hide (but still access for testability)</h2><p>Let&#8217;s use the TDDCounter example from the screencast, but hide its outlets and actions. The interface shrinks:</p><div
class="codecolorer-container objc default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div
class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span
style="color: #a61390;">@interface</span> CounterViewController <span
style="color: #002200;">:</span> UIViewController<br
/> <span
style="color: #002200;">-</span> <span
style="color: #002200;">&#40;</span><span
style="color: #a61390;">id</span><span
style="color: #002200;">&#41;</span>initWithCounter<span
style="color: #002200;">:</span><span
style="color: #002200;">&#40;</span>Counter <span
style="color: #002200;">*</span><span
style="color: #002200;">&#41;</span>counter;<br
/> <span
style="color: #a61390;">@end</span></div></div><p>The outlets move to a class extension in the .m file:</p><div
class="codecolorer-container objc default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div
class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span
style="color: #a61390;">@interface</span> CounterViewController <span
style="color: #002200;">&#40;</span><span
style="color: #002200;">&#41;</span><br
/> <span
style="color: #a61390;">@property</span> <span
style="color: #002200;">&#40;</span>weak, nonatomic<span
style="color: #002200;">&#41;</span> IBOutlet UILabel <span
style="color: #002200;">*</span>countLabel;<br
/> <span
style="color: #a61390;">@property</span> <span
style="color: #002200;">&#40;</span>weak, nonatomic<span
style="color: #002200;">&#41;</span> IBOutlet UIButton <span
style="color: #002200;">*</span>plusButton;<br
/> <span
style="color: #a61390;">@property</span> <span
style="color: #002200;">&#40;</span>weak, nonatomic<span
style="color: #002200;">&#41;</span> IBOutlet UIButton <span
style="color: #002200;">*</span>minusButton;<br
/> <span
style="color: #a61390;">@end</span></div></div><p>That hides things. How do we re-expose them for the tests? By adding a class extension to CounterViewControllerTest.m:</p><div
class="codecolorer-container objc default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div
class="objc codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span
style="color: #a61390;">@interface</span> CounterViewController <span
style="color: #002200;">&#40;</span>Testing<span
style="color: #002200;">&#41;</span><br
/> <br
/> <span
style="color: #a61390;">@property</span> <span
style="color: #002200;">&#40;</span>weak, nonatomic<span
style="color: #002200;">&#41;</span> IBOutlet UILabel <span
style="color: #002200;">*</span>countLabel;<br
/> <span
style="color: #a61390;">@property</span> <span
style="color: #002200;">&#40;</span>weak, nonatomic<span
style="color: #002200;">&#41;</span> IBOutlet UIButton <span
style="color: #002200;">*</span>plusButton;<br
/> <span
style="color: #a61390;">@property</span> <span
style="color: #002200;">&#40;</span>weak, nonatomic<span
style="color: #002200;">&#41;</span> IBOutlet UIButton <span
style="color: #002200;">*</span>minusButton;<br
/> <br
/> <span
style="color: #002200;">-</span> <span
style="color: #002200;">&#40;</span>IBAction<span
style="color: #002200;">&#41;</span>incrementCount<span
style="color: #002200;">:</span><span
style="color: #002200;">&#40;</span><span
style="color: #a61390;">id</span><span
style="color: #002200;">&#41;</span>sender;<br
/> <span
style="color: #002200;">-</span> <span
style="color: #002200;">&#40;</span>IBAction<span
style="color: #002200;">&#41;</span>decrementCount<span
style="color: #002200;">:</span><span
style="color: #002200;">&#40;</span><span
style="color: #a61390;">id</span><span
style="color: #002200;">&#41;</span>sender;<br
/> <br
/> <span
style="color: #a61390;">@end</span></div></div><p>Tests pass — this is a successful refactoring. …So what&#8217;s the problem?</p><h2>Why I avoid this technique</h2><p>I once used the technique above. And if the thought of relaxing information hiding really bothers you, go for it. …But before you do, let me explain why I avoid it.</p><h3>DRY</h3><p>&#8220;Don&#8217;t Repeat Yourself&#8221; is one reason I&#8217;m no longer comfortable creating a testing category. Those repeated declarations? They make test maintenance a pain. They slow down refactoring, especially renaming.</p><p>Since enabling refactoring is a primary purpose of unit tests, slowing down refactoring is especially counter-productive. For me, it&#8217;s a bigger problem than exposing too much.</p><h3>Encourages testing of privates</h3><p>When I&#8217;ve used categories to make hidden outlets and actions accessible to tests, a curious thing happened: Other properties began sneaking in to join the outlets. Other methods began sneaking in to join the actions. The temptation is strong. Just use the word &#8220;testability&#8221; and it&#8217;s easy to justify!</p><p>With TDD, it&#8217;s sometimes hard to come up with a good test that&#8217;s small enough to achieve in a short time. But before you decide to TDD a hidden method, or verify it through a hidden property, pay attention. <strong>Another class is almost certainly trying to get out.</strong></p><p>With legacy code, however, one adds unit tests after the fact. I may not feel comfortable extracting a class quite yet, because I don&#8217;t yet have the coverage I need for refactoring. So I&#8217;ll take the interim step of exposing certain methods and properties for testing. Their presence in the public interface is a reminder to me of unfinished work. And it&#8217;s easier to identify the class that wants to be extracted once enough previously hidden methods and properties are exposed.</p><h2>OK, but what about outlets and actions?</h2><p>For the most part, exposing IBOutlets and IBActions in the header file is a matter of expedience: testability trumps hiding. It would be easy to leave it at that, shrug, and move on.</p><p>But hold on. What if, as with legacy code, too many outlets and actions in the public interface is a reminder of unfinished work?</p><p>Imagine that the view I show in the screencast is more complex. Let&#8217;s say that it&#8217;s part of purchasing an item, and that the count determines the number of items to put into your shopping cart. So the view will also have item images, description, pricing, etc. Even if we extract the business logic, typical iOS code puts all the views together into one giant view controller.</p><p>Do you see the opportunity to <a
href="http://www.refactoring.com/catalog/extractClass.html" target="_blank">Extract Class</a>? We can pull out <code
class="codecolorer text default"><span
class="text">countLabel</span></code>, <code
class="codecolorer text default"><span
class="text">plusButton</span></code> and <code
class="codecolorer text default"><span
class="text">minusButton</span></code> to a subordinate view controller, separate from the other UI aspects of purchasing an item!</p><p>So when you write unit tests against a view controller (whether test-driven or test-after), don&#8217;t worry about hiding the IBOutlets and IBActions. Testability leads us to expose them, and exposing them may reveal that subsets of views we can group and extract. This is one way testing helps us discover better designs.</p><p
class="attribute">Photo by <a
href="http://www.flickr.com/photos/darwinbell/896429958/" target="_blank">Darwin Bell</a> (<a
href="http://creativecommons.org/licenses/by-nc/2.0/deed.en" target="_blank">license</a>)</p><p><hr
/><p>You just finished reading "<a
href="http://qualitycoding.org/testability-vs-hiding/">Testability vs. Information Hiding</a>" on <a
href="http://qualitycoding.org">Quality Coding</a>. I'd love to hear your thoughts about it!</p></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/qualitycoding?a=qvzwzOcZtgc:aORUIr7D9GI:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/qualitycoding?i=qvzwzOcZtgc:aORUIr7D9GI:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=qvzwzOcZtgc:aORUIr7D9GI:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/qualitycoding?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=qvzwzOcZtgc:aORUIr7D9GI:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/qualitycoding?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=qvzwzOcZtgc:aORUIr7D9GI:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/qualitycoding?i=qvzwzOcZtgc:aORUIr7D9GI:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/qualitycoding/~4/qvzwzOcZtgc" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://qualitycoding.org/testability-vs-hiding/feed/</wfw:commentRss> <slash:comments>10</slash:comments> <feedburner:origLink>http://qualitycoding.org/testability-vs-hiding/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=testability-vs-hiding</feedburner:origLink></item> <item><title>++count vs. count++: Do you know the difference?</title><link>http://feedproxy.google.com/~r/qualitycoding/~3/QK4_EoPax8k/</link> <comments>http://qualitycoding.org/pre-increment/#comments</comments> <pubDate>Tue, 29 Jan 2013 06:09:17 +0000</pubDate> <dc:creator>Jon Reid</dc:creator> <category><![CDATA[Objective-C]]></category> <guid isPermaLink="false">http://qualitycoding.org/?p=1113</guid> <description><![CDATA[<p>In my screencast of UIViewController TDD, I used an example of incrementing a counter and couldn&#8217;t help but give a slight aside: &#8220;We&#8217;ll increment it… ++count, instead of count++, please.&#8221; &#60;rant&#62; I blame Apple for propagating poor incrementing style. Programming with Objective-C starts with the statement, &#8220;[Objective-C is] a superset of the C programming language.&#8221; But [...]</p><p><hr
/><p>You just finished reading "<a
href="http://qualitycoding.org/pre-increment/">++count vs. count++: Do you know the difference?</a>" on <a
href="http://qualitycoding.org">Quality Coding</a>. I'd love to hear your thoughts about it!</p></p>]]></description> <content:encoded><![CDATA[<p><img
class="aligncenter size-full wp-image-1114" alt="WHAT YOU SAY!!" src="http://qualitycoding.org/jrwp/wp-content/uploads/2013/01/what-you-say.png" width="420" height="268" /></p><p>In my <a
href="http://qualitycoding.org/uiviewcontroller-tdd/">screencast of UIViewController TDD</a>, I used an example of incrementing a counter and couldn&#8217;t help but give a slight aside: &#8220;We&#8217;ll increment it… ++count, instead of count++, please.&#8221;</p><p><strong><em>&lt;rant&gt;</em></strong><br
/> I blame Apple for propagating poor incrementing style. <a
href="http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html" target="_blank">Programming with Objective-C</a> starts with the statement, &#8220;[Objective-C is] a superset of the C programming language.&#8221; But every example they give of incrementing a value uses <code
class="codecolorer text default"><span
class="text">someInteger++</span></code>, ignoring the fact that C has two different increment operators!</p><ul><li>Post-increment: <code
class="codecolorer text default"><span
class="text">count++</span></code></li><li>Pre-increment: <code
class="codecolorer text default"><span
class="text">++count</span></code></li></ul><p>The Wikipedia article <a
href="http://en.wikipedia.org/wiki/Increment_and_decrement_operators" target="_blank">Increment and decrement operators</a> gives clear examples of the difference.</p><p>What performance impact will it make? None. The extra code for post-increment semantics is probably optimized away by today&#8217;s compilers. Even if it&#8217;s not, it&#8217;ll still have almost no impact. So what does it matter?</p><p>It matters to the reader. It matters because it shows a lack of familiarity with the language&#8217;s operators, which doesn&#8217;t fill me with confidence in your code. It matters because <a
href="http://qualitycoding.org/objective-c-is-c/">Objective-C Is Still C (Not Java!)</a></p><p>Say what you mean, rather than relying on side-effects.<br
/> <strong><em>&lt;/rant&gt;</em></strong></p><p><hr
/><p>You just finished reading "<a
href="http://qualitycoding.org/pre-increment/">++count vs. count++: Do you know the difference?</a>" on <a
href="http://qualitycoding.org">Quality Coding</a>. I'd love to hear your thoughts about it!</p></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/qualitycoding?a=QK4_EoPax8k:3oooBAICKc0:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/qualitycoding?i=QK4_EoPax8k:3oooBAICKc0:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=QK4_EoPax8k:3oooBAICKc0:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/qualitycoding?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=QK4_EoPax8k:3oooBAICKc0:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/qualitycoding?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=QK4_EoPax8k:3oooBAICKc0:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/qualitycoding?i=QK4_EoPax8k:3oooBAICKc0:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/qualitycoding/~4/QK4_EoPax8k" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://qualitycoding.org/pre-increment/feed/</wfw:commentRss> <slash:comments>18</slash:comments> <feedburner:origLink>http://qualitycoding.org/pre-increment/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=pre-increment</feedburner:origLink></item> <item><title>UIViewController TDD [Screencast]</title><link>http://feedproxy.google.com/~r/qualitycoding/~3/BllSVf4x9Dw/</link> <comments>http://qualitycoding.org/uiviewcontroller-tdd/#comments</comments> <pubDate>Tue, 22 Jan 2013 04:38:20 +0000</pubDate> <dc:creator>Jon Reid</dc:creator> <category><![CDATA[TDD]]></category> <guid isPermaLink="false">http://qualitycoding.org/?p=1069</guid> <description><![CDATA[<p>Can't see the video in your RSS reader or email? Click Here! This screencast focuses on the question I get the most: &#8220;Do you do test-driven development for view controllers?&#8221; It&#8217;s clearly a roadblock for many people. This screencast should remove that roadblock. It also answers the question, &#8220;Is it worth doing?&#8221; I cover: Three [...]</p><p><hr
/><p>You just finished reading "<a
href="http://qualitycoding.org/uiviewcontroller-tdd/">UIViewController TDD [Screencast]</a>" on <a
href="http://qualitycoding.org">Quality Coding</a>. I'd love to hear your thoughts about it!</p></p>]]></description> <content:encoded><![CDATA[<p><iframe
title="YouTube video player" width="570" height="360" src="http://www.youtube.com/embed/NthPd0zbua4" frameborder="0" allowfullscreen></iframe><div
id="tentblogger-vimeo-youtube-message" style="width: 100%; border: 1px solid #e6e6e6; background: #f8f8f4; text-align:center; padding: 0.25em; ">Can't see the video in your RSS reader or email? <a
target="_blank" href="http://qualitycoding.org/uiviewcontroller-tdd/">Click Here!</a></div></p><p>This screencast focuses on the question I get the most: &#8220;Do you do test-driven development for view controllers?&#8221; It&#8217;s clearly a roadblock for many people. This screencast should remove that roadblock.</p><p>It also answers the question, &#8220;Is it worth doing?&#8221;</p><p>I cover:</p><ul><li>Three types of unit test verification</li><li>View controller unit tests: the trick</li><li>TDD demo</li><li>How UIViewController TDD can actually help you code faster</li></ul><p>Any questions? <span
id="more-1069"></span></p><p>…I did mess up something pretty big, and I don&#8217;t mean the nib and coding mistakes, which the unit tests successfully caught. I mean my failure to test the labels of the two buttons. I was so eager to show you how to test button behavior, that I forgot about how important it is to test button labels. So my apologies there, but I thought it was more important to get the information out than to try again.</p><p>Links:</p><ul><li>The first screencast, an <a
href="http://qualitycoding.org/objective-c-tdd/">Intro to Objective-C TDD</a></li><li>My <a
href="http://qualitycoding.org/resources/">Resources page</a>, where you can get OCHamcrest and my test case template</li><li><a
href="http://qualitycoding.org/subscribe/">Subscribe to this blog</a> and I&#8217;ll send you my test code snippets</li><li>Chris Hanson&#8217;s <a
href="http://chanson.livejournal.com/148204.html" target="_blank">original blog post from July 2006</a> describing the trick</li><li>Non-TDD UIViewController demo <a
href="https://github.com/mikeplate/counter-ios" target="_blank">counter-ios</a>, the basis for my example</li></ul><p><strong>See also:</strong> <a
href="http://qualitycoding.org/testability-vs-hiding/">Testability vs. Information Hiding</a>, a follow-up discussion about whether to expose outlets and actions in the interface.</p><p
class="attribute">&#8220;Palette&#8221; photo by <a
href="http://www.flickr.com/photos/brartist/312951348/" target="_blank">petra**</a> (<a
href="http://creativecommons.org/licenses/by-sa/2.0/deed.en" target="_blank">license</a>)</p><p><hr
/><p>You just finished reading "<a
href="http://qualitycoding.org/uiviewcontroller-tdd/">UIViewController TDD [Screencast]</a>" on <a
href="http://qualitycoding.org">Quality Coding</a>. I'd love to hear your thoughts about it!</p></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/qualitycoding?a=BllSVf4x9Dw:GD8ZEvYEvTE:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/qualitycoding?i=BllSVf4x9Dw:GD8ZEvYEvTE:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=BllSVf4x9Dw:GD8ZEvYEvTE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/qualitycoding?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=BllSVf4x9Dw:GD8ZEvYEvTE:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/qualitycoding?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=BllSVf4x9Dw:GD8ZEvYEvTE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/qualitycoding?i=BllSVf4x9Dw:GD8ZEvYEvTE:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/qualitycoding/~4/BllSVf4x9Dw" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://qualitycoding.org/uiviewcontroller-tdd/feed/</wfw:commentRss> <slash:comments>43</slash:comments> <feedburner:origLink>http://qualitycoding.org/uiviewcontroller-tdd/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=uiviewcontroller-tdd</feedburner:origLink></item> <item><title>Intro to Objective-C TDD [Screencast]</title><link>http://feedproxy.google.com/~r/qualitycoding/~3/SasjCOfj5T4/</link> <comments>http://qualitycoding.org/objective-c-tdd/#comments</comments> <pubDate>Sat, 29 Dec 2012 17:57:08 +0000</pubDate> <dc:creator>Jon Reid</dc:creator> <category><![CDATA[TDD]]></category> <guid isPermaLink="false">http://qualitycoding.org/?p=1040</guid> <description><![CDATA[<p>Can't see the video in your RSS reader or email? Click Here! My first screencast! It was sparked by a Stack Overflow question that said, &#8220;All the examples of unit testing I read about seem to be extremely simple and trivial.&#8221; The question asks how to write unit tests for a piece of sample code. [...]</p><p><hr
/><p>You just finished reading "<a
href="http://qualitycoding.org/objective-c-tdd/">Intro to Objective-C TDD [Screencast]</a>" on <a
href="http://qualitycoding.org">Quality Coding</a>. I'd love to hear your thoughts about it!</p></p>]]></description> <content:encoded><![CDATA[<p><iframe
title="YouTube video player" width="570" height="360" src="http://www.youtube.com/embed/WADaMF79Vts" frameborder="0" allowfullscreen></iframe><div
id="tentblogger-vimeo-youtube-message" style="width: 100%; border: 1px solid #e6e6e6; background: #f8f8f4; text-align:center; padding: 0.25em; ">Can't see the video in your RSS reader or email? <a
target="_blank" href="http://qualitycoding.org/objective-c-tdd/">Click Here!</a></div></p><p>My first screencast! It was sparked by a Stack Overflow question that said, &#8220;All the examples of unit testing I read about seem to be extremely simple and trivial.&#8221; The question asks how to write unit tests for a piece of sample code. What&#8217;s interesting about this problem is that it uses NSUserDefaults.</p><p>I cover:</p><ul><li>What to do with an external object (in this case, the NSUserDefaults singleton). Dependency injection to the rescue!</li><li>My basic setup: OCUnit + OCHamcrest + OCMockito (along with my test case template and test code snippets)</li><li>The 3 steps of &#8220;The TDD Waltz&#8221;</li><li>We TDD our way to the desired functionality</li></ul><p>Any questions? I&#8217;d love to hear your experience with this screencast. <span
id="more-1040"></span></p><h5>Links:</h5><ul><li>The <a
href="http://stackoverflow.com/questions/13711911/unit-testing-example-with-ocunit/" target="_blank">Stack Overflow question</a>. My original answer illustrates setter injection, as opposed to the (better) constructor injection of the video.</li><li>My <a
href="http://qualitycoding.org/resources/">Resources page</a>, where you can get OCHamcrest, OCMockito, and my test case template</li><li><a
href="http://qualitycoding.org/subscribe/">Subscribe to this blog</a> and I&#8217;ll send you my test code snippets</li><li><a
href="http://www.jetbrains.com/objc/" target="_blank">AppCode</a>, an alternative IDE with much more automated refactoring than Xcode</li><li><a
href="http://www.cleancoders.com" target="_blank">Clean Coders</a> video series by &#8220;Uncle Bob&#8221; Martin</li></ul><p><strong>See also:</strong> <a
href="http://qualitycoding.org/uiviewcontroller-tdd/">UIViewController TDD [Screencast]</a></p><p><hr
/><p>You just finished reading "<a
href="http://qualitycoding.org/objective-c-tdd/">Intro to Objective-C TDD [Screencast]</a>" on <a
href="http://qualitycoding.org">Quality Coding</a>. I'd love to hear your thoughts about it!</p></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/qualitycoding?a=SasjCOfj5T4:TnNismESicE:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/qualitycoding?i=SasjCOfj5T4:TnNismESicE:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=SasjCOfj5T4:TnNismESicE:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/qualitycoding?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=SasjCOfj5T4:TnNismESicE:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/qualitycoding?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=SasjCOfj5T4:TnNismESicE:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/qualitycoding?i=SasjCOfj5T4:TnNismESicE:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/qualitycoding/~4/SasjCOfj5T4" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://qualitycoding.org/objective-c-tdd/feed/</wfw:commentRss> <slash:comments>42</slash:comments> <feedburner:origLink>http://qualitycoding.org/objective-c-tdd/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=objective-c-tdd</feedburner:origLink></item> <item><title>How to Measure Code Coverage in Xcode</title><link>http://feedproxy.google.com/~r/qualitycoding/~3/9iIUVmiURVA/</link> <comments>http://qualitycoding.org/xcode-code-coverage/#comments</comments> <pubDate>Sun, 02 Dec 2012 06:21:10 +0000</pubDate> <dc:creator>Jon Reid</dc:creator> <category><![CDATA[Unit Testing]]></category> <guid isPermaLink="false">http://qualitycoding.org/?p=1004</guid> <description><![CDATA[<p>One of the first things I do when working on any Xcode project is set up code coverage. If the coverage shows a hole, I know that area is lacking unit tests. (Be careful, the opposite isn&#8217;t true: Just because some code has been touched by unit test execution doesn&#8217;t mean it&#8217;s actually covered. If altering [...]</p><p><hr
/><p>You just finished reading "<a
href="http://qualitycoding.org/xcode-code-coverage/">How to Measure Code Coverage in Xcode</a>" on <a
href="http://qualitycoding.org">Quality Coding</a>. I'd love to hear your thoughts about it!</p></p>]]></description> <content:encoded><![CDATA[<div
id="attachment_1005" class="wp-caption aligncenter" style="width: 348px"><img
class="size-full wp-image-1005  " title="hole" alt="Code coverage hole" src="http://qualitycoding.org/jrwp/wp-content/uploads/2012/12/hole.jpg" width="338" height="450" /><p
class="wp-caption-text">Measure your code coverage to find unit testing holes</p></div><p>One of the first things I do when working on any Xcode project is set up code coverage. If the coverage shows a hole, I know that area is lacking unit tests.</p><p>(Be careful, the opposite isn&#8217;t true: Just because some code has been touched by unit test execution doesn&#8217;t mean it&#8217;s actually covered. If altering the behavior of the code causes a test to fail, then you know it&#8217;s covered.)</p><p>Many people use <a
href="http://code.google.com/p/coverstory/" target="_blank">CoverStory</a>, a a code coverage browser app written by my friend Dave MacLachlan. Others use <a
href="https://software.sandia.gov/trac/fast/wiki/gcovr" target="_blank">gcovr</a> to integrate code coverage into their Jenkins continuous integration. Me, I use <a
href="http://ltp.sourceforge.net/coverage/lcov.php" target="_blank">lcov</a> because it lets me exclude third-party libraries from the measurements before generating an HTML report.<span
id="more-1004"></span></p><p>When a project is built from the command-line with xcodebuild, it places build artifacts into a &#8220;build&#8221; folder, kind of like the old days. But I want to measure coverage of unit tests as I run them from Xcode itself. This complicates things because build artifacts go into some obscure DerivedData subfolder. I solve this by having the build process export some of the project&#8217;s environment variables to a file. I&#8217;ll show you where to get the shell scripts I use to do all this.</p><h2>Download the code coverage tools</h2><p>I have a GitHub repository called <a
href="https://github.com/jonreid/XcodeCoverage" target="_blank">XcodeCoverage</a>. You&#8217;ll probably want to make some per-project changes. So if you use git for your projects, think about how you want to manage your fork &#8211; branch &#8211; submodule workflow.</p><p>Place the XcodeCoverage folder in the same folder as your Xcode project.</p><p>Then <a
href="http://downloads.sourceforge.net/ltp/lcov-1.10.tar.gz" target="_blank">download lcov-1.10</a>. Place the lcov-1.10 folder inside the XcodeCoverage folder.</p><p>Also (if you haven&#8217;t done so already) go to Xcode Preferences, into Downloads, and install Command Line Tools to get Xcode&#8217;s coverage instrumentation.</p><h2>Set up your project</h2><p>First, I assume you&#8217;re using Xcode 4.5. If so, you&#8217;re in luck: It&#8217;s easy. (Code coverage used to be a little more complicated in earlier versions of Xcode, as Claus Broch describes in <a
href="http://www.infinite-loop.dk/blog/2011/12/code-coverage-with-xcode-4-2/" target="_blank">Code Coverage with Xcode 4.2</a> and <a
href="http://www.infinite-loop.dk/blog/2012/02/code-coverage-and-fopen-unix2003-problems/" target="_blank">Code Coverage and fopen$UNIX2003 Problems</a>.)</p><p>The first steps are the same, regardless of what coverage tool you use. Select your project, and go into its Build Settings. (I like to make these changes at the project level so that they&#8217;ll apply to all targets.) Find the &#8220;Generate Test Coverage Files&#8221; setting. Spin down the disclosure triangle to reveal your configurations. Enable this settings for your Debug configuration:</p><p><img
class="aligncenter size-full wp-image-1008" title="test-coverage" alt="Generate Test Coverage Files" src="http://qualitycoding.org/jrwp/wp-content/uploads/2012/12/test-coverage1.png" width="570" height="167" /></p><p>Do the same for the &#8220;Instrument Program Flow&#8221; setting:</p><p><img
class="aligncenter size-full wp-image-1009" title="instrument" alt="Instrument Program Flow" src="http://qualitycoding.org/jrwp/wp-content/uploads/2012/12/instrument.png" width="570" height="167" /></p><p>So far, so good. Now let&#8217;s add the extra step so my scripts can get the project&#8217;s environment variables.</p><p>Select your primary target, and go into its Build Phases. Click &#8220;Add Build Phase&#8221; at the bottom, selecting &#8220;Add Run Script&#8221;. Edit it so it runs XcodeCoverage/exportenv.sh:</p><p><img
class="aligncenter size-full wp-image-1010" title="exportenv" alt="Run Script build phase to export environment variables" src="http://qualitycoding.org/jrwp/wp-content/uploads/2012/12/exportenv.png" width="570" height="342" /></p><p>This last step has tripped up some people. If you use OCUnit — where the the main target is executed with tests injected — <strong>make sure you add the script to your main target (your app or library), not your test target.</strong></p><p>On the other hand, if you use a different testing framework that depends on a separate testing app, then add the script to your test app, not the main target.</p><h2>Run!</h2><p>Now we&#8217;re ready for the good stuff. Run your unit tests.</p><p>Open a Terminal window, and cd to your project&#8217;s XcodeCoverage folder. Once the tests complete, run my <strong>getcov</strong> script:</p><div
class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div
class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">./getcov</div></div><p>Things will fly by. Eventually, a browser window should open. Now you can see your code coverage!</p><h2>Change test code, then re-run</h2><p>We measure code coverage to find the holes in our tests. So now let&#8217;s say you&#8217;ve added some new tests, and want to measure the coverage. As long as you haven&#8217;t changed your production code, the quickest way is to clean out the coverage data and re-measure. To do this, run the <strong>cleancov</strong> script:</p><div
class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div
class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">./cleancov</div></div><p>With the previous results zeroed out, now we can re-run the tests, then do getcov again.</p><h2>Change production code, then re-run</h2><p>Time has passed, and you&#8217;ve made changes to your production code. When you decide to measure code coverage again, you should clear out earlier build artifacts. (Leftovers confuse lcov.)</p><p>To do this, hold down the Option key in Xcode&#8217;s &#8220;Product&#8221; menu. Select &#8220;Clean Build Folder&#8221;.</p><p>Now you&#8217;re ready to re-run the tests, followed by <strong>getcov</strong>.</p><h2>Modify the scripts</h2><p>There are two places in the XcodeCoverage scripts you may want to modify for your project:</p><p>First: In the <strong>envcov.sh</strong> script, <tt>LCOV_INFO</tt> determines the name shown in the report. By default, the name is Coverage.info. But if you want to maintain coverage reports for multiple projects, it would be best to change this name to match the project name.</p><p>Second: If your project uses third-party libraries, you&#8217;ll probably want to exclude them from code coverage measurements. You can do so by editing the <strong>getcov</strong> script and changing the <tt>exclude_data()</tt> function.</p><p>What I do is put all third-party libraries into a folder named ThirdParty. Then I exclude the pattern <tt>"ThirdParty/*"</tt> using lcov&#8217;s <tt>--remove</tt> command.</p><h2>Let me know</h2><p>Let me know how it goes! Do you have any questions, about <a
href="https://github.com/jonreid/XcodeCoverage" target="_blank">XcodeCoverage</a> in particular, or about code coverage in general?</p><p
class="attribute">Photo by <a
href="http://www.flickr.com/photos/salim/4647347782/" target="_blank">Salim Virji</a> (<a
href="http://creativecommons.org/licenses/by-sa/2.0/deed.en" target="_blank">license</a>)</p><p><hr
/><p>You just finished reading "<a
href="http://qualitycoding.org/xcode-code-coverage/">How to Measure Code Coverage in Xcode</a>" on <a
href="http://qualitycoding.org">Quality Coding</a>. I'd love to hear your thoughts about it!</p></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/qualitycoding?a=9iIUVmiURVA:XoNMnJb0NZU:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/qualitycoding?i=9iIUVmiURVA:XoNMnJb0NZU:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=9iIUVmiURVA:XoNMnJb0NZU:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/qualitycoding?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=9iIUVmiURVA:XoNMnJb0NZU:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/qualitycoding?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=9iIUVmiURVA:XoNMnJb0NZU:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/qualitycoding?i=9iIUVmiURVA:XoNMnJb0NZU:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/qualitycoding/~4/9iIUVmiURVA" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://qualitycoding.org/xcode-code-coverage/feed/</wfw:commentRss> <slash:comments>63</slash:comments> <feedburner:origLink>http://qualitycoding.org/xcode-code-coverage/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=xcode-code-coverage</feedburner:origLink></item> <item><title>“Test-Driven iOS Development” Fills a Big Hole</title><link>http://feedproxy.google.com/~r/qualitycoding/~3/Sk1fuXxo_MQ/</link> <comments>http://qualitycoding.org/test-driven-ios-development-book/#comments</comments> <pubDate>Tue, 13 Nov 2012 02:37:12 +0000</pubDate> <dc:creator>Jon Reid</dc:creator> <category><![CDATA[Books]]></category> <guid isPermaLink="false">http://qualitycoding.org/?p=976</guid> <description><![CDATA[<p>Many programmers assume that Test Driven Development doesn&#8217;t work well for iOS development. This ill-founded assumption really comes from a lack of any experience with TDD. But because iOS developers learn most of their chops by referring to other people&#8217;s code, it also comes from a lack of helpful examples.  So I was really glad when [...]</p><p><hr
/><p>You just finished reading "<a
href="http://qualitycoding.org/test-driven-ios-development-book/">&#8220;Test-Driven iOS Development&#8221; Fills a Big Hole</a>" on <a
href="http://qualitycoding.org">Quality Coding</a>. I'd love to hear your thoughts about it!</p></p>]]></description> <content:encoded><![CDATA[<p><a
href="http://www.amazon.com/gp/product/0321774183/ref=as_li_ss_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0321774183&amp;linkCode=as2&amp;tag=qualitycoding-20"><img
class="alignright size-full wp-image-977" title="tdd-ios" src="http://qualitycoding.org/jrwp/wp-content/uploads/2012/11/tdd-ios.jpg" alt="Test-Driven iOS Development" width="200" height="257" /></a>Many programmers assume that Test Driven Development doesn&#8217;t work well for iOS development. This ill-founded assumption really comes from a lack of any experience with TDD. But because iOS developers learn most of their chops by referring to other people&#8217;s code, it also comes from a lack of helpful examples.  So I was really glad when Graham Lee&#8217;s book <a
href="http://www.amazon.com/gp/product/0321774183/ref=as_li_ss_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0321774183&amp;linkCode=as2&amp;tag=qualitycoding-20">Test-Driven iOS Development</a><img
style="border: none !important; margin: 0px !important;" src="http://www.assoc-amazon.com/e/ir?t=qualitycoding-20&amp;l=as2&amp;o=1&amp;a=0321774183" alt="" width="1" height="1" border="0" /> came out. Finally, something I can point others to besides my code!</p><h2>Book overview</h2><p>Chapter 1 starts off with a surprising answer to the question, &#8220;Why write unit tests?&#8221; <strong>Why, to make more money!</strong> It shows how the traditional handoff-to-QA form of testing comes from the waterfall model of development, and how the cost of fixing defects increases with each phase of the waterfall.</p><p>Chapter 2 lays out the principles of Test Driven Development: test first, writing &#8220;Just Barely Good Enough&#8221; code that satisfies the test, and refactoring. But it also describes an important principle from Extreme Programming: &#8220;Ya Ain&#8217;t Gonna Need It,&#8221; or YAGNI. Basically, code only what you need to. This keeps production code simple, and avoids wasting time writing code that won&#8217;t have any effect.</p><p>The book goes on to introduce unit testing by showing how one might write tests without a unit testing framework — the old-fashioned way! Then we get an overview of the more common tools. Finally, we hit the meat of the book: a full example of creating an iOS app using TDD, spanning five chapters.<span
id="more-976"></span></p><h2>My a-ha! moments</h2><p>The big example not only demonstrates TDD, but also shows how the Single Responsibility Principle improves design. I had two big a-ha! moments reading this code:</p><ol><li>All model code I&#8217;ve seen includes code to build that model from XML or JSON data. Graham&#8217;s code demonstrates the power of <strong>separating model construction from representation.</strong> This is a big deal not just for improving cohesion. I&#8217;ve run into a model that assumes it&#8217;s built from XML, only to find a case where it might be built from JSON instead.</li><li>All table code I&#8217;ve seen takes the table data source code and the table delegate code, and lumps it all together with the overall view controller. This is normal even when the view controller isn&#8217;t a UITableViewController. Graham&#8217;s code goes against the flow by <strong>pulling data source and delegate into a separate class.</strong> This allows you to use same view controller for different tables.</li></ol><h2>Where I differ</h2><p>I do want to point out one thing in the book that is incorrect, and another where I disagree.</p><h3>Unit test bundles should link just fine</h3><p>After writing the very first test, there&#8217;s a need to create the <tt>Topic</tt>class. On p.68 it says,</p><blockquote><p>Add a new <tt>NSObject</tt> class called <tt>Topic</tt> to the project. When Xcode asks which targets to add the new file to, check both the app target and the test bundle target. (This is required to work around a problem with unit test bundles: They don&#8217;t link symbols from their host apps correctly.)</p></blockquote><p>That was once true for iOS development with Xcode 3. But with Xcode 4, Apple brought iOS unit testing in line with Mac unit testing: Xcode links the test bundle against the app, and injects it into the running app. <strong>If the test bundle is unable to link, there&#8217;s a problem in the build settings.</strong> Make sure &#8220;Symbols Hidden by Default&#8221; is &#8220;No&#8221; for your app&#8217;s Debug configuration.</p><p><em><strong>Update:</strong> Graham Lee says, &#8220;Sadly, at the time of publication, the linker problem still needed to be worked around.&#8221;</em></p><h3>Is method swizzling worth it?</h3><p>The part where I disagree is the author&#8217;s use of method swizzling. He acknowledges that some may consider method swizzling &#8221;too clever,&#8221; and in my case, that may simply be because I haven&#8217;t used it yet. But let&#8217;s look at the two cases where he felt the need for swizzling.</p><p>First, on p.151, he&#8217;s trying to come up with a way to TDD that <tt>viewDidAppear:</tt> call its superclass. For me though, this feels like overkill because the &#8220;invoke super&#8221; idiom is well-ingrained in iOS developers. In particular, I don&#8217;t want to make testing look overly convoluted to my coworkers, whom I am trying to encourage to write tests. If I need to soften strict TDD to get them to adopt it at all, I&#8217;ll do so.</p><p>Still, I do have to say I&#8217;ve wondered how to enforce &#8220;invoke super&#8221; from a test. For idiomatic methods like <tt>viewDidAppear:</tt> I don&#8217;t think this is a big deal. But I may run into another method where it&#8217;s less obvious, and needs a test to verify it. Then I&#8217;ll know to pull method swizzling out of my toolbox.</p><p>The other case where the book uses method swizzling is on pp.154-156. The swizzling replaces a method normally invoked by a notification with a category method that records the notification. The tests verify that the class is observing a notification. But Michael Feathers&#8217; book <a
href="http://www.amazon.com/gp/product/0131177052/ref=as_li_ss_tl?ie=UTF8&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0131177052&amp;linkCode=as2&amp;tag=qualitycoding-20">Working Effectively with Legacy Code</a><img
style="border: none !important; margin: 0px !important;" src="http://www.assoc-amazon.com/e/ir?t=qualitycoding-20&amp;l=as2&amp;o=1&amp;a=0131177052" alt="" width="1" height="1" border="0" /> shows a different way to replace methods: <strong>Subclass and Override.</strong></p><ul><li>In the test code, create a special subclass that is only for testing. (For a class named Foo, I create a subclass named TestingFoo.)</li><li>Write your test to use the testing subclass.</li><li>Override the method.</li></ul><p>It&#8217;s that easy! And this approach works in any object-oriented language — no swizzling required.</p><p><em><strong>Update:</strong> Since writing this, I got into a situation where I needed to write a unit test for code that is tied to a singleton. Can you guess how I altered the singleton for testing? That&#8217;s right, I copied Graham&#8217;s method swizzling technique straight out of the book! I&#8217;d still consider it an unusual tool to be avoided if possible, but method swizzling is definitely part of my toolkit now.</em></p><p><em><strong>Update 2:</strong> OK, I&#8217;ve had to use Graham&#8217;s technique more than once now. I eat humble pie. As Graham told me in a tweet, &#8220;everyone says that’s a gross hack until the moment it solves their problem <img
src='http://qualitycoding.org/jrwp/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> &#8221;</em></p><h2>Conclusion: Test-Driven iOS Development is worthy</h2><p>The book concludes with an overview of coding principles that emerge from TDD, including:</p><ul><li><strong>Design to Interfaces, Not Implementations.</strong> This is more important for hand-rolled mocks, because it lets you easily substitute fakes. I find it less important when using mock object frameworks like OCMockito, because the generated mock is pretty close to a perfect stand-in. But designing to protocols isn&#8217;t just about substituting fakes; it&#8217;s also an important way to break dependencies between classes.</li><li><strong>Tell, Don&#8217;t Ask.</strong> This is a powerful tool for TDD, with a number of different ways to approach it. I use constructor injection, setter injection, injecting a factory, or factory methods which I subclass-and-override. It all depends, and I sometimes change my mind and switch.</li><li><strong>Prefer a Wide, Shallow Inheritance Hierarchy.</strong> I&#8217;d extend that beyond inheritance, to all dependencies: prefer a wide, shallow dependency graph. Again, protocols make this possible.</li></ul><p>I give <em>Test-Driven iOS Development</em>a big thumbs-up. It fills an important hole in TDD examples, and shows how improved designs emerge from good TDD. Pick up a copy… but don&#8217;t just read it! The act of typing someone else&#8217;s code actually reinforces the concepts in your head. And these are concepts that will serve you well.</p><div
style="text-align: center;"><iframe
style="width: 120px; height: 240px;" src="http://rcm.amazon.com/e/cm?lt1=_blank&amp;bc1=000000&amp;IS2=1&amp;bg1=FFFFFF&amp;fc1=000000&amp;lc1=0000FF&amp;t=qualitycoding-20&amp;o=1&amp;p=8&amp;l=as4&amp;m=amazon&amp;f=ifr&amp;ref=ss_til&amp;asins=0321774183" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" width="320" height="240"></iframe></div><p><hr
/><p>You just finished reading "<a
href="http://qualitycoding.org/test-driven-ios-development-book/">&#8220;Test-Driven iOS Development&#8221; Fills a Big Hole</a>" on <a
href="http://qualitycoding.org">Quality Coding</a>. I'd love to hear your thoughts about it!</p></p><div class="feedflare">
<a href="http://feeds.feedburner.com/~ff/qualitycoding?a=Sk1fuXxo_MQ:BVloou0CMZk:gIN9vFwOqvQ"><img src="http://feeds.feedburner.com/~ff/qualitycoding?i=Sk1fuXxo_MQ:BVloou0CMZk:gIN9vFwOqvQ" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=Sk1fuXxo_MQ:BVloou0CMZk:yIl2AUoC8zA"><img src="http://feeds.feedburner.com/~ff/qualitycoding?d=yIl2AUoC8zA" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=Sk1fuXxo_MQ:BVloou0CMZk:qj6IDK7rITs"><img src="http://feeds.feedburner.com/~ff/qualitycoding?d=qj6IDK7rITs" border="0"></img></a> <a href="http://feeds.feedburner.com/~ff/qualitycoding?a=Sk1fuXxo_MQ:BVloou0CMZk:F7zBnMyn0Lo"><img src="http://feeds.feedburner.com/~ff/qualitycoding?i=Sk1fuXxo_MQ:BVloou0CMZk:F7zBnMyn0Lo" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/qualitycoding/~4/Sk1fuXxo_MQ" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://qualitycoding.org/test-driven-ios-development-book/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://qualitycoding.org/test-driven-ios-development-book/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=test-driven-ios-development-book</feedburner:origLink></item> </channel> </rss><!-- Dynamic page generated in 1.924 seconds. --><!-- Cached page generated by WP-Super-Cache on 2013-05-12 23:34:47 -->
