<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Software Noise</title>
	<atom:link href="http://softnoise.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://softnoise.wordpress.com</link>
	<description>random software development stuff</description>
	<lastBuildDate>Tue, 21 Feb 2012 20:38:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='softnoise.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/9753fa3ab4f2320da051cf8fcb297af1?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Software Noise</title>
		<link>http://softnoise.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://softnoise.wordpress.com/osd.xml" title="Software Noise" />
	<atom:link rel='hub' href='http://softnoise.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Amazon(.de) is completely useless for Software eBooks&#8230;</title>
		<link>http://softnoise.wordpress.com/2011/11/09/amazon-de-is-completely-useless-for-software-ebooks/</link>
		<comments>http://softnoise.wordpress.com/2011/11/09/amazon-de-is-completely-useless-for-software-ebooks/#comments</comments>
		<pubDate>Wed, 09 Nov 2011 21:38:15 +0000</pubDate>
		<dc:creator>hauner</dc:creator>
				<category><![CDATA[ebooks]]></category>

		<guid isPermaLink="false">http://softnoise.wordpress.com/?p=211</guid>
		<description><![CDATA[So, everyone is reading eBooks today. So do I. Interesting is, while I bought most paper books in the past on amazon.de I don&#8217;t by software eBooks on amazon.de. What happend? Not much, the problem is simply that amazon.de just offers kindle/mobi format. Personally, with iBook as my prefered ebook reader, I would like to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=softnoise.wordpress.com&amp;blog=11897628&amp;post=211&amp;subd=softnoise&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>So, everyone is reading eBooks today. So do I.</p>
<p>Interesting is, while I bought most paper books in the past on amazon.de I don&#8217;t by software eBooks on amazon.de.</p>
<p>What happend? Not much, the problem is simply that amazon.de just offers kindle/mobi format. Personally, with iBook as my prefered ebook reader, I would like to get them in pub format. Amazon, pub? ehhhh, no. </p>
<p>Second, I also like to have my software ebooks as pdf because they are easier to read on the desktop machine. At home on the Mac and on Windows at work. Amazon, pdf? ehhhh, no again.</p>
<p>So where possible I buy ebooks directly on the publisher website, Manning, PragProg, O&#8217;Reilly because they offer all three formats for a single buy. You buy the ebook and you get all three formats. <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>That looks like a good deal for me. So why should I buy a software ebook on amazon.de? For me, there is no reason to do so.</p>
<p>But not all is lost for amazon. <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  For non software ebooks I don&#8217;t care that they are kindle only&#8230; <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>How&#8217;s your experience?</p>
<br /> Tagged: <a href='http://softnoise.wordpress.com/tag/ebooks/'>ebooks</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/softnoise.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/softnoise.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/softnoise.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/softnoise.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/softnoise.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/softnoise.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/softnoise.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/softnoise.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/softnoise.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/softnoise.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/softnoise.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/softnoise.wordpress.com/211/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/softnoise.wordpress.com/211/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/softnoise.wordpress.com/211/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=softnoise.wordpress.com&amp;blog=11897628&amp;post=211&amp;subd=softnoise&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://softnoise.wordpress.com/2011/11/09/amazon-de-is-completely-useless-for-software-ebooks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b8275cd51c46ecd441233ec6ddd7b7db?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">hauner</media:title>
		</media:content>
	</item>
		<item>
		<title>iOS: Test Driving Objective-C Retain &amp; Release, Revisited</title>
		<link>http://softnoise.wordpress.com/2011/04/30/ios-test-driving-objective-c-retain-release-revisited/</link>
		<comments>http://softnoise.wordpress.com/2011/04/30/ios-test-driving-objective-c-retain-release-revisited/#comments</comments>
		<pubDate>Sat, 30 Apr 2011 09:59:58 +0000</pubDate>
		<dc:creator>hauner</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[obj-c]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://softnoise.wordpress.com/?p=200</guid>
		<description><![CDATA[Michael found a few problems in the code I presented in iOS: Test Driving Objective-C Retain &#38; Release. Obviously he tried to use it Based upon his comments I have revisited the code as you can see it below. First issue is, that the RetainReleaseMock will simply crash when the verify complains. RetainReleaseMock is no [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=softnoise.wordpress.com&amp;blog=11897628&amp;post=200&amp;subd=softnoise&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://softnoise.wordpress.com/2011/03/20/ios-test-driving-retain-release/#comment-94">Michael</a> found a few problems in the code I presented in <a title="test driving retain &amp; release" href="http://softnoise.wordpress.com/2011/03/20/ios-test-driving-retain-release/">iOS: Test Driving Objective-C Retain &amp; Release</a>.</p>
<p style="text-align:justify;">Obviously he tried to use it <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p style="text-align:justify;">Based upon his comments I have revisited the code as you can see it below.</p>
<p style="text-align:justify;">First issue is, that the <code>RetainReleaseMock</code> will simply crash when the <code>verify</code> complains. <code>RetainReleaseMock</code> is no test case and so it is missing the method used to report an issue.</p>
<p style="text-align:justify;">Next issue is, that it doesn&#8217;t provide very useful messages. You don&#8217;t see if it is complaining about the retain or the release count.</p>
<p style="text-align:justify;">To fix the first issue, Michael moved the assertions back to the test method. Although this is a bit longer than the simple verify, it fixes the first issue and second issue in one step.</p>
<p style="text-align:justify;">Ok, I agree, that&#8217;s better so I have revisited my code with some renaming (it is no longer a mock but a spy), a special hamcrest matcher and a noise reducing macro which you may use or not.</p>
<p style="text-align:justify;">Here is the test code (without macro and with macro):</p>
<p><pre class="brush: objc; gutter: false;">
@interface CredentialsTest : GTMTestCase {
}
@end

@implementation CredentialsTest
- (void)testShouldRetainAndReleaseUserAndPassword {
  id user = [[[RetainReleaseSpy alloc] init] autorelease];
  id password = [[[RetainReleaseSpy alloc] init] autorelease];

  [[[Credentials alloc] initWithUser:user password:password] release];

  assertThat (user, isRetained (1));
  assertThat (user, isReleased (1));
  assertThat (password, isRetained (1));
  assertThat (password, isReleased (1));
}

@implementation CredentialsTest
- (void)testShouldRetainAndReleaseUserAndPassword {
  id user = RRSpy;
  id password = RRSpy;

  [[[Credentials alloc] initWithUser:user password:password] release];

  assertThat (user, isRetained (1));
  assertThat (user, isReleased (1));
  assertThat (password, isRetained (1));
  assertThat (password, isReleased (1));
}

@end
</pre></p>
<p style="text-align:justify;">In this case I intentionally put everything in a single test and violate the &#8220;single assertion (concept) per test&#8221; rule. It has everything in one spot and I think I can handle &#8220;hidden assertion&#8221; issue (I wont see the failures of the later assertions when the first fails). <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />
</p>
<p style="text-align:justify;">Assertion failures are reported like this:</p>
<p style="text-align:justify;"><code>-[CredentialsTest testShouldRetainAndReleaseUserAndPassword] : Expected release count 1, but was 0</code></p>
<p style="text-align:justify;">The <code>isRetained</code> and <code>isReleased</code> calls are creating hamcrest matchers to make it a little bit easier to read.</p>
<p style="text-align:justify;">Here is the code of the new <code>RetainReleaseSpy</code>, the matcher code (header and implementation) and the matcher factory methods:</p>
<p><pre class="brush: objc; gutter: false;">
// ios
#import &lt;Foundation/Foundation.h&gt;

// test
#import &lt;OCHamcrest/HCBaseMatcher.h&gt;

@interface RetainReleaseSpy : NSObject {
  int refCount;
}

@property (nonatomic, readonly) int actualRetainCount;
@property (nonatomic, readonly) int actualReleaseCount;

- (id)init;
- (id)retain;
- (void)release;

@end


id&lt;HCMatcher&gt; isRetained (int expectedRetainCount);
id&lt;HCMatcher&gt; isReleased (int expectedReleaseCount);

#define RRSpy [[[RetainReleaseMock alloc] init] autorelease]
</pre></p>
<p><pre class="brush: objc; gutter: false;">
#import &quot;RetainReleaseSpy.h&quot;

// test
#import &lt;OCHamcrest/OCHamcrest.h&gt;
#import &lt;OCHamcrest/HCDescription.h&gt;


@implementation RetainReleaseSpy

@synthesize actualRetainCount;
@synthesize actualReleaseCount;

- (id)init {
  if ((self = [super init])) {
    actualRetainCount = 0;
    actualReleaseCount = 0;
    refCount = 1;
  }
  return self;  
}

- (id)retain {
  ++refCount;
  ++actualRetainCount;
  return self;
}

- (void)release {
  ++actualReleaseCount;
  --refCount;
  
  if (refCount == 0) {
    [self dealloc];
  }
}

@end


@interface RetainReleaseMatcher : HCBaseMatcher {
  int expectedCount;

  SEL property;
  NSString* info;
}

- (id) initWithExpectedCount:(int)expectedCount property:(SEL)property info:(NSString*)info;

@end


@implementation RetainReleaseMatcher

- (id) initWithExpectedCount:(int)anExpectedCount property:(SEL)aProperty info:(NSString*)anInfo {
  if ((self = [super init])) {
    expectedCount = anExpectedCount;
    property = aProperty;
    info = [anInfo retain];
  }
  return self;
}

- (BOOL) matches:(id)item {
  int actualCount = (int)[item performSelector:property];
  if (actualCount != expectedCount) {
    return NO;
  }
  return YES;
}

- (void) describeTo:(id&lt;HCDescription&gt;)description {
  [description appendText:[NSString stringWithFormat:@&quot;%@ count %d&quot;, info, expectedCount]];
}

- (void) describeMismatchOf:(id)item to:(id&lt;HCDescription&gt;)mismatchDescription {
  int actualCount = (int)[item performSelector:property];
  [mismatchDescription appendText:[NSString stringWithFormat:@&quot;was %d&quot;, actualCount]];
}

- (void)dealloc {
  [info release];
  [super dealloc];
}   

@end


id&lt;HCMatcher&gt; isRetained (int expectedRetainCount)
{
  return [[[RetainReleaseMatcher alloc] initWithExpectedCount:expectedRetainCount
    property:@selector(actualRetainCount) info:@&quot;retain&quot;] autorelease];
}

id&lt;HCMatcher&gt; isReleased (int expectedReleaseCount)
{
  return [[[RetainReleaseMatcher alloc] initWithExpectedCount:expectedReleaseCount
    property:@selector(actualReleaseCount) info:@&quot;release&quot;] autorelease];
}
</pre></p>
<p>Better than before? I think so.</p>
<br /> Tagged: <a href='http://softnoise.wordpress.com/tag/ios/'>ios</a>, <a href='http://softnoise.wordpress.com/tag/memory/'>memory</a>, <a href='http://softnoise.wordpress.com/tag/obj-c/'>obj-c</a>, <a href='http://softnoise.wordpress.com/tag/test/'>test</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/softnoise.wordpress.com/200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/softnoise.wordpress.com/200/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/softnoise.wordpress.com/200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/softnoise.wordpress.com/200/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/softnoise.wordpress.com/200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/softnoise.wordpress.com/200/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/softnoise.wordpress.com/200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/softnoise.wordpress.com/200/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/softnoise.wordpress.com/200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/softnoise.wordpress.com/200/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/softnoise.wordpress.com/200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/softnoise.wordpress.com/200/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/softnoise.wordpress.com/200/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/softnoise.wordpress.com/200/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=softnoise.wordpress.com&amp;blog=11897628&amp;post=200&amp;subd=softnoise&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://softnoise.wordpress.com/2011/04/30/ios-test-driving-objective-c-retain-release-revisited/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b8275cd51c46ecd441233ec6ddd7b7db?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">hauner</media:title>
		</media:content>
	</item>
		<item>
		<title>First Impression of appCode, JetBrains Objective-C IDE</title>
		<link>http://softnoise.wordpress.com/2011/04/07/first-impression-of-appcode-jetbrains-objective-c-ide/</link>
		<comments>http://softnoise.wordpress.com/2011/04/07/first-impression-of-appcode-jetbrains-objective-c-ide/#comments</comments>
		<pubDate>Thu, 07 Apr 2011 21:43:17 +0000</pubDate>
		<dc:creator>hauner</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[appCode]]></category>
		<category><![CDATA[idea]]></category>
		<category><![CDATA[JetBrains]]></category>
		<category><![CDATA[obj-c]]></category>

		<guid isPermaLink="false">http://softnoise.wordpress.com/?p=191</guid>
		<description><![CDATA[JetBrains just released their first EAP version of a new IDE for Objective-C. Objective-C ???? Yes, no joke. The JetBrains page says: &#8220;appCode is a new IDE based on IntelliJ platform, for developers building apps for Apple devices such as Macs, iPhones &#38; iPads.&#8221; I don&#8217;t do daily programming in Java but If I do [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=softnoise.wordpress.com&amp;blog=11897628&amp;post=191&amp;subd=softnoise&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.jetbrains.com">JetBrains</a> just released their first <a href="http://www.jetbrains.com/objc/index.html">EAP version of a new IDE for Objective-C</a>.</p>
<p>Objective-C ???? Yes, no joke. <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>The JetBrains page says:</p>
<p><em>&#8220;<strong>appCode</strong> is a new IDE based on IntelliJ platform, for developers building apps for Apple devices such as Macs, iPhones &amp; iPads.&#8221;</em></p>
<p style="text-align:justify;">I don&#8217;t do daily programming in Java but If I do java programming I use <a href="http://www.jetbrains.com/idea/">IntelliJ IDEA</a>. At work with the commercial version and at home with the community edition.</p>
<p>My free time interest right know is iOS development and I have written a couple of articles about <a href="http://softnoise.wordpress.com/tag/ios/">iOS</a> stuff on my blog. So I was quite curious to take look at <strong>appCode</strong>.</p>
<p>I <a href="http://www.jetbrains.com/objc/index.html">downloaded</a> the archive and started to play around with it.</p>
<p>Here are a couple of things I tried:</p>
<p style="text-align:justify;">Loading an Xcode project did work without problem.</p>
<p style="text-align:justify;">Building and running my app did work out of the box. The only thing was that I had to specifically set the device to iPad. It didn&#8217;t pick that up by itself.</p>
<p style="text-align:justify;">Using the typical IDEA run/debug configuration dialog I was also able to configure and run my <a href="http://code.google.com/p/google-toolbox-for-mac/">GTM</a> unit tests. appCode recognizes all the targets from the Xcode project and you can modify the SDK, device and so on.</p>
<p style="text-align:justify;"><strong>appCode</strong> doesn&#8217;t seem handle the test results so far. It complained about 65 errors although only 2 failed. Not sure where it got that number from. The failing tests are not appCodes fault. Double clicking the error also didn&#8217;t jump to the source.</p>
<p style="text-align:justify;">Debugging works too. I was able to set breakpoints and step through the code. [<strong>Update: 11.04.</strong>] <del>A bit strange is that it didn&#8217;t honor breakpoints in all methods.</del> <em>I&#8217;m unable to reproduce the breakpoints that did not work. I retried multiple times and now it just works. I don&#8217;t know what made me believe it did not stop on all breakpoints. </em></p>
<p style="text-align:justify;">The editor itself works great. You are directly at home if you know IntelliJ IDEA. It offers a similar feature set:</p>
<p style="text-align:justify;">IDEAs common navigation shortcuts, auto completion, inspections, live templates and so on.</p>
<p style="text-align:justify;">At the left of the editor you have small icons that tell you that a method overwrites a base class method and clicking it will jump to its declaration. appCode also marks methods with a small pair of arrows icon to jump from declaration to definition and the other way.</p>
<p style="text-align:justify;"><strong>Auto completion</strong> works really good. I&#8217;ve just used it a short time but it looks like it provides better suggestions (less noise) than Xcode.</p>
<p style="text-align:justify;"><strong>Inspections</strong>. It&#8217;s recognizing unused #imports and variables and creates the IDEA typical yellow lines in the editor scroll bar.</p>
<p style="text-align:justify;"><strong>Live Templates</strong> work too. For example typing <em>alloc&lt;tab&gt;</em> will result in <em>[[ alloc] init]</em> with the cursor before the alloc.</p>
<p style="text-align:justify;">It also comes with a number of <strong>refactorings</strong>. I tried rename and extract method without problems.</p>
<p style="text-align:justify;">appCode did open a xib file as xml. It didn&#8217;t run Interface Builder. Not sure if it is even possible to run Interface Builder now that it is built into Xcode 4.</p>
<p style="text-align:justify;">It also had some problem to find all the #imported files and complained about undefined symbols (in the editor, building works, I guess it simply runs xcodebuild).</p>
<p style="text-align:justify;">I have created a couple of different source folders in my project to organize the sources. In Xcode I have set a couple of additional #import folders and #import header files relative to them.</p>
<p style="text-align:justify;">appCode didn&#8217;t pick up the additional #import folders. You can tell appCode about the source root folder and test source root folder but that did not completely fix this issue. I have three parallel source folders: &#8220;Source&#8221;, &#8220;Source Test&#8221; and &#8220;Source External&#8221; and the external folder contains the <a href="http://code.google.com/p/google-toolbox-for-mac/">GTM</a>, <a href="http://www.mulle-kybernetik.com/software/OCMock/">OCMock</a> and <a href="http://code.google.com/p/hamcrest/wiki/TutorialObjectiveC">OCHamcrest</a> code which appCode did not find.</p>
<p style="text-align:justify;">My first impression (after maybe an hour and a half) is quite good. I think I will spend some more time working with it and see how it feels when doing some real work.</p>
<p style="text-align:justify;">What&#8217;s your opinion on <strong>appCode</strong>?</p>
<p style="text-align:justify;">&nbsp;</p>
<p><em><br />
</em></p>
<br /> Tagged: <a href='http://softnoise.wordpress.com/tag/appcode/'>appCode</a>, <a href='http://softnoise.wordpress.com/tag/idea/'>idea</a>, <a href='http://softnoise.wordpress.com/tag/jetbrains/'>JetBrains</a>, <a href='http://softnoise.wordpress.com/tag/obj-c/'>obj-c</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/softnoise.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/softnoise.wordpress.com/191/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/softnoise.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/softnoise.wordpress.com/191/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/softnoise.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/softnoise.wordpress.com/191/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/softnoise.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/softnoise.wordpress.com/191/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/softnoise.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/softnoise.wordpress.com/191/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/softnoise.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/softnoise.wordpress.com/191/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/softnoise.wordpress.com/191/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/softnoise.wordpress.com/191/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=softnoise.wordpress.com&amp;blog=11897628&amp;post=191&amp;subd=softnoise&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://softnoise.wordpress.com/2011/04/07/first-impression-of-appcode-jetbrains-objective-c-ide/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b8275cd51c46ecd441233ec6ddd7b7db?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">hauner</media:title>
		</media:content>
	</item>
		<item>
		<title>iOS: Test Driving Objective-C Retain &amp; Release</title>
		<link>http://softnoise.wordpress.com/2011/03/20/ios-test-driving-retain-release/</link>
		<comments>http://softnoise.wordpress.com/2011/03/20/ios-test-driving-retain-release/#comments</comments>
		<pubDate>Sun, 20 Mar 2011 12:10:48 +0000</pubDate>
		<dc:creator>hauner</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[obj-c]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://softnoise.wordpress.com/?p=181</guid>
		<description><![CDATA[Does it make sense to write unit test for retain &#38; release for my classes? If I strictly follow Uncle Bob&#8217;s TDD Rules then yes. I have to write some test code that will make me add the retain &#38; release cycle for an object. Even if I don&#8217;t strictly follow the rules it may [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=softnoise.wordpress.com&amp;blog=11897628&amp;post=181&amp;subd=softnoise&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Does it make sense to write unit test for <code>retain</code> &amp; <code>release</code> for my classes?</p>
<p style="text-align:justify;">If I strictly follow <a title="tdd rules" href="http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd">Uncle Bob&#8217;s TDD Rules</a> then yes. I have to write some test code that will make me add the <code>retain</code> &amp; <code>release</code> cycle for an object.</p>
<p style="text-align:justify;">Even if I don&#8217;t strictly follow the rules it may make sense&#8230; at least it is a reminder to add the <code>release</code>. Which I forget from time to time.</p>
<p>But finally it is your decision if you test it or not. Anyway, I&#8217;d like to talk about <strong>how</strong> would I do it?</p>
<p style="text-align:justify;">First I tried to achieve it with <a title="mocking for objective-c" href="http://www.mulle-kybernetik.com/software/OCMock/">OCMock</a> but that did not work at all. Fiddling with retain and release on objects out of your control is, let&#8217;s say, one on the easiest way to make your test code crash <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p style="text-align:justify;">So I created a hand made mock called <code>RetainReleaseMock</code> that tracks the <code>retain</code> &amp; <code>release</code> calls.</p>
<p style="text-align:justify;">Here is a test that demonstrates how I use it. It tests that my <code>Credentials</code> object properly <code>retains</code> &amp; <code>releases</code> the user and password <code>NSString</code>s passed to the <code>initWithUser:password:</code> method.</p>
<p><pre class="brush: objc; gutter: false;">
@interface CredentialsTest : GTMTestCase {
}
@end

@implementation CredentialsTest

- (void)testShouldRetainAndReleaseUserAndPassword {
 id user = [[[RetainReleaseMock alloc] init] autorelease];
 id password = [[[RetainReleaseMock alloc] init] autorelease];

 [[[Credentials alloc] initWithUser:user password:password] release];

 [user verify];
 [password verify];
}

@end
</pre></p>
<p style="text-align:justify;">First I create a <code>RetainReleaseMock</code> for the user and password string. Then I create the <code>Credentials</code> object (passing the two mocks) to trigger the <code>retain</code> and directly release it again to trigger the <code>release</code>.</p>
<p style="text-align:justify;">The final step is to verify that <code>retain</code> and <code>release</code> was called on each mock.</p>
<p style="text-align:justify;">That&#8217;s it.</p>
<p style="text-align:justify;">Note that you can use <code>[autorelease]</code> to get the mock properly deallocated.</p>
<p style="text-align:justify;">Here is the code of the RetainReleaseMock:</p>
<p><pre class="brush: objc; gutter: false;">
// ios
#import &lt;Foundation/Foundation.h&gt;

@interface RetainReleaseMock : NSObject {
  int refCount;

  int expectedRetainCount;
  int expectedReleaseCount;
  int actualRetainCount;
  int actualReleaseCount;
}

- (id)init;
- (id)initWithRetain:(int)retainCount release:(int)releaseCount;

- (id)retain;
- (void)release;
- (void)verify;

@end

#import &quot;RetainReleaseMock.h&quot;

// test
#import &lt;OCHamcrest/OCHamcrest.h&gt;

@implementation RetainReleaseMock

- (id)init {
  return [self initWithRetain:1 release:1];
}

- (id)initWithRetain:(int)retainCount release:(int)releaseCount {
  if ((self = [super init])) {
    expectedRetainCount = retainCount;
    expectedReleaseCount = releaseCount;
    actualRetainCount = 0;
    actualReleaseCount = 0;
    refCount = 1;
  }
  return self;
}

- (id)retain {
  ++refCount;
  ++actualRetainCount;
  return self;
}

- (void)release {
  ++actualReleaseCount;
  --refCount;

  if (refCount == 0) {
    [self dealloc];
  }
}

- (void)verify {
  assertThatInt (actualRetainCount, equalToInt (expectedRetainCount));
  assertThatInt (actualReleaseCount, equalToInt (expectedReleaseCount));
}

@end
</pre></p>
<p style="text-align:justify;">In case you wonder what the second init method is for:</p>
<p style="text-align:justify;">I have added it to test <code>retain</code> &amp; <code>release</code> on an <code>AppDelegate</code> where I cannot pass the dependencies directly to the <code>AppDelegate</code> (.. because it is created by &#8220;iOS&#8221;). The <code>AppDelegate</code> calls a (global) factory object that I have stubbed (with OCMock) to return the <code>RetainReleaseMock</code>. The factory stub retains my mock too so I have to adjust the expected retain count.</p>
<p>The test then looks like this:</p>
<p><pre class="brush: objc; gutter: false;">
- (void)testReleasesCoreData {
  // extra retain from appFactory stub.
  id coredata = [[[RetainReleaseMock alloc] initWithRetain:2 release:1] autorelease];

  id appFactory = Stub (AppFactory);
  [[[appFactory stub] andReturn:controller] mainViewController];
  [AppFactory setFactory:appFactory];

  [delegate application:nil didFinishLaunchingWithOptions:nil];
  [delegate release];

  [coredata verify];
  [ReadmeAppFactory reset];
}
</pre></p>
<p style="text-align:justify;">If you have a better suggestion to handle this situation, I would like to hear it. <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<br /> Tagged: <a href='http://softnoise.wordpress.com/tag/ios/'>ios</a>, <a href='http://softnoise.wordpress.com/tag/memory/'>memory</a>, <a href='http://softnoise.wordpress.com/tag/obj-c/'>obj-c</a>, <a href='http://softnoise.wordpress.com/tag/test/'>test</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/softnoise.wordpress.com/181/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/softnoise.wordpress.com/181/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/softnoise.wordpress.com/181/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/softnoise.wordpress.com/181/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/softnoise.wordpress.com/181/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/softnoise.wordpress.com/181/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/softnoise.wordpress.com/181/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/softnoise.wordpress.com/181/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/softnoise.wordpress.com/181/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/softnoise.wordpress.com/181/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/softnoise.wordpress.com/181/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/softnoise.wordpress.com/181/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/softnoise.wordpress.com/181/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/softnoise.wordpress.com/181/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=softnoise.wordpress.com&amp;blog=11897628&amp;post=181&amp;subd=softnoise&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://softnoise.wordpress.com/2011/03/20/ios-test-driving-retain-release/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b8275cd51c46ecd441233ec6ddd7b7db?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">hauner</media:title>
		</media:content>
	</item>
		<item>
		<title>iOS: Setting Up Advanced Unit Testing &#8211; Take Two</title>
		<link>http://softnoise.wordpress.com/2011/02/20/ios-setting-up-advanced-unit-testing-take-two/</link>
		<comments>http://softnoise.wordpress.com/2011/02/20/ios-setting-up-advanced-unit-testing-take-two/#comments</comments>
		<pubDate>Sun, 20 Feb 2011 16:20:22 +0000</pubDate>
		<dc:creator>hauner</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[ochamcrest]]></category>
		<category><![CDATA[ocmock]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://softnoise.wordpress.com/?p=155</guid>
		<description><![CDATA[As Jon Reid mentioned on my &#8220;Setting Up Advanced Unit Testing&#8221; article on iOS testing, OCHamcrest now has  better support for iOS. It creates an OCHamcrest framework for IOS that includes the patches needed for iOS. I can now simply add the framework to my project and add a few additional linker options (which are [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=softnoise.wordpress.com&amp;blog=11897628&amp;post=155&amp;subd=softnoise&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify;">As Jon Reid <a title="ochamcrest with better iOS support" href="http://softnoise.wordpress.com/2010/11/14/ios-setting-up-advanced-unit-testing/#comment-34">mentioned</a> on my <a title="setup ochamcrest &amp; ocmock" href="http://softnoise.wordpress.com/2010/11/14/ios-setting-up-advanced-unit-testing/">&#8220;Setting Up Advanced Unit Testing&#8221;</a> article on iOS testing, <strong><a title="declarative test asserts" href="http://code.google.com/p/hamcrest/wiki/TutorialObjectiveC">OCHamcrest</a></strong> now has  better support for iOS. It creates an OCHamcrest framework for IOS that includes the patches needed for iOS. I can now simply add the framework to my project and add a few additional linker options (which are the same as for <strong> </strong><strong><a title="Objective-C Mock/Stub framework" href="http://www.mulle-kybernetik.com/software/OCMock/"><strong>OCMock</strong></a></strong>) to make it work.</p>
<p style="text-align:justify;">This should makes it a bit easier to setup hamcrest on iOS. Unfortunately there is a new complication. For iOS I now have to use</p>
<p><pre class="brush: plain;">
#import &lt;OCHamcrestIOS/OCHamcrestIOS.h&gt;
</pre></p>
<p>instead of</p>
<p><pre class="brush: plain;">
#import &lt;OCHamcrest/OCHamcrest.h&gt;
</pre></p>
<p style="text-align:justify;">I don&#8217;t like that. I don&#8217;t see why it has to use a different name.</p>
<p style="text-align:justify;">My solution is to build my own static lib for OCHamcrest. That is quite easy and it is my recommended solution.</p>
<p style="text-align:justify;">Initially I switched OCMock to a static library because I had some issue compiling OCMock with block support. It didn&#8217;t pick up the proper iOS version and I always ended up with a lib missing block support. So finally I copied all the OCMock source files to my project and created a static library.</p>
<p style="text-align:justify;">The OCMock source now live inside my project in a folder called <strong>&#8220;Source Xternal/OCMock&#8221;</strong>. To create a static lib I added a new &#8220;static library&#8221; target to my project (in XCode, right click <em>Targets</em> and <em>Add/New Target</em> and then select static library) with the OCMock source files below &#8220;Source Xternal/OCMock&#8221;.  Next I added the new lib (<strong>libOCMock.a</strong>) to my unit test project by adding it to the <strong>&#8220;Linked Libraries&#8221;</strong> (<em>Get Info/Linked Libraries </em>on the unit test target). The last step was to add <strong>&#8220;Source Xternal&#8221;</strong> to the <strong>&#8220;Header Search Paths&#8221;</strong> in the build settings.</p>
<p style="text-align:justify;">Since the source folder is named OCMock the usual <em>#import</em> will work without change, i.e.</p>
<p><pre class="brush: plain;">
#import &lt;OCMock/OCMock.h&gt;
</pre></p>
<p style="text-align:justify;">I didn&#8217;t need to modify any <em>#import</em> statement. (Now it also picks up the proper settings to compile it with block support <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ).</p>
<p style="text-align:justify;">I did the same with OCHamcrest. The only difference to the procedure used for OCMock was that I flattened the sources of OCHamcrest into a single folder <strong>&#8220;Source Xternal/OCHamcrest&#8221;</strong>. Now all header files are below OCHamcrest and I do not have to touch the hamcrest <em>#imports</em>. (The original source layout uses subfolder to group the files).</p>
<p style="text-align:justify;">This also removed the unwanted &#8220;<em>IOS</em>&#8221; postfix. So I can simply use the common <em>#import &lt;OCHamcrest/OCHamcrest.h&gt;</em>.</p>
<p style="text-align:justify;">Finally I also moved Google Toolbox for Mac stuff to my <strong>&#8220;Source Xternal&#8221;</strong> folder into <strong>&#8220;Source Xternal/GoogleToolbox&#8221;</strong> and created another static lib for it.</p>
<p style="text-align:justify;">So my source layout now looks like this:</p>
<p><pre class="brush: plain;">
Source
...
Source Test
...
Source Xternal
Source Xternal/OCMock
Source Xternal/OCHamcrest
Source Xternal/GoogleToolbox
</pre></p>
<p style="text-align:justify;">That&#8217;s straight forward and also improves the build on my continuous integration server as it now builds all my dependencies as part of my project with the same compiler settings.</p>
<p style="text-align:justify;">Another nice side effect is, that the source of the libraries is not far away and I can easily look into it. From time to time I get strange error messages when compiling and sometimes it helps to take a look into the source of OCHamcrest.</p>
<p>I&#8217;m already using this layout for a while now and its definitely my recommendation!</p>
<p>Happy Testing!</p>
<br /> Tagged: <a href='http://softnoise.wordpress.com/tag/ios/'>ios</a>, <a href='http://softnoise.wordpress.com/tag/ochamcrest/'>ochamcrest</a>, <a href='http://softnoise.wordpress.com/tag/ocmock/'>ocmock</a>, <a href='http://softnoise.wordpress.com/tag/test/'>test</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/softnoise.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/softnoise.wordpress.com/155/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/softnoise.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/softnoise.wordpress.com/155/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/softnoise.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/softnoise.wordpress.com/155/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/softnoise.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/softnoise.wordpress.com/155/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/softnoise.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/softnoise.wordpress.com/155/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/softnoise.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/softnoise.wordpress.com/155/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/softnoise.wordpress.com/155/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/softnoise.wordpress.com/155/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=softnoise.wordpress.com&amp;blog=11897628&amp;post=155&amp;subd=softnoise&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://softnoise.wordpress.com/2011/02/20/ios-setting-up-advanced-unit-testing-take-two/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b8275cd51c46ecd441233ec6ddd7b7db?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">hauner</media:title>
		</media:content>
	</item>
		<item>
		<title>iOS: Running Cucumber/Frank with Code Coverage in Jenkins/Hudson</title>
		<link>http://softnoise.wordpress.com/2010/11/14/ios-running-cucumberfrank-with-code-coverage-in-hudson/</link>
		<comments>http://softnoise.wordpress.com/2010/11/14/ios-running-cucumberfrank-with-code-coverage-in-hudson/#comments</comments>
		<pubDate>Sun, 14 Nov 2010 16:11:10 +0000</pubDate>
		<dc:creator>hauner</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[frank]]></category>
		<category><![CDATA[hudson]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[jenkins]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://softnoise.wordpress.com/?p=114</guid>
		<description><![CDATA[In the previous article iOS: Setting Up Acceptance Testing I introduced Frank. The next and last step will be to run Cucumber and Frank headless from Jenkins/Hudson. Frank is still new, and it uses apple script to remote control XCode to run the &#8220;frankified&#8221; app in the simulator. That&#8217;s fine for running the cucumber scenarios [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=softnoise.wordpress.com&amp;blog=11897628&amp;post=114&amp;subd=softnoise&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In the previous article <a title="setting up acceptance testing with Cucumber and Frank" href="http://softnoise.wordpress.com/2010/11/14/ios-setting-up-acceptance-testing">iOS: Setting Up Acceptance Testing</a> I introduced <strong><a title="cucumber for iOS" href="http://blog.thepete.net/2010/07/frank-automated-acceptance-tests-for.html">Frank</a></strong>. The next and last step will be to run <strong> </strong><strong><a title="acceptance testing framework" href="http://cukes.info/">Cucumber</a> </strong>and <strong><a title="cucumber for iOS" href="http://blog.thepete.net/2010/07/frank-automated-acceptance-tests-for.html">Frank</a> </strong>headless from <strong><a title="continuous integration server" href="http://jenkins-ci.org/">Jenkins/Hudson</a></strong>.</p>
<p style="text-align:justify;">Frank is still new, and it uses apple script to remote control XCode to run the <em>&#8220;frankified</em>&#8221; app in the simulator. That&#8217;s fine for running the cucumber scenarios manually but it is not so good for running them from Jenkins/Hudson.</p>
<p style="text-align:justify;">To run the cucumber tests from Jenkins/Hudson I need it to run headless, i.e. it should not open any window while running the tests. I don&#8217;t want Jenkins/Hudson to interfere with whatever I&#8217;m doing right know. It should run invisible in the background.</p>
<p style="text-align:justify;">Luckily it is possible to run an iOS app headless simply by running the app directly like this:</p>
<pre>&lt;path to app&gt;/MyApp.app/MyApp -RegisterForSystemEvents</pre>
<p>By default I would use a cucumber step like the following to run my app from cucumber:</p>
<pre>Given /^the app has just started$/ do
  launch_app_in_simulator
end</pre>
<p>with <code>launch_app_in_simulator</code> beeing the frank function that uses apple script  to run the app by controlling XCode.</p>
<p>I have changed that to:</p>
<pre>Given /^the app has just started$/ do
  launch_app_headless
end</pre>
<p>with launch_app_headless looking like this:</p>
<pre>def launch_app_headless
  @apppid = fork do
    exec(APP, "-RegisterForSystemEvents")
  end

  wait_for_frank_to_come_up
end</pre>
<p><code>APP</code> is a string variable that contains the path to the frankified app. It is currently set hardcoded in my cucumber <strong><code>Before</code></strong> block:</p>
<pre>require 'fileutils'

##
## adjust app, sdk dir and app dir
##
APP    = "build/Debug-iphonesimulator/Readme Frankified.app/Readme Frankified"
APPDIR = "build/Readme.build/Debug-iphonesimulator/Readme Frankified.build"
SDKDIR = "/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.2.sdk"

USERDIR = "#{APPDIR}/iPhone Simulator User Dir"
PREFDIR = "#{USERDIR}/Library/Preferences"

ACCESIBILITY_PLIST   = "com.apple.Accessibility.plist"
ACCESIBILITY_CONTENT = &lt;&lt;PLIST
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
&lt;dict&gt;
 &lt;key&gt;ApplicationAccessibilityEnabled&lt;/key&gt;
 &lt;true/&gt;
&lt;/dict&gt;
&lt;/plist&gt;
PLIST

Before do
  # check that pwd contains the "build" dir as we are creating
  # items relative to it.
  Dir["build"].length.should == 1

  # make sure we do start with a clean environment
  FileUtils.remove_dir("#{USERDIR}",true)

  pwd     = "#{Dir.pwd}"
  prefdir = "#{pwd}/#{PREFDIR}"
  FileUtils.mkdir_p prefdir

  File.open("#{PREFDIR}/#{ACCESIBILITY_PLIST}", 'w') do |f|
    f &lt;&lt;ACCESIBILITY_CONTENT
  end

  ENV['SDKROOT']               = "#{SDKDIR}"
  ENV['DYLD_ROOT_PATH']        = "#{SDKDIR}"
  ENV['IPHONE_SIMULATOR_ROOT'] = "#{SDKDIR}"
  ENV['TEMP_FILES_DIR']        = "#{pwd}/#{APPDIR}"
  ENV['CFFIXED_USER_HOME']     = "#{pwd}/#{USERDIR}"
end</pre>
<p style="text-align:justify;">The accessibility stuff is required to create a configuration file for the app that enables accessibility. Without it Frank will not find the accessibilityLabels which are used to identify the ui elements.</p>
<p style="text-align:justify;">Now I&#8217;m able to run the cucumber test for my app headless in Jenkins/Hudson. I created a second build configuration for the acceptance tests. It uses nearly the same setup as for unit testing. I just have added an additional &#8220;Execute Shell&#8221; step after building the frankified app that runs cucumber:</p>
<pre>cd trunk
cucumber -f junit --o ../cucumber --tags ~@ignore features.frank</pre>
<p style="text-align:justify;">Using the <code>-f junit</code> parameter cucmber will create an junit xml file so Jenkins/Hudson can display the test results in the same ways as the unit tests. <code>features.frank</code> is the folder were I keep my cucumber scenarios.</p>
<p style="text-align:justify;">Code coverage is set up the same way as for the unit tests (see <a title="setting up an automatic build with Hudson" href="http://softnoise.wordpress.com/2010/11/14/ios-running-unit-tests-with-code-coverage-in-hudson">iOS: Running Unit Tests with Code Coverage in Jenkins/Hudson</a>). Now here is also the last complication. Frank currently doesn&#8217;t shut down the app and the result is that the app doesn&#8217;t write the coverage information.</p>
<p style="text-align:justify;">To fix this I simply added a super simple <em>exit command</em> (only calling <code>exit(0)</code>) to Franks embedded http server and a ruby function to call it. I have forked the Frank git repository here <a title="exit command for Frank" href="http://github.com/hauner/Frank">http://github.com/hauner/Frank</a>.</p>
<p style="text-align:justify;">My cucumber <strong><code>After</code></strong> block now shuts down the app so it does write the code coverage info:</p>
<pre>After do
  frankly_exit
end</pre>
<p>with franky_exit beeing:</p>
<pre>def frankly_exit
  get_to_uispec_server('exit')
  # calling exit in the app will not return any response
  # so we simply catch the error caused by exiting.
  rescue EOFError
end</pre>
<p style="text-align:justify;">Now the app will shut down with a clean exit, write the code coverage information and the code coverage step in Jenkins/Hudson will properly display the code coverage for my acceptance tests.</p>
<p><strong>Done, </strong>finally <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p style="text-align:justify;"><strong>Summary:</strong> I have reached my goal to have a test environment to create unit tests (using <strong><a title="tools for iOS testing" href="http://code.google.com/p/google-toolbox-for-mac/">Google Toolbox for Mac</a></strong>,  <a title="an objective-c mock/stub framework" href="http://www.mulle-kybernetik.com/software/OCMock/"><strong>OCMock</strong></a> &amp; <a title="declarative test asserts" href="http://code.google.com/p/hamcrest/wiki/TutorialObjectiveC"><strong>OCHamcrest</strong></a>) and acceptance tests (using <strong><a title="acceptance testing framework" href="http://cukes.info/">Cucumber</a> </strong>&amp;<strong> <a title="cucumber for iOS" href="http://blog.thepete.net/2010/07/frank-automated-acceptance-tests-for.html">Frank</a></strong>) of an iOS  app. Both test categories are running in <a title="continuous integration server" href="http://jenkins-ci.org/"><strong>Jenkins/Hudson</strong></a> as two separate builds and  both builds provide code coverage information. It took a little bit of work, but it is running now.</p>
<p>That is all I have to say regarding testing an iOS app for now! <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><em>This is the 6th article of <a title="setting up an iOS test environment" href="http://softnoise.wordpress.com/2010/11/14/ios-setting-up-a-test-environment">iOS: Setting Up a Test Environment is a Mess</a>.</em></p>
<br /> Tagged: <a href='http://softnoise.wordpress.com/tag/cucumber/'>cucumber</a>, <a href='http://softnoise.wordpress.com/tag/frank/'>frank</a>, <a href='http://softnoise.wordpress.com/tag/hudson/'>hudson</a>, <a href='http://softnoise.wordpress.com/tag/ios/'>ios</a>, <a href='http://softnoise.wordpress.com/tag/jenkins/'>jenkins</a>, <a href='http://softnoise.wordpress.com/tag/test/'>test</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/softnoise.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/softnoise.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/softnoise.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/softnoise.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/softnoise.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/softnoise.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/softnoise.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/softnoise.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/softnoise.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/softnoise.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/softnoise.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/softnoise.wordpress.com/114/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/softnoise.wordpress.com/114/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/softnoise.wordpress.com/114/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=softnoise.wordpress.com&amp;blog=11897628&amp;post=114&amp;subd=softnoise&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://softnoise.wordpress.com/2010/11/14/ios-running-cucumberfrank-with-code-coverage-in-hudson/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b8275cd51c46ecd441233ec6ddd7b7db?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">hauner</media:title>
		</media:content>
	</item>
		<item>
		<title>iOS: Setting Up Acceptance Testing</title>
		<link>http://softnoise.wordpress.com/2010/11/14/ios-setting-up-acceptance-testing/</link>
		<comments>http://softnoise.wordpress.com/2010/11/14/ios-setting-up-acceptance-testing/#comments</comments>
		<pubDate>Sun, 14 Nov 2010 16:09:56 +0000</pubDate>
		<dc:creator>hauner</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[frank]]></category>
		<category><![CDATA[hudson]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[jenkins]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://softnoise.wordpress.com/?p=92</guid>
		<description><![CDATA[After setting up Jenkins/Hudson to build and run my unit tests and collecting code coverage in the last article I will give some guidance for setting up acceptance testing with Cucumber based on a new test framework called Frank. This article will not make much sense if you do not know cucumber. To learn about [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=softnoise.wordpress.com&amp;blog=11897628&amp;post=92&amp;subd=softnoise&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify;">After setting up <a title="continuous integration server" href="http://jenkins-ci.org/">Jenkins/Hudson</a> to build and run my unit tests and collecting code coverage in the <a href="http://softnoise.wordpress.com/2010/11/13/ios-running-un…rage-in-hudson">last article</a> I will give some guidance for setting up acceptance testing with <strong><a title="acceptance testing framework" href="http://cukes.info/">Cucumber</a></strong> based on a new test framework called <strong><a title="cucumber for iOS" href="http://blog.thepete.net/2010/07/frank-automated-acceptance-tests-for.html">Frank</a></strong>.</p>
<p style="text-align:justify;">This article will not make much sense if you do not know cucumber. To learn about cucumber check out the cucumber home page <a title="cucumber test framework" href="http://cukes.info/">here</a> or take a look at the <a title="cucumber introduction" href="http://cuke4ninja.com/"><em>Secret Ninja Cucumber Scrolls</em></a>.</p>
<p style="text-align:justify;"><strong>Frank</strong> embeds a http server into the test version of our app which will be run when the app gets started. Via this internal http server the cucumber part of frank will send commands to the app to remote control it (taps, button taps, filling texts and so on) or to look for ui elements I want to see on specific views.</p>
<p style="text-align:justify;">The first step is create a &#8220;<em>frankified</em>&#8221; version of the app for testing by modifiying a copy of the iOS Apps target configuration in XCode:</p>
<ul>
<li> <code>main</code> gets replaced by a version that start the http server before it creates the usual <code>UIApplicationMain</code></li>
<li>it links to the Frank library</li>
<li>and it includes a Frank resource bundle used by the http server</li>
</ul>
<p style="text-align:justify;">That is described in more detail in the Frank documentation so I will not repeat it here. After having a &#8220;<em>frankified</em>&#8221; app we can start writing cucumber scenarios.</p>
<p style="text-align:justify;">Frank already comes with a number of usable cucumber steps, making it easier to get started and are also useful as a template for private steps.</p>
<p>Here is a list of the built-in steps:</p>
<pre>Then /^I wait to see "([^\"]*)"$/
Then /^I wait to not see "([^\"]*)"$/
Then /^I wait to see a navigation bar titled "([^\"]*)"$/
Then /^I wait to not see a navigation bar titled "([^\"]*)"$/
Then /^I should see a "([^\"]*)" button$/
Then /^I should see "([^\"]*)"$/
Then /^I should not see "([^\"]*)"$/
Then /^I should see the following:/
Then /^I should see a navigation bar titled "([^\"]*)"$/

When /^I type "([^\"]*)" into the "([^\"]*)" text field$/
When /^I fill in "([^\"]*)" with "([^\"]*)"$/
When /^I fill in text fields as follows:$/

And /^I rotate to the "([^\"]*)"$/
When /^I touch "([^\"]*)"$/
Then /I touch the following:/
When /^I touch the button marked "([^\"]*)"$/
When /^I touch the "([^\"]*)" action sheet button$/
When /^I touch the (\d*)(?:st|nd|rd|th)? action sheet button$/

When /^I flip switch "([^\"]*)"$/
Then /^switch "([^\"]*)" should be on$/
Then /^switch "([^\"]*)" should be off$/

Then /^a pop\-over menu is displayed with the following:$/
Then /^I navigate back$/</pre>
<p>Having quite a number of example steps it is not very difficult to create additional steps. All the built-in steps are just a few lines and easy to understand.</p>
<p>For example I created a step that looks like this:</p>
<pre>Then /^I should see text fields for:$/ do |table|
  table.raw.each do |v|
    check_element_exists(%Q|textField accessibilityLabel:"#{v}"|);
  end
end</pre>
<p style="text-align:justify;">The interesting part is the <code>check_element_exists</code>. It is one of the basic calls used to implement the above steps. It takes care of all the communication with the http server in the <em>&#8220;frankified&#8221;</em> test app.</p>
<p style="text-align:justify;">By default Frank uses the &#8220;Accessibility Label&#8221; to locate ui elements in the app using <strong><a title="iOS ui test framework" href="http://code.google.com/p/uispec/">UISpec</a></strong>. The &#8220;Accessibility Label&#8221;s original use is to give a hint what a control is for to people with visual impairments. Frank uses it to mark ui elements with a &#8220;label&#8221; that we can use in our cucumber steps to refer to that ui element.</p>
<p style="text-align:justify;">For example the cucumber scenario using my custom step looks like this:</p>
<pre>Scenario:
  ask user to login at first startup

  Given the app runs for the first time
  Then I should be on the "Login" screen
  And I should see text fields for:
    | Login    |
    | Password |</pre>
<p style="text-align:justify;">The &#8220;And&#8221; step is using my custom step and it (i.e. UISpec triggered by a call to the embedded http server) will look for two text fields that are marked with the accessibility labels &#8220;Login&#8221; and &#8220;Password&#8221;.</p>
<p style="text-align:justify;">I set the labels from Interface Builder by opening the Inspector, switching to the View Identity tab (it is the last tab) and setting the &#8220;Label&#8221; under the &#8220;Accessibility&#8221; options.</p>
<p style="text-align:justify;"><strong>Note:</strong><br />
To make this work in the simulator I first had to enable &#8220;Accessibility&#8221; feature in MacOSX, i.e. enable &#8220;Enable access for assistive devices&#8221; in the &#8220;Universal Access&#8221; system preferences.</p>
<p>Really cool is, that the parameter to <code>check_element_exists</code> is a <strong><a title="UIScript documentation" href="http://code.google.com/p/uispec/wiki/Documentation#UIScript">UISpec script expression</a></strong>.</p>
<p>This make it possible to check for other properties than the accessibilityLabel of an ui element. I can easily check that the &#8220;tag&#8221; property (it is on the View Attributes tab in the Interface Builder inspector) of an ui element has a specific value using the following expression:</p>
<pre>check_element_exists("view tag:1")</pre>
<p>Check out <strong><a title="iOS ui test framework" href="http://code.google.com/p/uispec/">UISpec/UIScript</a></strong> to learn more about this.</p>
<p style="text-align:justify;">To run the cucumber scenarios for my app I simply run the <code>cucumber</code> command from bash and watch frank running trough my acceptance tests.</p>
<p style="text-align:justify;">Currently you will have to open XCode as frank uses apple script to run the app in the simulator from XCode. That is not the perfect way to run the cucumber test automatically from <a title="continuous integration server" href="http://jenkins-ci.org/">Jenkins/Hudson</a>.</p>
<p style="text-align:justify;"><strong>Summary:</strong> I have reached my next goal, running <strong><a title="acceptance testing framework" href="http://cukes.info/">Cucumber</a></strong> acceptance tests against my iOS app using <strong><a title="cucumber for iOS" href="http://blog.thepete.net/2010/07/frank-automated-acceptance-tests-for.html">Frank</a></strong>. Apart from enabling the accessibility stuff, there were no complications to get it running.</p>
<p style="text-align:justify;">In the next article <a title="setting up an automatic build for Frank with Hudson" href="http://softnoise.wordpress.com/2010/11/14/ios-running-cucumberfrank-with-code-coverage-in-hudson">iOS: Running Cucumber/Frank with Code Coverage in Jenkins/Hudson</a> I will describe how I managed to run my <em>&#8220;frankified&#8221;</em> app headless from <a title="continuous integration server" href="http://jenkins-ci.org/">Jenkins/Hudson</a> by using just a view lines of additional ruby code.</p>
<p style="text-align:justify;"><em>This is the 5th article of <a title="setting up an iOS test environment" href="http://softnoise.wordpress.com/2010/11/14/ios-setting-up-a-test-environment">iOS: Setting Up a Test Environment is a Mess</a>.</em></p>
<br /> Tagged: <a href='http://softnoise.wordpress.com/tag/cucumber/'>cucumber</a>, <a href='http://softnoise.wordpress.com/tag/frank/'>frank</a>, <a href='http://softnoise.wordpress.com/tag/hudson/'>hudson</a>, <a href='http://softnoise.wordpress.com/tag/ios/'>ios</a>, <a href='http://softnoise.wordpress.com/tag/jenkins/'>jenkins</a>, <a href='http://softnoise.wordpress.com/tag/test/'>test</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/softnoise.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/softnoise.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/softnoise.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/softnoise.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/softnoise.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/softnoise.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/softnoise.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/softnoise.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/softnoise.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/softnoise.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/softnoise.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/softnoise.wordpress.com/92/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/softnoise.wordpress.com/92/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/softnoise.wordpress.com/92/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=softnoise.wordpress.com&amp;blog=11897628&amp;post=92&amp;subd=softnoise&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://softnoise.wordpress.com/2010/11/14/ios-setting-up-acceptance-testing/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b8275cd51c46ecd441233ec6ddd7b7db?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">hauner</media:title>
		</media:content>
	</item>
		<item>
		<title>iOS: Running Unit Tests with Code Coverage in Jenkins/Hudson</title>
		<link>http://softnoise.wordpress.com/2010/11/14/ios-running-unit-tests-with-code-coverage-in-hudson/</link>
		<comments>http://softnoise.wordpress.com/2010/11/14/ios-running-unit-tests-with-code-coverage-in-hudson/#comments</comments>
		<pubDate>Sun, 14 Nov 2010 16:07:11 +0000</pubDate>
		<dc:creator>hauner</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[coverage]]></category>
		<category><![CDATA[gcvor]]></category>
		<category><![CDATA[hudson]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[jenkins]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://softnoise.wordpress.com/?p=76</guid>
		<description><![CDATA[Now that I have a nice unit test environment (see iOS: Setting Up Basic Unit Testing and iOS: Setting Up Advanced Unit Testing) I still need something to run them automatically. I choose Jenkins/Hudson as continuous integration server. To build a project from Jenkins/Hudson it helps to already have an automatic build. That means you [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=softnoise.wordpress.com&amp;blog=11897628&amp;post=76&amp;subd=softnoise&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify;">Now that I have a nice unit test environment (see <a title="setting up unit testing with Google Toolbox for Mac" href="http://softnoise.wordpress.com/2010/11/14/ios-setting-up-basic-unit-testing/">iOS: Setting Up Basic Unit Testing</a> and <a title="setting up OCMock and OCHamcrest" href="http://softnoise.wordpress.com/2010/11/14/ios-setting-up-advanced-unit-testing">iOS: Setting Up Advanced Unit Testing</a>) I still need something to run them automatically. I choose <strong><a title="continuous integration server" href="http://jenkins-ci.org/">Jenkins/Hudson</a></strong> as continuous integration server.</p>
<p style="text-align:justify;">To build a project from Jenkins/Hudson it helps to already have an automatic build. That means you have an XCode project which does not depend on any absolute paths for additional libraries (as  <a title="tools for iOS testing" href="http://code.google.com/p/google-toolbox-for-mac/">Google Toolbox for Mac</a>, <a title="an objective-c mock/stub framework" href="http://www.mulle-kybernetik.com/software/OCMock/">OCMock</a> or <a title="declarative test asserts" href="http://code.google.com/p/hamcrest/wiki/TutorialObjectiveC">OCHamcrest</a>). That is the background of the CI Tips to include OCMock and OCHamcrest into the projects source control in my previous articles.</p>
<p style="text-align:justify;">2011/2: see also <a title="setting up ocmock &amp; ochamcrest take two" href="http://softnoise.wordpress.com/2011/02/20/ios-setting-up-advanced-unit-testing-take-two/">iOS: Setting Up Advanced Unit Testing Take Two</a>.</p>
<p style="text-align:justify;">Already having an automatic clean build from XCode, it does not take much to run in from Jenkins/Hudson. Quite useful was <a title="building an XCcode Project from Hudson" href="http://blog.jayway.com/2010/01/31/continuos-integration-for-xcode-projects/">this article</a>. It shows how to use xcodebuild to run an XCode project without XCode. It also provides a small script to convert the objective-c test output to junit xml output that Jenkins/Hudson will understand.</p>
<p>Based on that blog my &#8220;Execute Shell&#8221; step looks like this:</p>
<pre>xcodebuild -target "UnitTests" -sdk /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.1.2.sdk/ -configuration "Debug" | /usr/local/bin/ocunit2junit.rb</pre>
<p>And the &#8220;post build step&#8221; &#8220;Publish JUnit test result report&#8221; like this:</p>
<pre>test-reports/*.xml</pre>
<p>as &#8220;Test report XMLs&#8221;.</p>
<p style="text-align:justify;">Great, after following the above article Jenkins/Hudson will watch my repository for changes, check out everything if a new commit hows up, build my &#8220;UnitTest&#8221; target (automatically running the tests, because of the shell script we added to the unit test project), convert the test output to a junit compatible format and display the test results and statistics in Jenkins/Hudson.</p>
<p style="text-align:justify;">Getting the build running in Jenkins/Hudson was the easy part, making it collect code coverage adds new complications.</p>
<p style="text-align:justify;"><strong>Code Coverage:</strong> To enable code coverage in the debug unit test target I set the following stuff in the XCode project (GetInfo on the unit test target):</p>
<p>In the &#8220;GCC 4.2 Preprocessing&#8221; section enable &#8220;Generate Test Coverage Files&#8221; and &#8220;Instrument Program Flow&#8221;. Add -lgcov to &#8220;Linking&#8221; section &#8220;other linker flags&#8221;. I got that info from <a title="Code Coverage with XCode" href="http://www.supermegaultragroovy.com/blog/2005/11/03/unit-testing-and-code-coverage-with-xcode/">here</a>.</p>
<p style="text-align:justify;"><strong>Complication No. 4:</strong> Unfortunately there are bugs in the XCode (currently 3.2.4 with gcc 4.2.1) that brake the code coverage. In my case link errors and 0% code coverage.</p>
<p style="text-align:justify;"><strong>Solution to Complication No. 4:</strong> The advice given <a title="Code Coverage on Slow Lepoard and GCC 4.2.1" href="http://code.google.com/p/google-toolbox-for-mac/wiki/SnowLeopardGCov">here</a> helped me to get proper code coverage info. It provides a fixed gcov library (to fix the link errors) and tells you to clear the prefix header (to fix the 0% coverage issue).</p>
<p style="text-align:justify;">Now running the test from Jenkins/Hudson will create the code coverage information but in a format that Jenkins/Hudson does not understand. By using another script called <a title="gcov to cobertura" href="https://software.sandia.gov/trac/fast/wiki/gcovr">gcovr</a> we can convert the gcov output to Cobertura xml. <a title="java code coverage" href="http://cobertura.sourceforge.net/">Cobertura</a> is a Java code coverage tool that Jenkins/Hudson understands. I got this info from <a title="using gcovr" href="http://wehart.blogspot.com/2009/07/summarizing-gcov-coverage-statistics.html">here</a>.</p>
<p style="text-align:justify;">Next step is to enable the cobertura &#8220;post build step&#8221; &#8220;Publish Cobertura Coverage Report&#8221; and set the &#8220;Cobertura xml report pattern&#8221; to</p>
<pre style="text-align:justify;">**/coverage.xml</pre>
<p>in the projects Hudson configuration.</p>
<p style="text-align:justify;"><strong>Complication No. 5:</strong> Of course this did not work for me out of the box. I had to patch the gcovr script a little bit. Orginally the script will change the current dir and run gcov with the filename of a gcov data file. That does not work. So I modified the script to run gcov with the full path of the data file and that works for me.</p>
<p style="text-align:justify;"><strong>Solution to Complication No.5:</strong> her is my patch for gcovr:</p>
<p><pre class="brush: plain;">
--- Downloads/gcovr	2010-06-06 18:49:03.000000000 +0200
+++ bin/gcovr	2010-06-08 22:36:21.000000000 +0200
@@ -296,10 +297,13 @@
     (dir,base) = os.path.split(file)
     (name,ext) = os.path.splitext(base)
     prevdir = os.getcwd()
-    os.chdir(dir)
+    #os.chdir(dir)
     (head, tail) = os.path.split(name)
     cmd = gcov_cmd + \
-          &quot; --branch-counts --branch-probabilities --preserve-paths &quot; + tail
+          &quot; --branch-counts --branch-probabilities --preserve-paths &quot; + file \
+          + &quot; -o &quot; + dir
+          #+ tail
     output = subprocess.Popen( cmd.split(&quot; &quot;),
                                stdout=subprocess.PIPE ).communicate()[0]
     #output = subprocess.call(cmd)
</pre></p>
<p><strong> </strong><strong><br />
</strong></p>
<p style="text-align:justify;"><strong>CI Tip:</strong> add the gcovr script to your repository.</p>
<p style="text-align:justify;"><strong>Summary: </strong>Finally, after going through all this issues I have an automatic build running in Jenkins/Hudson that runs the unit tests and collects code coverage information.</p>
<p style="text-align:justify;">In the next article <a title="setting up acceptance testing with Cucumber and Frank" href="http://softnoise.wordpress.com/2010/11/14/ios-setting-up-acceptance-testing">iOS: Setting Up Acceptance Testing</a> I will write a little  bit about using <strong><a title="acceptance testing framework" href="http://cukes.info/">Cucumber</a></strong> for acceptance testing with the help of <strong><a title="cucumber for iOS" href="http://blog.thepete.net/2010/07/frank-automated-acceptance-tests-for.html">Frank</a></strong>.</p>
<p style="text-align:justify;"><em>This is the 4th article of <a title="setting up an iOS test environment" href="http://softnoise.wordpress.com/2010/11/14/ios-setting-up-a-test-environment">iOS: Setting Up a Test Environment is a Mess</a>.</em></p>
<br /> Tagged: <a href='http://softnoise.wordpress.com/tag/coverage/'>coverage</a>, <a href='http://softnoise.wordpress.com/tag/gcvor/'>gcvor</a>, <a href='http://softnoise.wordpress.com/tag/hudson/'>hudson</a>, <a href='http://softnoise.wordpress.com/tag/ios/'>ios</a>, <a href='http://softnoise.wordpress.com/tag/jenkins/'>jenkins</a>, <a href='http://softnoise.wordpress.com/tag/test/'>test</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/softnoise.wordpress.com/76/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/softnoise.wordpress.com/76/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/softnoise.wordpress.com/76/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/softnoise.wordpress.com/76/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/softnoise.wordpress.com/76/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/softnoise.wordpress.com/76/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/softnoise.wordpress.com/76/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/softnoise.wordpress.com/76/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/softnoise.wordpress.com/76/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/softnoise.wordpress.com/76/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/softnoise.wordpress.com/76/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/softnoise.wordpress.com/76/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/softnoise.wordpress.com/76/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/softnoise.wordpress.com/76/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=softnoise.wordpress.com&amp;blog=11897628&amp;post=76&amp;subd=softnoise&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://softnoise.wordpress.com/2010/11/14/ios-running-unit-tests-with-code-coverage-in-hudson/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b8275cd51c46ecd441233ec6ddd7b7db?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">hauner</media:title>
		</media:content>
	</item>
		<item>
		<title>iOS: Setting Up Advanced Unit Testing</title>
		<link>http://softnoise.wordpress.com/2010/11/14/ios-setting-up-advanced-unit-testing/</link>
		<comments>http://softnoise.wordpress.com/2010/11/14/ios-setting-up-advanced-unit-testing/#comments</comments>
		<pubDate>Sun, 14 Nov 2010 16:04:31 +0000</pubDate>
		<dc:creator>hauner</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[ochamcrest]]></category>
		<category><![CDATA[ocmock]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://softnoise.wordpress.com/?p=59</guid>
		<description><![CDATA[In the previous article iOS: Setting Up Basic Unit Testing I choose Google Toolbox for Mac as my unit testing framework. Now I will add OCMock and OCHamcrest. OCMock: To create test doubles (mock, stubs etc.) in a unit test I like the objective-c mock framework OCMock. Its latest version adds support for iOS (universal [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=softnoise.wordpress.com&amp;blog=11897628&amp;post=59&amp;subd=softnoise&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify;">In the previous article <a title="setting up unit testing with Google Toolbox for Mac" href="http://softnoise.wordpress.com/2010/11/14/ios-testing-basic-unit-testing/"></a><a title="setting up unit testing with Google Toolbox for Mac" href="http://softnoise.wordpress.com/2010/11/14/ios-setting-up-basic-unit-testing/">iOS: Setting Up Basic Unit Testing</a> I choose <strong><a title="tools for iOS testing" href="http://code.google.com/p/google-toolbox-for-mac/">Google Toolbox for Mac</a></strong> as my unit testing framework. Now I will add <strong><a title="Objective-C Mock/Stub framework" href="http://www.mulle-kybernetik.com/software/OCMock/"><strong>OCMock</strong></a></strong> and <a title="declarative test asserts" href="http://code.google.com/p/hamcrest/wiki/TutorialObjectiveC"><strong>OCHamcrest</strong></a>.</p>
<p style="text-align:justify;"><strong>OCMock:</strong> To create test doubles (mock, stubs etc.) in a unit test I like the  objective-c mock framework OCMock. Its latest version adds support for  iOS (universal (simulator, device) static lib). Take care to check the <a title="OCMock on iOS" href="http://http//www.mulle-kybernetik.com/software/OCMock/#ios">iOS instructions</a>. You have to add a few compiler switches to avoid obscure linker errors.</p>
<p style="text-align:justify;">Here is another nice article explaining what you can do with OCMock: <a title="using ocmock" href="http://alexvollmer.com/posts/2010/06/28/making-fun-of-things-with-ocmock/">Making Fun of Things with OCMock</a>.</p>
<p style="text-align:justify;">When I  tried it for the first time the iOS support was only available in the  svn repository and the linker stuff was not yet covered in the  instructions. It is now, so we have one complication less <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p style="text-align:justify;">To use  the library I adjusted the &#8220;Header Seach Paths&#8221; &amp; &#8220;Library Search  Paths&#8221; in the &#8220;Search Path&#8221; section of the unit test target to include  the OCMock paths (OCMock/Debug/Headers, OCMock/Debug,  OCMock/Release/Headers, OCMock/Release). The Headers are the same for  Debug and Release but currently OCMock creates the above layout and it  will be easier to update if it is unchanged.</p>
<p style="text-align:justify;">2011/2: I improved my setup: <a title="setting up ocmock &amp; ochamcrest take two" href="http://softnoise.wordpress.com/2011/02/20/ios-setting-up-advanced-unit-testing-take-two/">iOS: Setting Up Advanced Unit Testing Take Two</a>.</p>
<p style="text-align:justify;"><strong>CI Tip:</strong> I added the debug and release headers/library to my subversion project  so I do not have to link  to external files when I&#8217;m going to setup the <a title="continuous integration server" href="http://jenkins-ci.org/">Jenkins/Hudson</a> build.</p>
<p style="text-align:justify;"><strong>Unit Testing Tip:</strong> To get some insight why you should use test doubles watch this <a title="unit testing advice" href="http://www.infoq.com/presentations/integration-tests-scam">presentation</a> by J.B. Rainsberger. Note that he is not really talking about  integration tests, he talks about not writing integration tests to test  units.  See also his <a title="integrated tests are a scam" href="http://blog.jbrains.ca/integrated_tests_are_a_scam">blog</a> where he admits that talking about &#8220;integration test&#8221; in this  context is confusing. Anyway, there is something to learn in this video.</p>
<p style="text-align:justify;"><strong>OCHamcrest</strong>: Another useful extension is <a title="declarative assertions" href="http://code.google.com/p/hamcrest/">OCHamcrest</a> that allows for more declarative assertions. Nothing that is required but it makes the test more readable.</p>
<p style="text-align:justify;"><strong>Complication No. 2</strong>, OCHamcrest does not provide iOS support out of the box.</p>
<p style="text-align:justify;">2011/2: The issue described here has been fixed, it it no longer necessary to patch OCHamcrest. See also <a title="setting up ocmock &amp; ochamcrest take two" href="http://softnoise.wordpress.com/2011/02/20/ios-setting-up-advanced-unit-testing-take-two/">iOS: Setting Up Advanced Unit Testing Take Two</a>.</p>
<p style="text-align:justify;"><strong>Solution to Complication No. 2</strong>, There is a project on <a title="ochamcrest for iOS" href="http://github.com/jonah-carbonfive/hamcrest-objectivec-iPhone">github</a> that adds an iOS target to the build but it doesn&#8217;t create a similar  universal library as OCMock. To make it similiar to OCMock I used the  original Hamcrest <a title="ochamcrest sources" href="http://hamcrest.googlecode.com/svn/trunk/hamcrest-objectivec">objective-c source</a> and added a static library target for iOS based on the OCMock xcode project.</p>
<p style="text-align:justify;">I only  used to the git project to fix the compile errors for the iOS target on  the original sources. Luckily it required only two small changes:</p>
<p><pre class="brush: plain;">
Index: Source/Core/HCMatcherAssert.mm
===================================================================
--- Source/Core/HCMatcherAssert.mm	(revision 557)
+++ Source/Core/HCMatcherAssert.mm	(working copy)
@@ -%ld,%ld +%ld,%ld @@
#import &quot;HCMatcher.h&quot;

// Objective-C
-#import
+//#import
+#import

namespace {
Index: Source/Core/HCBaseMatcher.mm
===================================================================
--- Source/Core/HCBaseMatcher.mm	(revision 557)
+++ Source/Core/HCBaseMatcher.mm	(working copy)
@@ -%ld,%ld +%ld,%ld @@
- (void) subclassResponsibility:(SEL)command
{
[NSException raise:NSGenericException
-                format:@&quot;-[%@  %s] not implemented&quot;, [self className], command];
+                format:@&quot;-[%@  %s] not implemented&quot;, [self class/*Name*/], command];
}

@end
</pre></p>
<p style="text-align:justify;">To use  the library I adjusted the &#8220;Header Seach Paths&#8221; &amp; &#8220;Library Search  Paths&#8221; in the &#8220;Search Path&#8221; section of the unit test target to include  the OCHamcrest paths as for OCMock (OCHamcrest/Debug/Headers,  OCHamcrest/Debug, OCHamcrest/Release/Headers, OCHamcrest/Release).</p>
<p style="text-align:justify;">Finally  I added -lOCHamcrest and -lstdc++ (I added -ObjC and -all-load already  for OCMock) to &#8220;Other Linker Flags&#8221; in the &#8220;Linking&#8221; Section. Adding  HC_SHORTHAND to the &#8220;Preprocessor Macros&#8221; in the &#8220;GCC 4.2 Preprocessing&#8221;  section allows me to assert without the &#8220;ST&#8221; prefix. (Based on the  description from the github hamcrest)</p>
<p><pre class="brush: plain;">
// useless test example ;-)
- (void) testOCHamcrest {
 assertThatBool (YES, equalToBool (YES));
}
</pre></p>
<p><strong><br />
</strong></p>
<p style="text-align:justify;"><strong>Complication No. 3:</strong> Unfortunately if an assertion fails the test runner crashes. This seems to be a bug in the simulator.</p>
<p style="text-align:justify;">2011/2: The issue described here has been fixed, it it no longer necessary to patch OCHamcrest. See also <a title="setting up ocmock &amp; ochamcrest take two" href="http://softnoise.wordpress.com/2011/02/20/ios-setting-up-advanced-unit-testing-take-two/">iOS: Setting Up Advanced Unit Testing Take Two</a>.</p>
<p style="text-align:justify;"><strong>Solution to Complication No. 3:</strong> This can be fixed by patching Hamcrest with a <a title="hamcrest patch for simulator bug" href="http://groups.google.com/group/google-toolbox-for-mac/browse_thread/thread/bcee48ef7612975e/4156b1dcc9feea1b?lnk=gst&amp;q=hamcrest#4156b1dcc9feea1b">patch</a> provided by the Google Toolbox for Mac project. To apply the patch use something like this:</p>
<pre style="text-align:justify;">git apply -p 3 ~/Downloads/hamcrest_ios4_fix.patch</pre>
<p style="text-align:justify;">After applying the patch it works a lot better, but it is still not perfect. Hopefully the bug in the simulator will be fixed in a future version of the iOS SDK.</p>
<p style="text-align:justify;"><strong>S</strong><strong>ummary:</strong> in this article I wrote about extending the unit testing tool set with OCMock and OCHamcrest.<strong> </strong></p>
<p style="text-align:justify;"><strong>Advice: </strong>if you are unfamiliar with OCMock check it out. You do  not really need OCHamcrest if you don&#8217;t care about the declarative  assertions. If you want to avoid Complication No. 2 and No 3. you can  skip OCHamcrest. But I like it <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p style="text-align:justify;">The next topic is <a title="setting up an automatic build with Hudson" href="http://softnoise.wordpress.com/2010/11/14/ios-running-unit-tests-with-code-coverage-in-hudson">iOS: Running Unit Tests with Code Coverage in Jenkins/Hudson</a>.</p>
<p style="text-align:justify;"><em>This is the 3rd article of <a title="setting up an iOS test environment" href="http://softnoise.wordpress.com/2010/11/14/ios-setting-up-a-test-environment">iOS: Setting Up a Test Environment is a Mess</a>.</em></p>
<br /> Tagged: <a href='http://softnoise.wordpress.com/tag/ios/'>ios</a>, <a href='http://softnoise.wordpress.com/tag/ochamcrest/'>ochamcrest</a>, <a href='http://softnoise.wordpress.com/tag/ocmock/'>ocmock</a>, <a href='http://softnoise.wordpress.com/tag/test/'>test</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/softnoise.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/softnoise.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/softnoise.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/softnoise.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/softnoise.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/softnoise.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/softnoise.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/softnoise.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/softnoise.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/softnoise.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/softnoise.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/softnoise.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/softnoise.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/softnoise.wordpress.com/59/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=softnoise.wordpress.com&amp;blog=11897628&amp;post=59&amp;subd=softnoise&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://softnoise.wordpress.com/2010/11/14/ios-setting-up-advanced-unit-testing/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b8275cd51c46ecd441233ec6ddd7b7db?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">hauner</media:title>
		</media:content>
	</item>
		<item>
		<title>iOS: Setting Up Basic Unit Testing</title>
		<link>http://softnoise.wordpress.com/2010/11/14/ios-setting-up-basic-unit-testing/</link>
		<comments>http://softnoise.wordpress.com/2010/11/14/ios-setting-up-basic-unit-testing/#comments</comments>
		<pubDate>Sun, 14 Nov 2010 16:02:34 +0000</pubDate>
		<dc:creator>hauner</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[gtm]]></category>
		<category><![CDATA[ios]]></category>
		<category><![CDATA[test]]></category>
		<category><![CDATA[xcode]]></category>

		<guid isPermaLink="false">http://softnoise.wordpress.com/?p=56</guid>
		<description><![CDATA[After a short introduction in my first iOS testing article I will describe how I set up basic unit testing on iOS. Complication No. 1, &#8220;the Apple way&#8221;: XCode comes with a unit test framwork, OCUnit, but unfortunately its integration is a little bit strange. You create an octest bundle that&#8217;s &#8220;somehow&#8221; (I didn&#8217;t try [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=softnoise.wordpress.com&amp;blog=11897628&amp;post=56&amp;subd=softnoise&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p style="text-align:justify;">After a short introduction in my <a title="setting up an iOS test environment" href="http://softnoise.wordpress.com/2010/11/14/ios-setting-up-a-test-environment">first iOS testing article</a> I will describe how I set up basic unit testing on iOS.</p>
<p style="text-align:justify;"><strong>Complication No. 1</strong>,  <em>&#8220;the Apple way&#8221;</em>: XCode comes with a unit test framwork, <strong>OCUnit</strong>, but  unfortunately its integration is a little bit strange. You create an  octest bundle that&#8217;s &#8220;somehow&#8221; (I didn&#8217;t try to understand how this is  working in detail) loaded into your normal project target and then will  run your unit tests.</p>
<p style="text-align:justify;">Usually  I would simply create a second binary that contains the test sources  and the production sources and links to the same libraries plus the  libraries needed for testing.</p>
<p style="text-align:justify;">The  only advantage I see in using the bundle approach is that I do not have  to create a test target with nearly the same setup for the unit tests  (copying all settings, adding all classes you want to test and so  on&#8230;).</p>
<p style="text-align:justify;">One  annoying drawback is setting it up for debugging. Sometimes it is useful  to step trough a test to understand where it is going wrong but you will need  additional setup to debug your unit tests with breakpoints. That&#8217;s  inconvenient but possible without to much work for normal <a title="debug ocunit test bundles" href="http://chanson.livejournal.com/119578.html">MacOSX development</a> (i.e not iOS). For iOS this is getting more <a title="debugging ocunit test bundle on iOS" href="http://www.grokkingcocoa.com/how_to_debug_iphone_unit_te.html">complicated</a>. As the article says: <em>&#8220;What a mess&#8221;</em>.</p>
<p style="text-align:justify;">Another  drawback is that you can&#8217;t run the tests in the simulator or on the  device itself because your test bundle is not an ordinary iOS app.</p>
<p style="text-align:justify;"><strong>Solution to Complication No. 1</strong>: While looking for iPhone/iOS test resources I found <strong><a title="tools for iOS testing" href="http://code.google.com/p/google-toolbox-for-mac">Google Toolbox for Mac</a></strong> (GTM). First I was wondering why I would need it but after being a  little bit <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  frustrated by the setup of the standard Apple way  above, I gave it a try.</p>
<p style="text-align:justify;">Basically  you create a normal standalone iOS app as part of your project. You  just have to add a couple of GTM source files to your test target app (a  copy of the production app), setup a &#8220;run script&#8221; build phase (to run  the test after they are built) and you are done. This is described in  the <a title="GTM setup for iOS" href="http://code.google.com/p/google-toolbox-for-mac/wiki/iPhoneUnitTesting">GTM iPhoneUnitTesting</a> instructions.</p>
<p style="text-align:justify;"><strong>Note:</strong> I had to remove the MainWindow.xib from the plist file  created for my  test target. With the xib set I got some complains about  the app being  unable to load it.</p>
<p style="text-align:justify;"><strong>CI Tip:</strong> I copied the required files of GTM to my subversion project so I do not  have to link to external files when I&#8217;m going to setup the<strong><strong> </strong></strong> <a title="continuous integration server" href="http://jenkins-ci.org/">Jenkins/Hudson</a> build. 2011/2: See also <a title="setting up ocmock &amp; ochamcrest take two" href="http://softnoise.wordpress.com/2011/02/20/ios-setting-up-advanced-unit-testing-take-two/">iOS: Setting Up Advanced Unit Testing Take Two</a>.</p>
<p style="text-align:justify;">The  only difference for creating new tests is that you have to use  GTMTestCase as base class instead of SenTestCase. But that is not a big  issue and GTMTestCase itself is based on SenTestCase. Which is nice  because it will automatically play well with OCMock and OCHamcrest  (which will be covered in the next article).</p>
<p style="text-align:justify;">A lot  simpler than the default way. Nice is that you will not need any  extra setup to step into your test code. Just set breakpoints and run  the test target. And because it is an ordinary app <strong>it will run in the simulator and on the device</strong>.</p>
<p style="text-align:justify;">GTM has more stuff to explore (e.g. support for UI testing, additional asserts) but I have not yet played with it.</p>
<p style="text-align:justify;"><strong>S</strong><strong>ummary:</strong> with GTM I can easily debug my test cases and run the test in the simulator and on the device. Not bad!<strong> </strong></p>
<p style="text-align:justify;"><strong>Advice: </strong>go with Google Toolbox for Mac for unit testing on iOS.</p>
<p style="text-align:justify;">In <a title="setting up OCMock and OCHamcrest" href="http://softnoise.wordpress.com/2010/11/14/ios-setting-up-advanced-unit-testing">iOS: Setting Up Advanced Unit Testing</a> I will pimp the unit testing environment with OCMock and OCHamcrest which has a few new complications.</p>
<p style="text-align:justify;"><em>This is the 2nd article of <a title="setting up an iOS test environment" href="http://softnoise.wordpress.com/2010/11/14/ios-setting-up-a-test-environment">iOS: Setting Up a Test Environment is a Mess</a>.</em></p>
<br /> Tagged: <a href='http://softnoise.wordpress.com/tag/gtm/'>gtm</a>, <a href='http://softnoise.wordpress.com/tag/ios/'>ios</a>, <a href='http://softnoise.wordpress.com/tag/test/'>test</a>, <a href='http://softnoise.wordpress.com/tag/xcode/'>xcode</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/softnoise.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/softnoise.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/softnoise.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/softnoise.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/softnoise.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/softnoise.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/softnoise.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/softnoise.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/softnoise.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/softnoise.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/softnoise.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/softnoise.wordpress.com/56/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/softnoise.wordpress.com/56/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/softnoise.wordpress.com/56/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=softnoise.wordpress.com&amp;blog=11897628&amp;post=56&amp;subd=softnoise&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://softnoise.wordpress.com/2010/11/14/ios-setting-up-basic-unit-testing/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b8275cd51c46ecd441233ec6ddd7b7db?s=96&#38;d=http%3A%2F%2F1.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">hauner</media:title>
		</media:content>
	</item>
	</channel>
</rss>
