tag:blogger.com,1999:blog-38330723564135020192024-03-18T10:06:46.604+02:00The Code SheriffKeeping the streets clean of bad development practices.Anonymoushttp://www.blogger.com/profile/06100813770559493046noreply@blogger.comBlogger18125tag:blogger.com,1999:blog-3833072356413502019.post-52790467907023298502017-11-20T17:12:00.000+02:002017-11-20T17:12:09.772+02:00Migrated to MediumIf you reached this blog, know that I no longer write here, but moved to Medium instead:<br />
<a href="https://medium.com/@theyonibomber">https://medium.com/@theyonibomber</a><br />
<br />
Please follow me there!Anonymoushttp://www.blogger.com/profile/06100813770559493046noreply@blogger.com24tag:blogger.com,1999:blog-3833072356413502019.post-10719578280933930532015-05-29T13:41:00.000+03:002015-05-29T13:41:25.536+03:00Importing Swift code from Objective-C in a Test Target - It's Possible!<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><b>TL;DR</b></span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><b>By changing the 'PRODUCT_MODULE_NAME' build setting + adding XCTest.h import in the bridging header file, I was able to make this work.</b></span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">On my previous <a href="http://codesheriff.blogspot.co.il/2014/12/why-i-think-swift-is-not-ready-yet.html">post about Swift</a>, I mentioned that one of the biggest issues I had with Swift is the fact I get a compilation error on my unit tests target if I ever use the import "MyProject-Swift.h" in a file that is included in this target (whether it's a test case or production code).</span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">I also mentioned this is a big issue in the <a href="http://www.reversim.com/2015/04/summit-2015-should-you-move-from.html">Swift talk I gave in Reversim Summit 2015</a> (in Hebrew).</span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;">Well, turns out </span><b style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;">I was wrong</b><span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"> (or at least - it can be fixed).</span><br />
<br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">To fully understand the solution, lets' first make sure you understand the problem and why this is such a big issue for me.</span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">I'll try to show a concrete example so you could understand it, </span><span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;">and maybe because all names are stupid it may be harder to relate to, but believe me - if you write new swift code in a real life Objective-C project, you will eventually need to use it SOMEWHERE from your Objective-C code.</span><br />
<div>
<span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"><br /></span></div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><u>Here goes:</u></span>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">Lets' say I have an existing Objective-C project with unit tests.</span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">Class A is written in Objective-C and has a unit test.</span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">It also internally uses a class called B, written in Objective-C and doesn't have a unit test.</span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">I now decided I want to add a new class named C. It's written in Swift and I add a unit test for it in Swift.</span><br />
<br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">Now I want to use class C in class B.</span><br />
<span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;">I need to add "MyProject-Swift.h" to B's code for it to work, right?</span><br />
<span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;">Right.</span><br />
<span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;">So here's what we've come up with by now:</span><br />
<script src="https://gist.github.com/theyonibomber/c1710ad63f948ae805ca.js"></script>
<span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;">If I build and run my app, everything is fine.</span><br />
<span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;">If I build and run my unit tests target, I get the following error:</span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj60vH2fNxtS32vE0vhk_JRXetwftU38OEmDD2Vb5uYr0m-3Rd6589P5ve_r0ZMtqm6OYVUl6H-c5H_FswY9jxg4YUc_qQUA33caNycfJxGms1q_XZmhhgJ0-IIPlEVkaASGGGxjxzm7hY/s1600/B_m.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="145" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj60vH2fNxtS32vE0vhk_JRXetwftU38OEmDD2Vb5uYr0m-3Rd6589P5ve_r0ZMtqm6OYVUl6H-c5H_FswY9jxg4YUc_qQUA33caNycfJxGms1q_XZmhhgJ0-IIPlEVkaASGGGxjxzm7hY/s400/B_m.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">'MyProject-Swift.h' file not found</td></tr>
</tbody></table>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br />When I originally found out about this (somewhere during the early days of Xcode 6), I was helpless and devastated.</span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">There were only 3 workarounds I could think of and apply to my projects:</span><br />
<br />
<ol>
<li><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">Not importing "MyProject-Swift.h", and therefore having to use tricks like </span><span style="font-family: Courier New, Courier, monospace;">NSClassFromString(@"C")</span><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"> and </span><span style="font-family: Courier New, Courier, monospace;">performSelector </span><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">- </span><span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"><i>UGLY as hell</i></span></li>
<li><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">Removing B.m from the Test target (by unchecking the target in the "Target Membership" section of the File Inspector) - <i>Might work for certain cases, but as you see in my example, this means ATest can't compile as it uses A that uses B (that uses Swift code). So if I have enough coverage in my unit tests this is hopeless.</i></span><span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"><i> </i></span></li>
<li><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">Porting the whole project to Swift - <i>Too expensive</i>.</span></li>
</ol>
<br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">This essentially meant that I used swift only for very isolated features in my project, which was very upsetting.</span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">The reason I originally came to the conclusion that it can't be fixed and there aren't any other workarounds, apart from banging my head for a long time about it without success, was an <a href="http://stackoverflow.com/a/24933328/414037">answer on SO</a> basically saying that Apple declared it's a known issue.</span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">In a weird coincidence, just several hours before I decided I should tackle this issue again, <a href="http://stackoverflow.com/a/30494448/414037">a new answer</a> was posted to the same question. </span><span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;">It didn't quite solve my problem (I think it's because I didn't move to Xcode 6.3 yet for the problematic project), but it gave me the hope and the direction to a solution!</span><br />
<br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><u>The Solution</u></span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">What essentially happens, is that the name of the generated header file that contains all the exported classes from Swift to Objective-C, is called "${PRODUCT_MODULE_NAME}-Swift.h"</span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">What's ${PRODUCT_MODULE_NAME}? By default, Xcode sets it to be the same as the ${TARGET_NAME}, meaning: MyProject-Swift.h for the App target, and MyProjectTests-Swift.h for the test target.</span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">So, we could use some </span><span style="font-family: Courier New, Courier, monospace;">#ifdef </span><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">statements each time we want to include the generated Swift header, but this is a terrible solution. Instead, I manually changed the product module name the following way:</span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkTvvhjJXdWeZKAUQ6xZwoV_zWgs-iQ0FSL40q0RCX-eeIOojpAI6ihk8K24dWOf08iJqo-MGs7de9on1fePGDUSVOsKOsR2jUbTI3jvToubWjl3AH7wp5Lpp4MhyphenhyphenIBj1cjcx0y-4JAE4/s1600/MyProject_xcodeproj.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="186" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkTvvhjJXdWeZKAUQ6xZwoV_zWgs-iQ0FSL40q0RCX-eeIOojpAI6ihk8K24dWOf08iJqo-MGs7de9on1fePGDUSVOsKOsR2jUbTI3jvToubWjl3AH7wp5Lpp4MhyphenhyphenIBj1cjcx0y-4JAE4/s640/MyProject_xcodeproj.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">PRODUCT_MODULE_NAME = "MyProject"</td></tr>
</tbody></table>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">That's it. For the example project I created for this post it was all I needed to do for solving the problem.</span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">In my real project however, possibly because it was created with an older version of Xcode, I had another issue that I thought was worth mentioning - an issue of Xcode suddenly not running my <b>Swift</b> unit tests (CTest.swift in this example). It was complaining about not finding XCTestCase in the generated MyProject-Swift.h file.</span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">What eventually solved it for me, is adding an XCTest import in my "MyProjectTests-Bridging-Header.h" file in the following way:</span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQHb8c9OixPnZxR82kv76Ev0ax5VYhl6kRzBjqHZ8jg59yeJolPz82CDdyDM05GMVkxxAz6hP7WvE3PTd1SawjxoY0JsKaDZV_hnjPWnlsG1SnjvZt4CL7Lr2S143ytvtsVfCbtKBcEzs/s1600/MyProjectTests-Bridging-Header_h.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="49" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQHb8c9OixPnZxR82kv76Ev0ax5VYhl6kRzBjqHZ8jg59yeJolPz82CDdyDM05GMVkxxAz6hP7WvE3PTd1SawjxoY0JsKaDZV_hnjPWnlsG1SnjvZt4CL7Lr2S143ytvtsVfCbtKBcEzs/s400/MyProjectTests-Bridging-Header_h.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><div style="text-align: start;">
Add #import <XCTest/XCTest.h> to MyProjectTests-Bridging-Header.h</div>
</td></tr>
</tbody></table>
<br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">And that's it - problem solved.</span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span>
<u><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">BTW</span></u><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">If you are having problems with the other way around (Swift code importing Objective-C code in Unit Tests), I recommend reading <a href="http://iosunittesting.com/testing-mixed-swift-objective-c-code/">the following post</a>.</span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">Also, if you have found this post interesting, you should <a href="http://twitter.com/theyonibomber">follow me on twitter</a> and <a href="http://mobileandbeer.com/">listen to my podcast</a> (in Hebrew).</span>Anonymoushttp://www.blogger.com/profile/06100813770559493046noreply@blogger.com15tag:blogger.com,1999:blog-3833072356413502019.post-81537679485852418012014-12-01T17:04:00.000+02:002015-05-29T13:43:10.134+03:00Why I think Swift is not ready yet<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: Times; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; margin: 0px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px;">
</div>
<div>
</div>
<br />
<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: Times; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px;">
<div style="margin: 0px;">
<u style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif; font-weight: bold;">UPDATE Feb '15:</u><span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"> With Xcode 6.3, Apple fixed some of the issues this post is talking about. However - there are still some major issues for me, the number one of them is the fact I can't use Swift classes in Objective-C without porting the tests for them to Swift.</span></div>
<div style="margin: 0px;">
<span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"><br /></span></div>
</div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">So,</span><br />
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">Like every relatively-early-adpoter-iOS-developer, I decided to give Swift a try in the past few features I worked on for <a href="https://88608.api-03.com/serve?action=click&publisher_id=88608&site_id=68692&offer_id=321678&my_campaign=yoni&my_site=codersheriff.blogspot.co.il">Piano Maestro</a>.</span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">It was a lot of fun to get into, and I wrote some pretty code and features came out very nice. However, </span><span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;">I ran into some issues, that made me eventually come to the conclusion that swift isn't quite ready yet, and I should stick to Objective-C as the main language for developing iOS apps. At least for now.</span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">Here are my top reasons:</span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<b><u><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif; font-size: large;">Inaccuracies in compilation errors</span></u></b></div>
<div>
<span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;">Often, when a line is relatively complex and has a compilation error, compiler will give you an error message that's simply not describing the real issue.</span></div>
<div>
<br />
<span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;">The most common use case is a simple error like sending the wrong primitive type as an argument to a function (a problem that happens a lot to us Objective-C/C/C++ developers, which are used to implicit conversion of primitives).</span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">Consider the following example:</span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidzbozkmMK9EPkuLqzO2TieRLYVh7FjjpHom-7SSq1CXMVf5jDxO1UGynX4toz95WNOHy_KfV3D4JJptqbvxgIcikz_g4Px_7HrfvBwDmKaLgF8d-5ickckw8xkQcakgzO9N0T0b-kPJ8/s1600/PPSwiftUtils_swift_%E2%80%94_Edited.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><img border="0" height="64" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidzbozkmMK9EPkuLqzO2TieRLYVh7FjjpHom-7SSq1CXMVf5jDxO1UGynX4toz95WNOHy_KfV3D4JJptqbvxgIcikz_g4Px_7HrfvBwDmKaLgF8d-5ickckw8xkQcakgzO9N0T0b-kPJ8/s1600/PPSwiftUtils_swift_%E2%80%94_Edited.png" width="640" /></span></a></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">WAT??</span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">dispatch_after receives exactly these types arguments. So what's wrong here?</span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">Turns out the problem is that dispatch_time expects Int64 to be sent as the second argument, and I actually sent NSTimeInterval.</span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">But how could I know that from that irrelevant error message?</span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">There went an hour of banging my head until I figured this out.</span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span>
<br />
<div>
<u style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif; font-weight: bold;">UPDATE Feb '15:</u><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"> at least for this example, was fixed in Xcode 6.3 Beta 1 and error message is now very descriptive and relevant.</span></div>
<br />
<div>
</div>
<br />
<div style="-webkit-text-stroke-width: 0px; color: black; font-family: Times; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px;">
<span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"><br /></span></div>
</div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<b><u><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif; font-size: large;">Debugging is hard</span></u></b></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">More head banging often happened when trying to see the value of a variable in the debugger, I eventually find myself adding debug prints instead.</span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">A tip about this: If you get "</span><span style="font-family: Courier New, Courier, monospace;">Some</span><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">" as the output of trying to '</span><span style="font-family: Courier New, Courier, monospace;">po var</span><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">', you can '</span><span style="font-family: Courier New, Courier, monospace;">po print(var)</span><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">' instead, and it will (hopefully) work.</span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">See <a href="http://stackoverflow.com/questions/24232976/how-do-i-list-po-the-contents-of-a-swift-array">http://stackoverflow.com/questions/24232976/how-do-i-list-po-the-contents-of-a-swift-array</a></span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<b><u><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif; font-size: large;">Can't use Swift code within Objective-C in unit tests</span></u></b></div>
</div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><b>Update May 2015:</b> <a href="http://codesheriff.blogspot.co.il/2015/05/importing-swift-code-from-objective-c.html">I found workaround!</a></span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">While it's absolutely possible to mix Swift <-> Objective-C code in the app's main target (apart for some limitations I will rant about later), in the test target, I can't import </span><span style="background-color: #eeeeee; line-height: 17.804800033569336px;"><span style="font-family: Courier New, Courier, monospace;">$(PRODUCT_MODULE_NAME)-Swift.h</span></span><span style="background-color: white; font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif; line-height: 17.804800033569336px;"> in Objective-C code.</span></div>
<div>
<span style="background-color: white;"><span style="line-height: 17.804800033569336px;"><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">This does not only mean that tests for Swift classes can only be written in Swift (fair enough), it also means that any Objective-C code in my app that uses Swift classes cannot be tested at all. Build will fail if it's included in the test target of the project.</span></span></span></div>
<div>
<span style="background-color: white;"><span style="line-height: 17.804800033569336px;"><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">LAME.</span></span></span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">See:</span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><a href="http://stackoverflow.com/a/24933328/414037">Relevant answer in StackOverflow</a></span></div>
<div>
<a href="https://developer.apple.com/library/ios/documentation/swift/conceptual/BuildingCocoaApps/MixandMatch.html"><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">Swift and Objective-C in the Same Project</span></a></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<div>
<b><u><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif; font-size: large;">Can't use tuples and trivial enums in Objective-C</span></u></b></div>
</div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">As the official documentation says, you can't use <span style="background-color: white; color: #414141; line-height: 20.299999237060547px;">Swift-only features in your Objective-C code.</span></span></div>
<div>
<span style="background-color: white; color: #414141; font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif; line-height: 20.299999237060547px;">This makes sense for some things, but it would make a huge difference if they could have made an effort to expose some of the more trivial features in the </span><span style="background-color: #eeeeee; line-height: 17.804800033569336px;"><span style="font-family: Courier New, Courier, monospace;">$(PRODUCT_MODULE_NAME)-Swift.h</span></span><span style="background-color: white; font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif; line-height: 17.804800033569336px;"> bridge</span><span style="background-color: white; color: #414141; font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif; line-height: 20.299999237060547px;">:</span></div>
<div>
<span style="background-color: white; color: #414141; line-height: 20.299999237060547px;"><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">- Trivial enums can become C enums with a prefix (like it's done in the opposite direction)</span></span></div>
<div>
<span style="background-color: white; color: #414141; line-height: 20.299999237060547px;"><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">- Tuples can become trivial classes</span></span></div>
<div>
<span style="background-color: white; color: #414141; line-height: 20.299999237060547px;"><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">etc.</span></span><br />
<span style="background-color: white; color: #414141; font-family: Helvetica Neue, Arial, Helvetica, sans-serif; line-height: 20.299999237060547px;">For now, I can't expose functions that receive a tuple or a Swift enum to Objective-C, and must add some kind of bridge myself (e.g. get an </span><span style="background-color: white; color: #414141; font-family: Courier New, Courier, monospace; line-height: 20.299999237060547px;">Int</span><span style="background-color: white; color: #414141; font-family: Helvetica Neue, Arial, Helvetica, sans-serif; line-height: 20.299999237060547px;"> parameter instead of an enum and </span><span style="background-color: white; color: #414141; font-family: Helvetica Neue, Arial, Helvetica, sans-serif; line-height: 20.299999237060547px;">use the constructor with </span><span style="background-color: white; color: #414141; font-family: Courier New, Courier, monospace; line-height: 20.299999237060547px;">rawValue:</span><span style="background-color: white; color: #414141; font-family: Helvetica Neue, Arial, Helvetica, sans-serif; line-height: 20.299999237060547px;">). </span></div>
<div>
<span style="background-color: white; color: #414141; line-height: 20.299999237060547px;"><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">Maybe it was too much of an effort for Apple to deal with, but t</span></span><span style="background-color: white; color: #414141; font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif; line-height: 20.299999237060547px;">his makes it harder to use these features if I know the class will be used in Objective-C code.</span></div>
<div>
<b><u><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span></u></b>
<u style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif; font-weight: bold;">UPDATE Feb '15:</u><span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"> you can now use trivial enums!</span><br />
<b><u><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span></u></b></div>
<div>
<b><u><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif; font-size: large;">Can't use c++ in Swift</span></u></b></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">If like us, your app uses Objective-C++ code and not only Objective-C, you're in trouble and won't be able to use any code that uses c++ types in the header. You'll have to create some kind of Objective-C bridge that will hide the c++ types.</span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">See: <a href="http://stackoverflow.com/questions/24042774/can-i-mix-swift-with-c-like-the-objective-c-mm-files">http://stackoverflow.com/questions/24042774/can-i-mix-swift-with-c-like-the-objective-c-mm-files</a></span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<b><u><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif; font-size: large;">Can't use mocking frameworks</span></u></b></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">Because of limitations in the availability of the language runtime in Swift, there's no good way to use a mocking framework for tests right now. That's a big problem.</span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">In the meanwhile - best workaround IMO is adding an Inner Class called "MockMyClass" in your test, and overriding any methods you want to mock (like we did in 2006 before mocking frameworks were introduced).</span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">See:</span></div>
<div>
<a href="http://ocmock.org/swift/"><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">http://ocmock.org/swift/</span></a></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<b><u><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif; font-size: large;">Xcode sucks, AppCode has only limited support</span></u></b></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">So, as you probably know from my <a href="http://codesheriff.blogspot.co.il/2012/02/xcode-vs-appcode.html">Xcode vs AppCode comparison</a> (a bit outdated, but most of it still applies), I don't use Xcode for coding. It's lacking some very basic IDE mechanisms that AppCode is excellent at (e.g. Extract Method, Quick Fix, Find Usages, ...).</span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">This is still true for Xcode 6.1 and Swift support. Sure, Xcode improved since writing this comparison, but still - I can't even extract method? This sucks.</span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">Unfortunately, Swift support in AppCode is still very rudimentary. But the good news is that they are working on it.</span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">In the meanwhile, here's a link to <a href="http://confluence.jetbrains.com/display/OBJC/AppCode+EAP">AppCode EAP</a> that contains some basic features of syntax highlighting and some basic refactoring in Swift. I still don't recommend it over Xcode's current Swift support though.</span><br />
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span>
<u style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif; font-weight: bold;">UPDATE Feb '15:</u><span style="font-family: 'Helvetica Neue', Arial, Helvetica, sans-serif;"> AppCode 3.x has basic Swift support, but still has a very long way to go in order to be as good as it is for Objective-C in terms of refactoring etc.</span></div>
<h2>
<b><u><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif; font-size: x-large;">To sum it up</span></u></b></h2>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">I guess things are not that bad, because Swift is a very neat language and has some really cool features I'm in love with, like <a href="https://developer.apple.com/library/ios/documentation/swift/conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-XID_494">tuples</a>, <a href="https://developer.apple.com/library/ios/documentation/swift/conceptual/Swift_Programming_Language/Enumerations.html#//apple_ref/doc/uid/TP40014097-CH12-XID_221">better enums</a>, <a href="https://developer.apple.com/library/ios/documentation/swift/conceptual/Swift_Programming_Language/Closures.html#//apple_ref/doc/uid/TP40014097-CH11-XID_151">cooler closures</a>, <a href="https://developer.apple.com/library/ios/documentation/swift/conceptual/Swift_Programming_Language/Generics.html#//apple_ref/doc/uid/TP40014097-CH26-XID_275">generics</a>, <a href="https://developer.apple.com/library/ios/documentation/swift/conceptual/Swift_Programming_Language/Properties.html#//apple_ref/doc/uid/TP40014097-CH14-XID_390">property observers</a>, and many many more. </span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">I assume my complaints are either going to be solved soon, or become less of an issue - many of them are mix&match issues, which only affect apps with existing Objective-C/C++ code. Hopefully</span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">Anyhow, at least for the time being, I guess I'll stick with Objective-C as the main iOS development language.</span></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><br /></span></div>
<div>
<u><b><span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;">Further reading:</span></b></u></div>
<div>
<span style="font-family: Helvetica Neue, Arial, Helvetica, sans-serif;"><a href="http://artsy.github.io/blog/2014/11/13/eidolon-retrospective">Developing a Bidding Kiosk for iOS in Swift</a> - a great retrospective with some more reasons of why Swift isn't ready yet.</span></div>
<div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/06100813770559493046noreply@blogger.com18tag:blogger.com,1999:blog-3833072356413502019.post-84689594186828388812014-03-13T18:25:00.001+02:002014-03-15T19:50:16.985+02:008 Tips for working effectively with Interface Builder<div class="p1">
<b><u><span style="font-family: Times, Times New Roman, serif;">Introduction</span></u></b><br />
<span style="font-family: Times, Times New Roman, serif;">While working at <a href="http://www.joytunes.com/"><span class="s1">JoyTunes</span></a> on the latest versions of <a href="http://bit.ly/1dVSGNG" target="_blank">our top-notch piano app</a>, we've done a great deal of UI redesign and therefore had to spend long hours with the notorious Interface Builder, resizing images and views, which can be a lot of frustrating work.</span></div>
<div class="p1">
<span style="font-family: Times, Times New Roman, serif;">During this work, we actually discovered a great deal of neat IB tricks, and I decided I must share them with the world.</span></div>
<div class="p1">
<span style="font-family: Times, Times New Roman, serif;">So I conducted this little post of my 8 greatest tips for working effectively with IB.</span></div>
<div class="p2">
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div class="p1">
<span style="font-family: Times, Times New Roman, serif;">A little disclaimer:</span></div>
<div class="p1">
<span style="font-family: Times, Times New Roman, serif;">In JoyTunes, we work with .xib files (not storyboards), and without Auto Layout. This is mostly for historical reasons. As a result, some of the tips I'm mentioning might react a little differently for you if you're using storyboards or Auto Layout, but most should apply just the same.</span></div>
<div class="p2">
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div class="p1">
<b><u><span style="font-family: Times, Times New Roman, serif;">1. Size to Fit Content</span></u></b></div>
<div class="p1">
<span style="font-family: Times, Times New Roman, serif;">I'm so ashamed I only took the effort to look this up only recently. A HUGE time saver.</span></div>
<div class="p1">
<span style="font-family: Times, Times New Roman, serif;">Select any view and then go to Editor->Size to Fit Content or simply press <b>⌘=</b></span></div>
<div class="p1">
<span style="font-family: Times, Times New Roman, serif;">Will resize the selected view to fit its content in the following manner:</span></div>
<div class="p2">
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<ul class="ul1">
<li class="li1"><span style="font-family: Times, Times New Roman, serif;">An ImageView/Button will be resized to the image's original size (most common usage):</span></li>
</ul>
<div class="separator" style="clear: both; text-align: center;">
</div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMn8CIguhwmAhtlbruxwJaONmrhVGnQrJSHdS4QtsbJre7Tx1mrdIxzHRBvaZbGOpG3gFM7Xb4Tk-mBWyszH2S2neuPPm2pbhhclD-s0ant1dSUIcFbYQ-pPOTaoTPp2ypt-aAwrPVsJ4/s1600/sizeToFitContentImage.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: Times, Times New Roman, serif;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMn8CIguhwmAhtlbruxwJaONmrhVGnQrJSHdS4QtsbJre7Tx1mrdIxzHRBvaZbGOpG3gFM7Xb4Tk-mBWyszH2S2neuPPm2pbhhclD-s0ant1dSUIcFbYQ-pPOTaoTPp2ypt-aAwrPVsJ4/s1600/sizeToFitContentImage.gif" /></span></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<ul class="ul1">
<li class="li1"><span style="font-family: Times, Times New Roman, serif;">A Label/Button will be resized to fit the text it's currently containing:</span></li>
</ul>
<table>
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
</div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span></td><td><div class="separator" style="clear: both; text-align: center;">
</div>
</td></tr>
</tbody></table>
<div class="p2">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihHzM_zH1E_Phz4vICHB2yrN1_1BdIWXvk23n_QotdewxVXVPVJbP6SUfTcktgltAFV4YFgiyLFBBzhdqMAFPi_mdnlXEBS4C7zDXt_ykgkXy66FmLX4i3TOdM4ado-rorMhOsCJPr_f0/s1600/sizeToFitContentLabel.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: Times, Times New Roman, serif;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihHzM_zH1E_Phz4vICHB2yrN1_1BdIWXvk23n_QotdewxVXVPVJbP6SUfTcktgltAFV4YFgiyLFBBzhdqMAFPi_mdnlXEBS4C7zDXt_ykgkXy66FmLX4i3TOdM4ado-rorMhOsCJPr_f0/s1600/sizeToFitContentLabel.gif" /></span></a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
</div>
<ul class="ul1">
<li class="li1"><span style="font-family: Times, Times New Roman, serif;">A parent container view to fit the frames of its subviews.</span></li>
</ul>
<table>
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
</div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span></td>
<td><div class="separator" style="clear: both; text-align: center;">
</div>
</td></tr>
</tbody></table>
<div class="p2">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirST04ikMX8Y9tIjI9yINJHL2vaWTviCTH6Rd7M8Fy6gQnFv1F7q-GPTaSvXpSvZW5iZy3JcJ8Oz28NXdZ3yCzPg0j-V93rWyYu0SCdq6nZDV1Do3sSL4J9B-sMBm4EOqGXQyEWfzAvDo/s1600/sizeToFitContentView.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: Times, Times New Roman, serif;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirST04ikMX8Y9tIjI9yINJHL2vaWTviCTH6Rd7M8Fy6gQnFv1F7q-GPTaSvXpSvZW5iZy3JcJ8Oz28NXdZ3yCzPg0j-V93rWyYu0SCdq6nZDV1Do3sSL4J9B-sMBm4EOqGXQyEWfzAvDo/s1600/sizeToFitContentView.gif" /></span></a></div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div class="p1">
<b><u><span style="font-family: Times, Times New Roman, serif;">2. Holding option key to view distance from another view's edges</span></u></b></div>
<span style="font-family: Times, Times New Roman, serif;">Holding option key after selecting a view, and then hovering over some other view, will show you cool distance indicators from that view's edges:
</span><br />
<table>
<tbody>
<tr>
<td><div class="separator" style="clear: both; text-align: center;">
</div>
</td><td><div class="separator" style="clear: both; text-align: center;">
</div>
</td><td><div class="separator" style="clear: both; text-align: center;">
</div>
</td></tr>
</tbody></table>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZL1E69YBpGZReMMdT86wQULwAhIgM4bphyphenhyphen4pjRb91z8eD-7CE-VXSs1GlE80O993MURDAHiAceQ9_cbzYFX2sQlfEv9q2do1XuaSBLDu7bIlnZjqrQTXmvNFPj4SbsLaSBUEVrKEY3NQ/s1600/holdOption.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: Times, Times New Roman, serif;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZL1E69YBpGZReMMdT86wQULwAhIgM4bphyphenhyphen4pjRb91z8eD-7CE-VXSs1GlE80O993MURDAHiAceQ9_cbzYFX2sQlfEv9q2do1XuaSBLDu7bIlnZjqrQTXmvNFPj4SbsLaSBUEVrKEY3NQ/s1600/holdOption.gif" /></span></a></div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<br />
<div class="p3">
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div class="p1">
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<br />
<div class="p1" style="-webkit-text-stroke-width: 0px; color: black; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px;">
</div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<br />
<div class="p1" style="-webkit-text-stroke-width: 0px; color: black; font-style: normal; font-variant: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px;">
<div style="margin: 0px;">
<b><u><span style="font-family: Times, Times New Roman, serif;">3. Editor -> Embed In View, Unembed:</span></u></b><br />
<div style="font-weight: normal;">
<span style="font-family: Times, Times New Roman, serif;">Do you know that annoying feeling when you have some subviews all located and then you decide they need to have a different parent view, or even a different .xib, and then they are all automatically get located in the center of the new view?</span></div>
<div style="font-weight: normal;">
<span style="font-family: Times, Times New Roman, serif;">Well - here's the solution:</span></div>
</div>
<div style="font-weight: normal; margin: 0px;">
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<br />
<div class="separator" style="clear: both; font-size: medium; text-align: center;">
</div>
<div class="separator" style="clear: both; font-size: medium; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhA6DWljbH_pNfFMsZcNKrjaOrGjooCxGai_BJ23roOSqs_pmrjmvaV5RwWI1vXMBlfmI75nsFygHcp-EGgcXVHCGN7ByJN4dYCXBoOhMZb8pX5OpEpTaFG3e3lI0OpiuXVBYIKOnMAm34/s1600/embed.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: Times, Times New Roman, serif;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhA6DWljbH_pNfFMsZcNKrjaOrGjooCxGai_BJ23roOSqs_pmrjmvaV5RwWI1vXMBlfmI75nsFygHcp-EGgcXVHCGN7ByJN4dYCXBoOhMZb8pX5OpEpTaFG3e3lI0OpiuXVBYIKOnMAm34/s1600/embed.gif" /></span></a></div>
<div style="font-size: medium;">
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
</div>
</div>
</div>
<div class="p1">
<b><u><span style="font-family: Times, Times New Roman, serif;">4. Adding padding to freeform sized view without affecting subview's positions</span></u></b><br />
<span style="font-family: Times, Times New Roman, serif;">When trying to add padding to a view, the x's and y's of the subview is retained, which isn't always what you want.</span><br />
<span style="font-family: Times, Times New Roman, serif;">The best way I found to get past this, is to drag the edges while holding ⌘:</span><br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_ZQXwQDC8PW_jy60wjVIPdIM1awnWXef_y4DUDnFPOBynW0UCLd-7Bsh3NncxiZaVklsIDC1ub966QBNho6X_h5a0a01DFejNdIIsRvJiNXI55NS0vU9oTWSTSfCdHChyiUNueFPgO0A/s1600/drag_to_resize.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: Times, Times New Roman, serif;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_ZQXwQDC8PW_jy60wjVIPdIM1awnWXef_y4DUDnFPOBynW0UCLd-7Bsh3NncxiZaVklsIDC1ub966QBNho6X_h5a0a01DFejNdIIsRvJiNXI55NS0vU9oTWSTSfCdHChyiUNueFPgO0A/s1600/drag_to_resize.gif" height="224" width="320" /></span></a></div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div class="p1">
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div class="p1">
<b><u><span style="font-family: Times, Times New Roman, serif;">5. Move a view that isn't in the front:</span></u></b><br />
<span style="font-family: Times, Times New Roman, serif;">One thing that bugs me when working with IB, is the inability to move views that aren't in front easily.</span><br />
<span style="font-family: Times, Times New Roman, serif;">One way to do so will be to temporary bring it to front and then bring it back, but this is annoying.</span><br />
<span style="font-family: Times, Times New Roman, serif;">Another way will be to use the size inspector on the right panel, which is fine but could take some guessing and adjustments until you get it right.</span><br />
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<span style="font-family: Times, Times New Roman, serif;">A way I found of moving a view with the arrow keys without bringing it to front is this:</span><br />
<span style="font-family: Times, Times New Roman, serif;">1. Choose the view on the document outline.</span><br />
<span style="font-family: Times, Times New Roman, serif;">2. Click on the frame of the root view in order to gain focus.</span><br />
<span style="font-family: Times, Times New Roman, serif;">3. Move with arrow keys.</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRFXToYsxeG18iUIbBPZxI2f1nooSlCPAUXCimImkRabKdszBFft84S9276g-u-l3E04Slhs7cpXjuAdbEGoQsV5YxFyAbS33X_SidRTxsX-A6YdyzlnkYwdkgrqqOluj9bpIUq58qsRs/s1600/move_view_in_back.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: Times, Times New Roman, serif;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRFXToYsxeG18iUIbBPZxI2f1nooSlCPAUXCimImkRabKdszBFft84S9276g-u-l3E04Slhs7cpXjuAdbEGoQsV5YxFyAbS33X_SidRTxsX-A6YdyzlnkYwdkgrqqOluj9bpIUq58qsRs/s1600/move_view_in_back.gif" height="457" width="640" /></span></a></div>
<span style="font-family: Times, Times New Roman, serif;"><b>EDIT:</b></span><br />
<span style="font-family: Times, Times New Roman, serif;">Some other (better) way of gaining focus, taken from the comments to this post:</span><br />
<br />
<ul>
<li><span style="font-family: Times, Times New Roman, serif;"><span style="background-color: white; color: #333333; line-height: 14.5600004196167px; text-align: justify;">If you double-click a view in the outline, it will switch focus to the layout pane with that view selected.</span></span></li>
<li><span style="font-family: Times, Times New Roman, serif;"><span style="background-color: white; color: #333333; line-height: 14.5600004196167px; text-align: justify;">Shift+Right(Ctrl) Click over the view in IB and you'll see a menu of all the views that exist where you've clicked.</span></span></li>
</ul>
<span style="font-family: Times, Times New Roman, serif;"><br /></span></div>
<div class="p1">
<b><u><span style="font-family: Times, Times New Roman, serif;">6. IBOutletCollection ordering</span></u></b></div>
<div class="p1">
<span style="font-family: Times, Times New Roman, serif;">Often, the order of IBOutletColletions is important to us, and we want to iterate on them in code in that order.</span><br />
<span style="font-family: Times, Times New Roman, serif;">One way of doing it is sorting them in code by their x/y/tag, and then iterate.</span><br />
<span style="font-family: Times, Times New Roman, serif;">This is unnecessary. The order of connection is determined by the order in which we dragged the connection, and we can see the current order if by ⌃+Clicking the File's Owner:</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVfceQ8yxMu7w5WoM-wKNrf9WZ_BXlvpK_PvBsIC2GzDhtyJPtIvU156m_G5k9FFTkPogFYhoTCKEuRINClkd9Iz8jsZWhHrWu8XP5feuSNMJR58TeMhK-c7J0QXz_nm8tuYhdw4eKYaQ/s1600/IBOutletCollection.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: Times, Times New Roman, serif;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVfceQ8yxMu7w5WoM-wKNrf9WZ_BXlvpK_PvBsIC2GzDhtyJPtIvU156m_G5k9FFTkPogFYhoTCKEuRINClkd9Iz8jsZWhHrWu8XP5feuSNMJR58TeMhK-c7J0QXz_nm8tuYhdw4eKYaQ/s1600/IBOutletCollection.gif" height="248" width="640" /></span></a></div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<b><u><span style="font-family: Times, Times New Roman, serif;">7. Use custom properties </span></u></b><br />
<span style="font-family: Times, Times New Roman, serif;">I think a relatively underused feature of IB is the ability to set custom properties on views, using the "User Defined Runtime Attributes" of the Identity inspector:</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiMrpfH3U5dLSM9NS87QE_Id7kLsrGhP6AFHEoEyrW_EP65G5R-nA0IE12sGdzP9MU3J4fC7CrwiWrttQHl0m7EUDtcVtH2T8PQFRLLNnjwLWPlUbLbijIibtcVpw1_h0TuPjLTM8Zfwk/s1600/PianoPlatform_%E2%80%94_PPRateUsViewController_xib_%E2%80%94_Edited.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: Times, Times New Roman, serif;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiMrpfH3U5dLSM9NS87QE_Id7kLsrGhP6AFHEoEyrW_EP65G5R-nA0IE12sGdzP9MU3J4fC7CrwiWrttQHl0m7EUDtcVtH2T8PQFRLLNnjwLWPlUbLbijIibtcVpw1_h0TuPjLTM8Zfwk/s1600/PianoPlatform_%E2%80%94_PPRateUsViewController_xib_%E2%80%94_Edited.gif" /></span></a></div>
<span style="font-family: Times, Times New Roman, serif;"><span id="goog_824992998"></span><span id="goog_824992999"></span><br /></span>
<span style="font-family: Times, Times New Roman, serif;">As you can probably guess, we defined a JTLabel class that you can set stroke color and width to, and this is our way of immediately setting this without having to write any code.</span><br />
<span style="font-family: Times, Times New Roman, serif;">Another common hack that can be applied this way is setting "layer.cornerRadius" of any view, to make it have rounded corners.</span><br />
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<span style="font-family: Times, Times New Roman, serif;">A relevant tool that uses this mechanism is <a href="http://canvaspod.io/" target="_blank">Canvas</a>, which will let you define animations for views without writing code.</span><br />
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<b><span style="font-family: Times, Times New Roman, serif;">Important warning regarding this that saved my life on one occasion:</span></b><br />
<div class="p1">
<span style="font-family: Times, Times New Roman, serif;">In your implementation class you cannot use <span class="s1">initWithCoder:</span> otherwise your key-value path setting will not be picked up. You will have to do all your implementation within <span class="s1">awakeFromNib.</span></span></div>
<div class="p1">
<span style="font-family: Times, Times New Roman, serif;">(Credit to <a href="http://www.wannabegeek.com/?p=395">http://www.wannabegeek.com/?p=395</a>)</span></div>
</div>
<div class="p2">
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<b><u><span style="font-family: Times, Times New Roman, serif;">8. MoarFonts - custom fonts WYSIWYG</span></u></b><br />
<span style="font-family: Times, Times New Roman, serif;">Custom fonts have always been a big issue when working with Interface Builder.</span><br />
<span style="font-family: Times, Times New Roman, serif;">There's no built-in support for those, and the best solutions I have seen were either using custom properties solutions like <a href="http://canvaspod.io/" target="_blank">Canvas</a>, or using font replacing techniques like <a href="https://github.com/deni2s/IBCustomFonts" target="_blank">IBCustomFonts</a>. These are valid solutions, but they have a great downside - they don't give you a full WYSIWYG experience, which is exactly why you are using Interface Builder in the first place.</span><br />
<span style="font-family: Times, Times New Roman, serif;">It can be very annoying to place a label with a placeholder font and then having to run the app in order to discover that the width you gave it doesn't fit well with your replacing custom font.</span><br />
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<span style="font-family: Times, Times New Roman, serif;">Lately I stumbled upon this solution called <a href="http://pitaya.ch/moarfonts/" target="_blank">MoarFonts</a>. It costs 10$, and there's no demo or trial - but trust me, it's totally worth it!</span><br />
<span style="font-family: Times, Times New Roman, serif;">It's a pretty simple setup: you'll have to build your app with MoarFonts as a script build phase, restart Xcode, and voila! You can see custom fonts in InterfaceBuilder:</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqNsh-YrfmyO_rkjKO8G48P6sx_sDgkSwcRQrgo3GtCHI2lX443fG0b9BSxAcoC7yO22UYSip3F1XndGM1FuAk-57dphpR7l5wyHfdxVJe4CJtP64Z0a1eIiOdKY0Usum3xCFmTRZqRiU/s1600/moarfonts.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><span style="font-family: Times, Times New Roman, serif;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqNsh-YrfmyO_rkjKO8G48P6sx_sDgkSwcRQrgo3GtCHI2lX443fG0b9BSxAcoC7yO22UYSip3F1XndGM1FuAk-57dphpR7l5wyHfdxVJe4CJtP64Z0a1eIiOdKY0Usum3xCFmTRZqRiU/s1600/moarfonts.png" height="400" width="640" /></span></a></div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<b><span style="font-family: Times, Times New Roman, serif;">That's it!</span></b><br />
<span style="font-family: Times, Times New Roman, serif;">I hope at least some of the tips were something you didn't know.</span><br />
<span style="font-family: Times, Times New Roman, serif;">If you have any other tips you think I should add to the list, or if you have a better way to achieve some of the stuff I was trying to solve, please send me a tweet (<a href="http://twitter.com/theyonibomber" target="_blank">@theyonibomber</a>).</span></div>
<span style="font-family: Times, Times New Roman, serif;"><br /></span>
<br />
<div class="p1">
<span style="font-family: Times, Times New Roman, serif;">Also, you should listen to <a href="http://mobileandbeer.com/" target="_blank">my podcast</a> about mobile development & beer (in Hebrew).</span></div>
Anonymoushttp://www.blogger.com/profile/06100813770559493046noreply@blogger.com39tag:blogger.com,1999:blog-3833072356413502019.post-63997005326102783672012-09-26T20:12:00.000+02:002014-01-04T13:26:26.641+02:00Using Crittercism SDK to effectively find & fix crashes<div>
<span style="font-size: x-small;">This post is talking about iOS apps, but I'm sure most of it applies to Android as well...</span></div>
<div>
<div>
<br />
Having a crash report framework for your app is not really optional.</div>
</div>
<div>
<br /></div>
<div>
While investing in the QA phase before submitting your app can find and eliminate a lot of the crashes, there will always be something you'll miss, and there's nothing like millions of potential users to help you find and fix these annoying crashes when they happen.<br />
<br /></div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioOoPz4X5GNi4rVrZ-_nbLwg3AEJ7eliLp1NnS6F-OdhA25xtpIjNwqNxfv7W3kjqk535On6xRJCReA4VDsi5PR2jSFy8qk5YQgNfSjHfFXAXKPHfyBwRto-1rkbzMLdSMlG-gTp4f05s/s1600/crittercism.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="66" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioOoPz4X5GNi4rVrZ-_nbLwg3AEJ7eliLp1NnS6F-OdhA25xtpIjNwqNxfv7W3kjqk535On6xRJCReA4VDsi5PR2jSFy8qk5YQgNfSjHfFXAXKPHfyBwRto-1rkbzMLdSMlG-gTp4f05s/s320/crittercism.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<a href="https://www.crittercism.com/" target="_blank"><b>Crittercism</b></a> is a great example of a framework that makes sure you are going to get all the needed data from your users, AND may also be very helpful during the development & QA phase (in case you are not connected with a debugger and an exception breakpoint and a crash occurred).</div>
<div>
<br /></div>
<div>
The framework is really simple to use and the documentation is very succinct, so I'm not going to elaborate too much about the basic integration and features (such as symbolicated stack traces for each crash), but I DO want to tell you about some of <b>my favorite features</b> in the framework, that got us at JoyTunes to choose and use it for our iOS apps.</div>
<div>
<br />
<a name='more'></a><br /></div>
<div>
<h2>
1. Live Data</h2>
</div>
<div>
This is a feature that is actually useful for app analytics regardless of crash monitoring, and it behaves much better than similar features in many analytics frameworks do.<br />
<br />
You get live stats of how many app loads and how many of them crashed (filterable by app version).<br />
This is cool because you can use it for live monitoring of app loads when an event occurs like a broadcast push notification.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWUOz5eljG2iOQNjin-GPDUv7vQfR4YctqbZhtApMD8c_JKRLc8XyJeKiy6fMzj6z2NUqP6ej1aTSMyQz7roCnhcpIgaGoMfCtQVTcBxQDH2mJ-QghIEvX9qyUZ3Ojo1bFG9ubzbZY2FA/s1600/Crittercism+-+Live+Stats.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="312" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWUOz5eljG2iOQNjin-GPDUv7vQfR4YctqbZhtApMD8c_JKRLc8XyJeKiy6fMzj6z2NUqP6ej1aTSMyQz7roCnhcpIgaGoMfCtQVTcBxQDH2mJ-QghIEvX9qyUZ3Ojo1bFG9ubzbZY2FA/s400/Crittercism+-+Live+Stats.jpg" width="400" /></a></div>
<br />
<br /></div>
<div>
In the same category, it's worth mentioning that new crashes appear in the list (and you get an e-mail) immediately as they happen. Especially useful for the QA phase when you don't have to wait hours to view the stack trace of a crash.</div>
<div>
<br /></div>
<div>
<h2>
2. Crash Trends</h2>
Another great app analytics related feature. You can watch graphs of your DAU, MAU, App Loads, etc.<br />
The most useful graph is the % of app loads that crashed, with separates graphs per app version.<br />
This is really useful to make sure that you lowered the percentage by fixing crashes in certain versions, and make sure the new features you added didn't raise the percentage...<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEm2vMrYLK5hVGZQsLmvwv6aXntCBtiabDQlQyHtdaD7UjmhetIWwksSSzawC7J0HFN3CUZt79LXGc0dU0Arj4rmfJigzdxNSimSFb6qrkVGN7tBXF6W5-SbzEsHRn3Wkzp6TsYlzsZnI/s1600/Crittercism+-+Crash+Trends-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="186" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEm2vMrYLK5hVGZQsLmvwv6aXntCBtiabDQlQyHtdaD7UjmhetIWwksSSzawC7J0HFN3CUZt79LXGc0dU0Arj4rmfJigzdxNSimSFb6qrkVGN7tBXF6W5-SbzEsHRn3Wkzp6TsYlzsZnI/s400/Crittercism+-+Crash+Trends-1.jpg" width="400" /></a></div>
<br />
<h2>
3. Breadcrumbs</h2>
While often looking at the stack trace alone is enough to understand what is going on and why the crash happened, there will be times you will find yourself staring at the stack trace not getting what were the circumstances that caused this line to crash.<br />
<br />
This is where breadcrumbs kick in.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPsmyCtRP6IgXJLbLWHbUzjZBo8R5jAp03Id93UjbIJy_gfUqfut56brltTj9wUru6l6jmNHKVnZklFe04wkmcCUlgnF2TTFghgtUn9MyupEgN2dJMAej-S8EMvUWkMgXrrLSFFecNQbo/s1600/crittercism-breadcrumbs.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="133" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPsmyCtRP6IgXJLbLWHbUzjZBo8R5jAp03Id93UjbIJy_gfUqfut56brltTj9wUru6l6jmNHKVnZklFe04wkmcCUlgnF2TTFghgtUn9MyupEgN2dJMAej-S8EMvUWkMgXrrLSFFecNQbo/s400/crittercism-breadcrumbs.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
Using breadcrumbs effectively will let you track problematic user paths that may reproduce a crash in your development environment.<br />
<br />
Since we are using Flurry for advanced analytics features, we simply added a method that reports an event both to Flurry and to Crittercism as a breadcrumb, and then we call this method instead of directly calling to the Flurry API.<br />
This way each new flurry event is automatically reported as a breadcrumb as well.<br />
<br />
The only caveat here is that while flurry supports parameters, Crittercism does not, so if parameters are important for you to understand what the user was doing, you should simply append the relevant info to the event's name when sending a breadcrumb.<br />
<br />
<h2>
4. User Metadata</h2>
<div>
By default, Crittercism creates a guest profile for each user of your app, and lets you know what crashes are affecting the same user.</div>
<br />
This is useful by itself, but with User Metadata you get much more!<br />
<br />
You can assign a username, an e-mail, and every other piece of metadata to a Crittercism user, and then you can link crashes analytics to each<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyF35OPpZ6KJA0yE378VwtMSvogFHFMd-RJtgDSB5fRdTQBgha-hr9oMdBF__A_T_kubChCQnWnSZA8KgFKG6gEjvn75FXZtQD3GADjX-TNOUDZszHrZzOU4oRmgPl6VWf1IR_i-i0qMY/s1600/Crittercism+-+User+Details.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="284" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyF35OPpZ6KJA0yE378VwtMSvogFHFMd-RJtgDSB5fRdTQBgha-hr9oMdBF__A_T_kubChCQnWnSZA8KgFKG6gEjvn75FXZtQD3GADjX-TNOUDZszHrZzOU4oRmgPl6VWf1IR_i-i0qMY/s640/Crittercism+-+User+Details.jpg" width="640" /></a></div>
<br />
This is useful for many things. For instance:<br />
<br />
- If you get a support ticket with a description of a crash, you can "Search by User" in Crittercism and get all the info about the crash the ticket is referring to.<br />
<br />
- If breadcrumbs data was not enough to identify the problem, and you want to further investigate the user's usage in your database/in other frameworks, you can do it by the username.<br />
<br />
- You can contact all the users that suffered from a crash and let them know of a workaround or an app update that solves it.<br />
<br />
- You can set up custom metadata fields to help you identify crashes that occur only to specific types of users (like the Diagnostics tab in a crash page helps you identify crashes that occur only for specific device types or iOS versions...)<br />
<br />
<hr />
<br />
<b>That's it for this post.</b><br />
Crittercism has a lot to offer besides the features I mentioned, like an in-app support forum, so you should definitely check out their website and see everything for yourselves.<br />
<br />
But bottom line - I think Crittercism is a great affordable framework for monitoring and fixing crashes, and you should definitely consider it for any of your apps - just make sure you make the most out of it!</div>
Anonymoushttp://www.blogger.com/profile/06100813770559493046noreply@blogger.com2tag:blogger.com,1999:blog-3833072356413502019.post-73902203245985160562012-04-14T17:10:00.001+03:002014-01-04T13:28:02.787+02:00Developing "Piano Dust Buster"So... "Piano Dust Buster" - the game I've been working on in the past few months in JoyTunes - is live in the iPad App Store for two weeks now. This is very exciting to me, so I decided to write a blog post about it, sharing some thoughts about this game and how it was to develop it.<br />
<br />
<h2>
About the game</h2>
The game is a piano song game, that you can play both in touch mode and with your own real piano.<br />
The idea is to give a tap-tap/guitar hero like experience, while being on the more educational side (e.g. piano keys are real-life sized + there's a game mode with a musical staff that you can learn reading sheet music through) + instead of playing with a toy guitar, you can play with your own real instrument, so you're actually practicing.<br />
<br />
Here's the game trailer, so you can get a hunch of what's the game like:<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.youtube.com/embed/TR8ZQ4Bu0EQ?feature=player_embedded' frameborder='0'></iframe></div>
<br />
For more info, visit the game's homepage: <a href="http://www.joytunes.com/piano">www.joytunes.com/piano</a><br />
The link to the game: <span style="background-color: white; color: #333333; font-family: inherit; font-size: x-small; line-height: 18px; text-align: justify;"><a href="http://itunes.apple.com/us/app/piano-dust-buster-song-game/id502356539?mt=8">http://itunes.apple.com/us/app/piano-dust-buster-song-game/id502356539?mt=8</a></span><br />
<br />
<a name='more'></a><br />
<br />
<h2>
Techincal Facts</h2>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://gamua.com/img/sparrow/title-logo.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="200" src="http://gamua.com/img/sparrow/title-logo.png" width="200" /></a></div>
<ul>
<li>We chose to develop the game in pure objective-c and not some cross platform framework like Adobe AIR. Mainly for performance reasons (recognizing which real piano note was played in real time) and it also allowed us to give a native look-and-feel for menus etc.</li>
<li>The chosen game engine was <a href="http://gamua.com/sparrow/" target="_blank">The Sparrow Framework</a>. The main reason for choosing this framework is because JoyTunes's existing games were written in ActionScript and Sparrow is imitating the ActionScript SDK pretty well. <br />I also found it much easier to learn than the popular alternative - cocos2d.</li>
<li>A major part of the game was developed in TDD (which I'm sure is not something you can say about many games in the app store).</li>
</ul>
<h2>
Lessons Learned</h2>
Since this is both the first iOS app and the first game I developed officially, I learned A LOT and have a tons to share:<br />
<ul>
<li><b>A good second programmer can increase productivity in >x3 factor</b><br />I started to develop "Piano Dust Buster" as a sole programmer, and about 2-3 months later another rockstar game developer (<a href="http://www.twitter.com/noamgat" target="_blank">@noamgat</a>) joined JoyTunes and started to work with me on this project.<br />I was actually lucky enough to have known Noam previously, and we actually took a very thorough programming course together, so we also had a real good understanding of each other.<br /><br />The increase in development pace was unbelievable.<br />In the first few weeks, we did pretty much only pair-programming. This was my way of mentoring him both on the existing codebase, and on Objective-C and development tools. The benefits of pair programming are well discussed <a href="http://anarchycreek.com/2009/05/26/how-tdd-and-pairing-increase-production/" target="_blank">here</a>, and I can really relate. You would think that pairing with someone new to the technology and to the codebase would slow me down, but it really did the opposite - I found myself spending much less time on pondering what would be a good design here and what would be a good behavior there, which were taking a very large percentage of my time when working alone.<br />Needless to say that when Noam got the hang of things our velocity was improving constantly. We still consulted each other about tricky decisions and could get through them quickly, and of course dividing the more straightforward tasks between us helped us finishing them much faster.</li>
</ul>
<div>
<br /></div>
<ul>
<li><b>It's amazing to work on something that you have a real passion towards</b><br /><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEmf2HF6FofuWyxeESRNJuddg0GL2hNVvsQrvrYh5Af8WidoFds0m9qmdZbdN9BTU9yyHP6UtDkfrs72EQFGvDoR2Dxaj9ogbeJvAVH2N8sz0mcpmoS1Gy2577Yl-QqGwjioSD_7SKyyw/s1600/Combine_your_passions-1.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEmf2HF6FofuWyxeESRNJuddg0GL2hNVvsQrvrYh5Af8WidoFds0m9qmdZbdN9BTU9yyHP6UtDkfrs72EQFGvDoR2Dxaj9ogbeJvAVH2N8sz0mcpmoS1Gy2577Yl-QqGwjioSD_7SKyyw/s1600/Combine_your_passions-1.png" /></a><br />My 2 greatest passions in life are software development and music.<br />I felt so amazing being both a part of the musical production team and the development team of this game. Also, I could solve problems like an algorithm to locate a note correctly on a musical staff, while applying advance TDD techniques such as Uncle Bob's <a href="http://cleancoder.posterous.com/the-transformation-priority-premise" target="_blank">Transformation Priority Premise</a> - a classic combination of my 2 big passions. <br />A piece of advice: If you are developers and have an additional passion in life (like I do), when the opportunity arrives to work on something that relates to this passion, don't hesitate and take it. <br />I left a really fun job at IBM in order to join JoyTunes, working more hours for less money, and I don't regret it for a second, because of all the things I learned and the amazing fun I had combining my loves while developing this game.</li>
</ul>
<div>
<br /></div>
<ul>
<li><b>Prototyping is a powerful and important tool.</b><br /><br />Requirements from a game are much fuzzier than developing a server-side application, especially the requirements from the UI layer. <br />You rarely have a good idea of what is the "correct" behavior, and how things should look and interact on screen. <br />Therefore, you have to just go ahead and write a lot of half-baked prototypes for different game modes and interactions, then give it to a bunch of people and see how they feel about it. You will quickly get a grasp of what's working and what's not.</li>
</ul>
<div>
<br /></div>
<ul>
<li><b>Start usability testing early</b><br />Due to the fact that you can know if your menus and your game levels are behaving "correctly" until the players interact with them, usability testing is a crucial phase before releasing. <br />For us, it was especially important to see how children of different age groups interact with the game, and how people with various piano experience level do.<br />I can say we found tons of issues in our usability tests, and I actually wish we started the tests in a much earlier phase, because we had to delay our release date in order to fix all the critical usability issues.</li>
</ul>
<div>
<br /></div>
<ul>
<li><b>Don't take every criticism and feedback too hard</b>Once again, it's hard to define what feels "right" when playing a game, especially when it comes to a game with a lot of visual art and background music. <br />You need to remember that different people have different opinions and different taste. The more usability you do, the more different opinions you are going to get. It's going to be impossible to please everybody, and it's going to be impossible for you to release the "perfect" game that has no usability issues at all.<br />Heck, I'm sure if I look at successful games like "Angry Birds" from a judgmental point of view, I'll easily come up with 2 pages of things they could have done better.<br />So just know your 80-20 rule, and know which feedback is critical and should be fixed immediately, and which feedback is what you are aware of and are willing to live with. You will never release otherwise.</li>
</ul>
<div>
<br /></div>
<ul>
<li><b>Analytics are super important</b>What's a better usability test than the data arriving from all the app store users of your game?<br />There are a lot of good analytics frameworks out there that can help you with this task. We used Flurry.<br /><b><b> <div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNBr8deJAC3oBMhHUHwdfGmCNDSlUHR1BwpQvy4lHypYsBARFVZBMN79d0Hfi7pGyqjaccfNnmrtA0i5VvKNGwmhEEtA4j9H7reBIol7AS4yvwVBGPly4HNQYt3B6xuOIGIqTBR2aPm20/s1600/Flurry-logo.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="110" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNBr8deJAC3oBMhHUHwdfGmCNDSlUHR1BwpQvy4lHypYsBARFVZBMN79d0Hfi7pGyqjaccfNnmrtA0i5VvKNGwmhEEtA4j9H7reBIol7AS4yvwVBGPly4HNQYt3B6xuOIGIqTBR2aPm20/s200/Flurry-logo.jpg" width="200" /></a></div>
</b></b><br />In order to get useful data though, you need to make sure you collect analytics about pretty much everything, and you need to design it carefully so you would be able to extract the essence of your problematic use patterns and what's causing them from the data.<br />Also, we often forget to test the analytics part of our code, since it's not something you usually look for testing in the QA phase. However, if you have a bug there when you release to the App Store (which we did), you would be stuck with the bug until your next update, which could be quite painful.</li>
</ul>
<div>
<br /></div>
<ul>
<li><b>Continuous Deployment is a pain in iOS development</b><br />Nothing would make me happier than the ability to add a tiny feature and simply deploy it to all our users and see its impact immediately. <br />Unfortunately, since releasing an update for your app includes a review process that takes approximately 1 week, continuous deployment is not an option. Also, an update has other hidden meanings like losing all you current version's ranking and reviews. This makes an update something you really need to plan carefully, which is problematic for many reasons (see any continuous deployment presentation/book).<br />A solution for this issue that is only partial: Use the TestFlight API to automatically build and deploy to your up-to 100 beta testers after each commit. At least you'll get some feedback. However, what's 100 beta testers compared to tens of thousands users in the app store?</li>
</ul>
<h2>
Spread the word!</h2>
That's it for now. As you can see, I had a blast working on this game, and we have tons of features and big plans for it in the future. I hope you enjoyed this post and I think I'll post some more thoughts of this kind in the future.<br />
<br />
If you have an iPad, it would be really cool if you download the game and give it a nice review in the app store, and if you don't - it would be really cool if you would share this to someone who has :)<br />
<br />Anonymoushttp://www.blogger.com/profile/06100813770559493046noreply@blogger.com10tag:blogger.com,1999:blog-3833072356413502019.post-88269032330394403662012-02-04T21:45:00.003+02:002012-02-17T19:42:01.629+02:00Xcode vs. AppCode<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5SdMzkUA3i9SM_xeOijolq4EYqg4LmUdYxnZ69XEi_P3ntq2ntUr16aGdl0OiL1OGTwcuPRPiHcEAfMwrSMVPENJK3E6kX-Kx1sjSQoyej03KEFKIVf2CtnGmT7a2ihGvOoezWf47e1s/s1600/xcode_vs_appcode.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5SdMzkUA3i9SM_xeOijolq4EYqg4LmUdYxnZ69XEi_P3ntq2ntUr16aGdl0OiL1OGTwcuPRPiHcEAfMwrSMVPENJK3E6kX-Kx1sjSQoyej03KEFKIVf2CtnGmT7a2ihGvOoezWf47e1s/s1600/xcode_vs_appcode.png" /></a></div>
<b><u><span style="font-family: Verdana, sans-serif; font-size: x-large;"><br /></span></u></b><br />
<b><u><span style="color: purple; font-family: Verdana, sans-serif; font-size: x-large;">Some Background</span></u></b><br />
<b><span style="font-family: Verdana, sans-serif;">(mostly some personal info about me - skip if you're only interested in the comparison):</span></b><br />
<span style="font-family: Verdana, sans-serif;">I've always been an Eclipse fan.</span><br />
<span style="font-family: Verdana, sans-serif;">Eclipse was always my favorite IDE for Java, and therefore when I started developing in Python PyDev was the obvious and excellent choice.</span><br />
<span style="font-family: Verdana, sans-serif;">I tried a little bit of Jetbrains' IntelliJ and PyCharm. They both seemed very impressive, but to be honest - whole the project settings there were a little bit scary for me, plus they cost money and I was happy with the free Eclipse so I didn't see a good reason to make the move.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Upon joining <a href="http://www.joytunes.com/?tok=codesheriff" target="_blank">JoyTunes</a>, I started to develop in 2 new technologies for me: ActionScript3, and Objective-C.</span><br />
<span style="font-family: Verdana, sans-serif;"></span><br />
<a name='more'></a><span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Naturally, <b>Xcode was the first IDE I tried</b> for ObjC. All the tutorials and professional materials are always demonstrated with Xcode so there's no real escape from having to learn it as your first Xcode IDE. <b>I heard about AppCode</b>, but I heard it's very early stage and Xcode was free for apple developers and good enough for a novice iOS developer like me.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">ActionScript3 on mac is a different story though. You can't really find any good IDE for that without having to spend a significant amount of money (FDT seems like a decent IDE for that, but the free version is way too limited). Finally stumbled upon <a href="http://confluence.jetbrains.net/display/AS/Astella+EAP" target="_blank"><b>Astella</b></a>.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<b><span style="font-family: Verdana, sans-serif;">Hello JetBrains!</span></b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.jetbrains.com/img/logos/logo_jetbrains.gif" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="122" src="http://www.jetbrains.com/img/logos/logo_jetbrains.gif" width="320" /></a></div>
<b><span style="font-family: Verdana, sans-serif;"><br /></span></b><br />
<span style="font-family: Verdana, sans-serif;">Astella was such a good experience for me, had pretty much everything I was looking for in an IDE, and even though it's still on beta-testers phase, it's certainly good enough for me and I'm using it as my primary ActionScript development environment.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">So, I thought to myself: All JetBrains products are pretty much alike. If I got used to Astella, getting familiar with every other JetBrains product should be pretty much trivial. So <b>why not give AppCode a try?</b></span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">So I did.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">And there you go - the findings!</span><br />
<span style="font-family: Verdana, sans-serif;"></span><br />
<br />
<hr />
<b><u><span style="color: purple; font-family: Verdana, sans-serif; font-size: x-large;">The Comparison!</span></u></b><br />
<b><span style="font-family: Verdana, sans-serif;">(if you skipped the boring intro this is where you come in)</span></b><br />
<i><span style="font-family: Verdana, sans-serif;"><br /></span></i><br />
<span style="font-family: Verdana, sans-serif;"><b><span style="color: blue;">Disclaimer:</span></b> The comparison was made between <b>Xcode 4.2 </b>and <b>AppCode 1.5 EAP</b> - things might change for future versions of both IDEs.</span><br />
<i><span style="font-family: Verdana, sans-serif;"><br /></span></i><br />
<span style="font-family: Verdana, sans-serif;">This is going to be long, so <b>I'll tell you who won in each category in the headline</b>, and you can skip the category if you don't care for it too much.</span><br />
<span style="font-family: Verdana, sans-serif;"></span><br />
<hr />
<b><u><span style="color: #274e13; font-family: Verdana, sans-serif; font-size: large;">Price (Xcode!)</span></u></b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQN5hM1eItF_HEPxMctdB2R3dl00fj4onjxSpLoswLjNoTNhQn2JCmJcTFEatBDSsmaqaC2nkoWSVrHtgmEUUqhb8GOltrOQN7R-lNfKoCjBi-guMq6svduz3lMTQatlGQx-xNEKpZ4_A/s1600/Mac+App+Store+-+Xcode.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQN5hM1eItF_HEPxMctdB2R3dl00fj4onjxSpLoswLjNoTNhQn2JCmJcTFEatBDSsmaqaC2nkoWSVrHtgmEUUqhb8GOltrOQN7R-lNfKoCjBi-guMq6svduz3lMTQatlGQx-xNEKpZ4_A/s200/Mac+App+Store+-+Xcode.png" width="150" /></a></div>
<span style="font-family: Verdana, sans-serif;">Well, that's a no-brainer. <b>Xcode is free</b> for apple developers, and is sometimes free for non-developers as well (Apple keeps changing that, I lost track), anyhow the highest price I saw for Xcode was 4.99$.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;"><b>AppCode costs</b> 199$ for commercial license, 99$ for indie developers, and it's free for Open Source projects. </span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Wondering if it's worth the price? Keep reading :)</span><br />
<hr />
<span style="font-family: Verdana, sans-serif; font-size: large;"><br /></span><br />
<b><u><span style="font-family: Verdana, sans-serif; font-size: large;"></span></u></b><br />
<b><u><span style="color: #274e13; font-family: Verdana, sans-serif; font-size: large;">Refactoring (AppCode!)</span></u></b><br />
<span style="font-family: Verdana, sans-serif;">I believe most of the readers know the importance of refactoring the code. If they don't - they should look it up or grab a book...</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Anyhow, refactoring is something that without the right tools could be very painful and dangerous, so refactoring is definitely one of the first feature to look for in the IDE you choose from.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;"><b>Xcode has refactoring</b>, but lets examine what it has to offer:</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisqU0-XHG8cXbHe7dGxHTIuqJ2zOWgB1ZhmlguHIEWINwWC-wqL0RFqz8uJbVN4HnPknEWOBtqdHR0hlK9ATqp6sa5Q6h5Lj3MRRl05VsUKjrMT28BEIbpNbkKSEjJXHDNB7E0GGSZ0yQ/s1600/Xcode-3.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><span style="font-family: Verdana, sans-serif;"><img border="0" height="177" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisqU0-XHG8cXbHe7dGxHTIuqJ2zOWgB1ZhmlguHIEWINwWC-wqL0RFqz8uJbVN4HnPknEWOBtqdHR0hlK9ATqp6sa5Q6h5Lj3MRRl05VsUKjrMT28BEIbpNbkKSEjJXHDNB7E0GGSZ0yQ/s320/Xcode-3.png" width="320" /></span></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-family: Verdana, sans-serif;">Xcode: only 6 refactoring methods available</span></td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;"><b>Only 6 commands</b>. Of which I must admit I found myself using <b>only the first two</b>.</span><br />
<span style="font-family: Verdana, sans-serif;">Create superclass, move up and move down are pretty rare. Encapsulate? You mean for an iVar? Who declares iVars anymore? Just use properties.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">The <b>rename refactoring</b> was <b>buggy</b> for me in several cases (forgot to rename some stuff or simply crashed Xcode and left the code in an unstable state), and it <b>doesn't</b> have the option to<b> rename text occurrences</b> as well, which is funny because by default - Xcode writes the name of the file on the top - so renaming a class will always require you to change the filename in comment manually.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Furthermore, notice there are<b> no keyboard shortcuts</b> for refactoring by default (you can configure them, but come on...), and using Refactor -> Rename... from the menu will always open a popup screen with a preview, even when renaming a local variable.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">You CAN rename a local variable by selecting the "<b>Edit All In Scope</b>" after hovering over the variable:</span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEislwNAU4dIWxCxoB1NkNlpXDVvZ66VjE4McIdsLvqs-98ibCmzd5HwCtFAdl3WXKWESMJIlRxFg9RwBu8fm1T4Vy3C8Ncv6Y7jIkFO4q4uQzQjUcS0eSmQl9ov86mog_1HIL0Pv8rJHoY/s1600/Xcode-4.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><span style="font-family: Verdana, sans-serif;"><img border="0" height="199" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEislwNAU4dIWxCxoB1NkNlpXDVvZ66VjE4McIdsLvqs-98ibCmzd5HwCtFAdl3WXKWESMJIlRxFg9RwBu8fm1T4Vy3C8Ncv6Y7jIkFO4q4uQzQjUcS0eSmQl9ov86mog_1HIL0Pv8rJHoY/s320/Xcode-4.png" width="320" /></span></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-family: Verdana, sans-serif;">Xcode: Edit All in Scope is in the same menu as "Add to iTunes as a Spoken Track"</span></td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;">This way works nicely and it even has a keyboard shortcut (<b>⌃⌘E</b>) - but the unintuitive thing to me is <b>how to exit </b>the "rename in scope" mode once you're done? Enter/Tab/Escape all don't work - the only way as I see it, is<b> use the arrow keys</b> to get out of the name of the variable...</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;"><b>AppCode</b>, on the other hand, is on a <b>complete different level</b> here. And it <b>keeps getting better</b> (some of the refactorings I metion were added in the recent prerelease version of<b> AppCode 1.5</b> and there are more to come).</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">This is the current refactoring menu in AppCode:</span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqV-78Or54F4IYxce1-0n-KhLPghf04PYd6lAbYpIVl7U7Z7fZb3EHAWQ5nifv3xZNBNY_wktVWsG9X4Y2Y7-qs-BqHn0XrDW5NpZXDvpE3_-WCun4OH-sjo3V5QDkY3-4lZfqKhLtmXI/s1600/AppCodeSandboxTests.m+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567-1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><span style="font-family: Verdana, sans-serif;"><img border="0" height="198" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqV-78Or54F4IYxce1-0n-KhLPghf04PYd6lAbYpIVl7U7Z7fZb3EHAWQ5nifv3xZNBNY_wktVWsG9X4Y2Y7-qs-BqHn0XrDW5NpZXDvpE3_-WCun4OH-sjo3V5QDkY3-4lZfqKhLtmXI/s640/AppCodeSandboxTests.m+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567-1.png" width="640" /></span></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-family: Verdana, sans-serif;">AppCode's refactoring options: Aah... That's better!</span></td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;">So much cool stuff, like <b>Change Signature, Extract Variable/Constant/Property, Safe Delete</b> (searches for references before deleting) and I from my experience they are all very safe and accurate.</span><br />
<span style="font-family: Verdana, sans-serif;">Notice that almost every refactoring has a <b>built-in keyboard shortcut</b> by default, and even the ones who don't have one are still easily reachable without using the mouse (I'll discuss keyboard shortcuts later).</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Other cool things to mention here, is that the <b>"rename" refactoring is very context aware</b>, and usually can be done "in place" (i.e. without a dialog box).</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">One really cool dialog box worth mentioning, is the <b>Rename method / Change signature</b> one:</span><br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtLAiqXe607NFP72hPQLNWB6K4dcZw5g9UDmsgY2I9xpVnjvXgSlfEW_1zQIf0i0Za-ZYGS0MgIEScE3vkPGJMFmaUz0E_CA26Fckw9Fe6THm2htq6XjikJHDPk0qaYP8U-ajDyndrnWQ/s1600/Change+Signature-1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><span style="font-family: Verdana, sans-serif;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtLAiqXe607NFP72hPQLNWB6K4dcZw5g9UDmsgY2I9xpVnjvXgSlfEW_1zQIf0i0Za-ZYGS0MgIEScE3vkPGJMFmaUz0E_CA26Fckw9Fe6THm2htq6XjikJHDPk0qaYP8U-ajDyndrnWQ/s640/Change+Signature-1.png" width="420" /></span></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-family: Verdana, sans-serif;">AppCode's Change Signature dialog: Very well designed</span></td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;">The <b>only bad thing</b> I can say about the refactoring mechanism and the change signature one specifically, is that <b>when</b> <b>you change</b> a method's signature/name and now it's<b> longer than the max line length</b> you defined (120 chars for me, easily reached in objective-c method names), <b>it will discard any nice line wraps</b> you made and will define the entire method <b>on a single line</b>.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">However, in general - you can see what I mean when I say they're not in the same league here, and <b>AppCode is the definite winner</b>.</span><br />
<span style="font-family: Verdana, sans-serif;"></span><br />
<hr />
<b><u><span style="color: #274e13; font-family: Verdana, sans-serif; font-size: large;">Quick Fix (AppCode!!!!)</span></u></b><br />
<span style="font-family: Verdana, sans-serif;"><b>Quick fix is</b> IMO one of the <b>most important</b> features of an IDE, if not THE most important one.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">If you don't know what this feature means - basically it means that when the cursor stands on an error/warning and choose from a menu of things you can do in order to fix the problem.</span><br />
<span style="font-family: Verdana, sans-serif;">This is <b>great if you're practicing TDD</b>, or other forms of "Programming by Wishful Thinking" when you type the code you need to use <b>before it even exists</b>, as it can generate the missing methods/classes for you.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Even if you don't do TDD, I think all Objective-C developers would know how annoying it is to<b> declare a @property </b>and have the compiler complain about it not having<b> @synthesize</b>. Well with quick-fix, it becomes a whole lot easier...</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Advanced IDEs (such as AppCode) will do even better and let you "quick-fix" stuff that are<b> not even errors yet</b>, like add a missing private declaration for a helper method you have in your .m file, etc. </span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">So, does <b>Xcode</b> have Quick Fix?</span><br />
<span style="font-family: Verdana, sans-serif;"><b>It actually does</b>, but it's <b>very basic and limited</b>. In order to use it, you can either click the red dot near the problematic line (<i>if you could ever succeed doing it <b>without adding a breakpoint... so annoying</b>!!</i>), or you can use the keyboard shortcut <b>⌃⌘'</b> for quick-fixing next error. </span><br />
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhD6sroK_60RhdyXsRRFueltG6iHJ_klycum2tYAOQk13VxrqyY9WbM1O2MuWI7wGB0DCiBQKvR7_EYjtDPl-K-myRdbf0HDbJshe_lYJlVjzuskkuqA2-JLx8zDpql_38tWnlhN8Cyr7Q/s1600/Xcode-2.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><span style="font-family: Verdana, sans-serif;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhD6sroK_60RhdyXsRRFueltG6iHJ_klycum2tYAOQk13VxrqyY9WbM1O2MuWI7wGB0DCiBQKvR7_EYjtDPl-K-myRdbf0HDbJshe_lYJlVjzuskkuqA2-JLx8zDpql_38tWnlhN8Cyr7Q/s1600/Xcode-2.png" /></span></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-family: Verdana, sans-serif;">Xcode: lets you fix only trivial things like a semicolon</span></td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;"><b>AppCode</b>, on the other hand, has <b>extremely powerful quick-fix</b> feature, by simply standing on code and typing<b> Alt+Enter</b>. Instead of describing it in words, here is an example:</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPfERsYVzvyWOgfa-DjUrP5jz9Kuowm61e2NDNkLhxJE7uHIhiQ4IbRSqNS_OLD80XNZka2QConVfG6yBwJXKKxTsAW_vtiaZPE8Lp1sknKr3mGskChWyr36199JhHP3FrtfMUUEAit7s/s1600/AppCodeSandboxTests.m+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><span style="font-family: Verdana, sans-serif;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPfERsYVzvyWOgfa-DjUrP5jz9Kuowm61e2NDNkLhxJE7uHIhiQ4IbRSqNS_OLD80XNZka2QConVfG6yBwJXKKxTsAW_vtiaZPE8Lp1sknKr3mGskChWyr36199JhHP3FrtfMUUEAit7s/s1600/AppCodeSandboxTests.m+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567.png" /></span></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-family: Verdana, sans-serif;">AppCode: Red lightbulbs are fixes for errors, pencils are quick-edit operations you can do</span></td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">The cool thing, which brings me back to the refactoring issue, is that all the creation of code is done by the same dialog boxes or in place renaming features of the refactoring operations. One of the<b> coolest quick fixes</b> is this one:</span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOFkPaOwYv32V49MWJ4WNSoBkJ9sgTQOMRVVKTet62y6BduZgblvOV9yjfBoX4xBTrNSYyUzLQ1i__-_r9zDuG3AGExXOcH1iNWnaQTmdgMrIAx0_tL2mhMT2k77RHgRUHsMscPv8sGoE/s1600/AppCodeSandboxTests.m+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567-2.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><span style="font-family: Verdana, sans-serif;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOFkPaOwYv32V49MWJ4WNSoBkJ9sgTQOMRVVKTet62y6BduZgblvOV9yjfBoX4xBTrNSYyUzLQ1i__-_r9zDuG3AGExXOcH1iNWnaQTmdgMrIAx0_tL2mhMT2k77RHgRUHsMscPv8sGoE/s1600/AppCodeSandboxTests.m+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567-2.png" /></span></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-family: Verdana, sans-serif;">AppCode 1.5's new property quick-fix : Just type self.something and press Alt+Enter...</span></td></tr>
</tbody></table>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4gI7jCwycvXFx9FGyNkNdrRLPbfTZUPCHrh16n3t0klFa6BwwVPtlGHKw-Af_Tv0RPDDgcp1hy-KUM9YNKhBF77Ni3UFbWjb9vHCGYa6WAn0gwu3fNNU-FRunSpYiriPEJbgqh95P_5k/s1600/AppCodeSandboxTests.m+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567-2-1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><span style="font-family: Verdana, sans-serif;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4gI7jCwycvXFx9FGyNkNdrRLPbfTZUPCHrh16n3t0klFa6BwwVPtlGHKw-Af_Tv0RPDDgcp1hy-KUM9YNKhBF77Ni3UFbWjb9vHCGYa6WAn0gwu3fNNU-FRunSpYiriPEJbgqh95P_5k/s1600/AppCodeSandboxTests.m+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567-2-1.png" /></span></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-family: Verdana, sans-serif;">One click for everything! It evens releases "retain" property in dealloc for you</span></td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Damn, I wanted a private property and it defined it in the interface? What do I do?</span><br />
<span style="font-family: Verdana, sans-serif;">You guessed correctly. <b>Alt+Enter again</b>:</span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_uekBGgkwljwvz5s7mu4ICym7FP_KHlgvlnwmOFii9S4e-BfH2acDzUT6FZ5m981LBOaRABioYKCGXibH4j6YUZOKgmagguNlxV4xCWaaDsAHb7g1uEEK8un4gDBzgSRXDbi7kqduugg/s1600/AppCodeSandboxTests.h+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><span style="font-family: Verdana, sans-serif;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_uekBGgkwljwvz5s7mu4ICym7FP_KHlgvlnwmOFii9S4e-BfH2acDzUT6FZ5m981LBOaRABioYKCGXibH4j6YUZOKgmagguNlxV4xCWaaDsAHb7g1uEEK8un4gDBzgSRXDbi7kqduugg/s1600/AppCodeSandboxTests.h+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567.png" /></span></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><span style="font-family: Verdana, sans-serif;">AppCode's Quick-Fix: more powerful than you think...</span></td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Well, I think you get the picture - AppCode's quick-fix is <b>simply magic</b> and saves you precious development time. Xcode? Well... It can fix missing semicolons...</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">The only thing you need to notice about quick-fix, is that if your code is <b>inside a macro</b> (e.g. STAssertEquals), it <b>sometimes fails</b> to work properly.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">BTW, the annoying breakpoint adding instead of showing the error is easily avoided in AppCode. First of all you need to hold your click for about 1 second before it creates a breakpoint, and also the error/warning will appear as a floating lightbulb near the text and not in the beginning of the line.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<hr />
<span style="color: #274e13; font-family: Verdana, sans-serif; font-size: large;"><b><u>Code completion & generation (AppCode)</u></b></span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">I must say I really<b> enjoyed Xcode code completion </b>when I started with it. It really knows what I'm going to write and it's very easy to choose from the list of suggestions.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;"><b>AppCode is no sucker</b> here as well and has pretty much the same code completion standards as well. The only annoying thing for me is that <b>sometimes</b> you select the completion you want <b>with Enter and sometimes</b> <b>with Tab</b> (e.g. for suggestions of variable names). But I can live with that.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">A place where AppCode has a small win in code generation, is when you need to <b>implement/override a method</b> in an @implementation context.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">In Xcode, as I had a hard time finding out at first, you can go into method-name-completion mode by <b>starting a line with '-' </b>and then the name of the method:</span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0p7fUYQChssQDaq1_B-d7C15zI_OJ8WkjfP5CHtklFPWY1q3kUrisYL_yfHwH8RsDYVu3fyCbyKSqOp3p1mzijJ9fXzsEx-v0mBbGl76euEyhi7pow0sY-dAqai2ubz-HT07vltBLSzk/s1600/Xcode-5.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="302" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0p7fUYQChssQDaq1_B-d7C15zI_OJ8WkjfP5CHtklFPWY1q3kUrisYL_yfHwH8RsDYVu3fyCbyKSqOp3p1mzijJ9fXzsEx-v0mBbGl76euEyhi7pow0sY-dAqai2ubz-HT07vltBLSzk/s640/Xcode-5.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Xcode: type '-' and the beginning of a method name to activate completion</td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;">In AppCode, completion may not be automatic on typing something, but it gives you a better set of options for completion.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">You need to choose if you want to Override a method (</span><span style="font-family: Verdana, sans-serif;"><b>⌃O</b>) or Implement a method (</span><span style="font-family: Verdana, sans-serif;"><b>⌃I</b>). And then you get a menu like this:</span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxNjD6B4Xj_Wgy8SJbwKgmcnUDhixHz2LLkPaguGUVqyiYsvcle2bCz1hVBJu2flJFFVHHjugDAG5Wakt6GJLn6Tj7DA0OxHoddycfVIjcZLa3l4xDRC7qYzDkg5uTs31BpOsKC0dyhrU/s1600/Choose+Methods+to+Override.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxNjD6B4Xj_Wgy8SJbwKgmcnUDhixHz2LLkPaguGUVqyiYsvcle2bCz1hVBJu2flJFFVHHjugDAG5Wakt6GJLn6Tj7DA0OxHoddycfVIjcZLa3l4xDRC7qYzDkg5uTs31BpOsKC0dyhrU/s640/Choose+Methods+to+Override.png" width="428" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">AppCode: dialog box instead of text only, but you get to see what you are overriding exactly</td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Another aspect of code generation, are common templates like <b>templates for init/dealloc</b>/etc.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">In <b>Xcode</b> 4, Apple added the "<b>Code Snippets</b>" feature:</span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGpSHEi6jqygFifiakxJs_icn3cwiDywhHnm9hWLE_Q4c67ThqRXyM7C-0pmeGpdaDIubIcnKjzYUzWhG3VGj4PFettyJ1u_vVrRpdlv31wXRYV_g4tVQgPjWzZ62mAuhvJeyKOKBXf2M/s1600/Xcode-6.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGpSHEi6jqygFifiakxJs_icn3cwiDywhHnm9hWLE_Q4c67ThqRXyM7C-0pmeGpdaDIubIcnKjzYUzWhG3VGj4PFettyJ1u_vVrRpdlv31wXRYV_g4tVQgPjWzZ62mAuhvJeyKOKBXf2M/s1600/Xcode-6.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Xcode's Code Snippets feature: quite neat.</td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;">Of course you can <b>customize</b> your own snippets quite easily.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">In AppCode, sadly, simply <b>typing "init" won't do anything</b>. Not because AppCode doesn't have its own snippets mechanism, but because there's another way of generating initializers, which is the "Generate..." feature, activated by </span><span style="font-family: Verdana, sans-serif;"><b>⌘N</b>:</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8Pu5uHCeCLwoC_ir7YyZK61UA97l_zgjqAF0rrcjNNQ6_SvmxdYZZIJuv30-AQDZQcIuKBU2ATqAj2yvdaAC6IdmqGHEGEaB2frervUrzQ9TsY9nHpPDBPAIYgz7p3eH7OR0OzUldglc/s1600/AppCodeSandboxTests.m+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567-3.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8Pu5uHCeCLwoC_ir7YyZK61UA97l_zgjqAF0rrcjNNQ6_SvmxdYZZIJuv30-AQDZQcIuKBU2ATqAj2yvdaAC6IdmqGHEGEaB2frervUrzQ9TsY9nHpPDBPAIYgz7p3eH7OR0OzUldglc/s1600/AppCodeSandboxTests.m+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567-3.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">AppCode's Generate menu - similar to its refactor one</td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;">Of course, AppCode also comes with its customizable "<b>Live Templates</b>" mechanism, activated by </span><span style="font-family: Verdana, sans-serif;"><b>⌘J</b>, which like Xcode is context aware (interface/implementation/function body) featuring stuff like declaring a property, iterating over a collection, NSLogging the current function's name, etc.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">In conclusion, the difference here is less significant, but <b>AppCode is a little better</b>, because of the <b>more controlled and easier to discover</b> method names completion.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<br />
<hr />
<b><u><span style="color: #274e13; font-family: Verdana, sans-serif; font-size: large;">Key Bindings (AppCode)</span></u></b><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;"><u>A little background for this part:</u></span><br />
<span style="font-family: Verdana, sans-serif;"><i>"oh no... background again? I though I skipped this..."</i></span><br />
<span style="font-family: Verdana, sans-serif;">Well tough... Deal with it.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">First, I must admit <b>I'm a newcomer to Mac OS X</b> and therefore what seems intuitive to me might be different for some power Mac users that read this review.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Second, I work with a <b>full Mac keyboard</b> with the keypad:</span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="http://www.assistiveit.co.uk/images/keyboard.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="http://www.assistiveit.co.uk/images/keyboard.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">Full Mac Keyboard: Helps me to be more productive</td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;">I find it for me since looking for the function key all the time in order to delete/home/end/page up/page down is quite annoying for me. Using a regular PC keyboard might have the same advantage, but it's very annoying that the command (windows key) and the alt/option key are located differently from when I work on my laptop keyboard.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Anyhow - sorry for digressing from the comparison - just thought this is good to know and an important tip.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;"><u>Default key bindings behavior:</u></span><br />
<span style="font-family: Verdana, sans-serif;">So, the good thing about<b> both IDEs</b> regarding key bindings is that they are quite <b>easily configurable</b>, so no matter how crappy you think the default bindings are, you can also customize it to make more sense to you.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Regarding the default key bindings - when starting with <b>Xcode</b> I found myself <b>reconfiguring a bit too much</b>: <b>Page Down/Page Up only scroll</b> the view and not move the cursor, <b>Home/End key</b> goes to the <b>beginning/end of the document</b>, and more... </span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">In <b>AppCode</b>, I can't remember anything I had to configure, and the default bindings worked quite nicely. Regarding <b>Home key</b> specifically - AppCode has an additional feature that pressing home key multiple times will <b>move from the first column in the line to the first non-whitespace character</b> in the line - quite useful. In Xcode I couldn't really find a way of doing this.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">A <b>small win for Xcode</b> here, is the <b>Ctrl+Arrow Keys vs. Alt+Arrow Keys</b> (Also Ctrl/Alt+Backspace/Delete): In Xcode using <b>Ctrl+Move</b> jumps to the next/previous <b>CamelHump</b> (notice in Lion you need to disable the default behavior for Ctrl+Left/Right in the System Preferences in order for this to work) and <b>Alt+Move</b> jumps to the <b>next/previous whole word</b>. This is useful, because camel-hump jumpings is neat when you want to change a variable name etc., but if that's your only way of skipping words it could be slowish.</span><br />
<span style="font-family: Verdana, sans-serif;">In <b>AppCode</b>, you have <b>only Alt+Left/Right</b>. By default it moves entire words, but you can <b>change this in the preferences</b> (look for "CamelHumps")</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;"><u>Difficulty in learning the key bindings</u></span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Here AppCode's win is more noticeable.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Both AppCode and Xcode have the key bindings written near the operations in the menus. However, in AppCode <b>every button</b> you hover on have a key binding written <b>in the tooltip</b>, which isn't the case with Xcode:</span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVh0amMqYO1_iIR-C8Xc2wxAfAFvySJOiiKB6RGv9O1aXzPQoxEaGLpKE94wP4fPyJUUEs2WC9tXnA17MAxpntBnicnkhWKd9O4z6p3ROEaJdHKVG-uapRrHoUNyYxNH63EL_EH-bF8PY/s1600/TCSAppDelegate.m+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVh0amMqYO1_iIR-C8Xc2wxAfAFvySJOiiKB6RGv9O1aXzPQoxEaGLpKE94wP4fPyJUUEs2WC9tXnA17MAxpntBnicnkhWKd9O4z6p3ROEaJdHKVG-uapRrHoUNyYxNH63EL_EH-bF8PY/s1600/TCSAppDelegate.m+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567.png" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">AppCode: tooltips contain the key bindings so you can easily memorize them</td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;">Now, that's all nice and fun, but the real<b> killer feature</b> here, is the <b>"Find Action"</b> feature, activated with </span><span style="font-family: Verdana, sans-serif;"><b>⌘⇧A</b> :</span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimQsl9Ynsjf2PFxr41GNkMOC-xBJi1CKv2Q-0Ijf26mgcHqEGPBwQWL2piys-6Q-ObShsvl5gKYrOfIz2CFF3xLl_QjDrwiuG3znC7Gj51XeHrnPK05jfeCJnAWOirDnWyMJmWMA8B-0s/s1600/TCSAppDelegate.m+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567-1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="270" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimQsl9Ynsjf2PFxr41GNkMOC-xBJi1CKv2Q-0Ijf26mgcHqEGPBwQWL2piys-6Q-ObShsvl5gKYrOfIz2CFF3xLl_QjDrwiuG3znC7Gj51XeHrnPK05jfeCJnAWOirDnWyMJmWMA8B-0s/s320/TCSAppDelegate.m+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567-1.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="font-size: 13px;">AppCode's "Find Action..." dialog: turns your IDE into a command line interpreter</td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;">As you can see, it shows you the key bindings for commands that have one, and the really fun thing is that you can <b>access actions that do not have a key binding</b> like that, <b>without</b> having to<b> configure</b> a new key binding, <b>or</b> using the <b>mouse</b>.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;"><u>Quick Reference Card</u></span><br />
<span style="font-family: Verdana, sans-serif;">AppCode comes with a <b>built in keymap reference card</b>, that can be reached from the help menu (or by using Find Action of course...)</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Xcode doesn't have a built-in one, and I'm afraid that the ones that you can find on the web are usually <b>not up-to-date</b>, since Apple tends to change the key bindings from version to version of Xcode, and not everyone always bother to update the reference cards.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;"><u>Summary</u></span><br />
<span style="font-family: Verdana, sans-serif;">All in all, I find myself <b>using the mouse a lot less in AppCode</b>, since it's easier to learn the shortcuts, and there seems to be more shortcuts in general. If you want to learn the existing shortcuts in <b>Xcode 4+, <a href="http://pragmaticstudio.com/screencast-tags/xcode4" target="_blank">these screencasts</a></b> might come in handy.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<hr />
<span style="color: #274e13; font-family: Verdana, sans-serif; font-size: large;"><b><u>Project Setup and File Management (Xcode)</u></b></span><br />
<span style="font-family: Verdana, sans-serif;">Here we are touching the <b>weak spot of JetBrains</b> as I see it. In all of their products, the most <b>unintuitive and cumbersome</b> thing is how do I configure the project - the dependencies, which files are built and how, etc.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">I once tried to add an external framework for my project from AppCode, and it caused complete chaos. Files were copied instead of being referenced, stuff didn't compile, and I ended up <b>undoing everything and starting from fresh</b> in Xcode for the dependency to work well.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Furthermore, there are some basic projects settings Xcode has that <b>I simply couldn't find in AppCode</b>. The build settings and various flags is one example, but a common use case is the following: </span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">You have a test target and a regular target. When you <b>add a source file or resource</b> to the project, you need to <b>choose which targets</b> should include it. AppCode lets you choose this <b>when you add</b> the file, but if you want to change it <b>later</b> because you forgot or made a mistake, <b>you must launch Xcode</b>.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsYwNKHmweCYdN2VFemaCX_NOd0GnPD7uanaNyezbLa0fC5j3qKPwSW32iF8NC1qtzp2xsreHXcHE1BDthXj8FxkKW02_Zc_SxhZIepEUeKRnWoiqPOqKaCgSn-wfX2ZdBmgKmkOfClKo/s1600/Xcode-7.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="210" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsYwNKHmweCYdN2VFemaCX_NOd0GnPD7uanaNyezbLa0fC5j3qKPwSW32iF8NC1qtzp2xsreHXcHE1BDthXj8FxkKW02_Zc_SxhZIepEUeKRnWoiqPOqKaCgSn-wfX2ZdBmgKmkOfClKo/s320/Xcode-7.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Xcode's project/build settings view. <br />
You need to mess with it so often, yet AppCode simply doesn't have it.</td></tr>
</tbody></table>
<br />
<span style="font-family: Verdana, sans-serif;">Something that makes the whole thing <b>less critical</b> when deciding if you want AppCode or not (and is a big win for AppCode), is the fact that <b><span style="color: red; font-size: large;">AppCode is 100% compatible with Xcode</span></b>'s projects settings and the </span><span style="font-family: Verdana, sans-serif;">project.pbxproj file. This means that you can change settings in one IDE without fear and the other will automatically synchronize on the changes.</span><br />
<div>
<span style="font-family: Verdana, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Verdana, sans-serif;">Another small win for AppCode in this category, is the ability to move from the standard Xcode project structure view, to a regular <b>file-based view</b>:</span></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAmuahgyho-Czxtt0K-l3DGzTKA5ZF64J0cMbZWV-NkbSv7ZZi1uSV93DeUQE8qLWigpKszrjKT5XXQX0GCXGnpnjvZqPJQWu47xMMRGLz4sZ2keqfbtpqFu3WAFFJJ_3e410kNQw4oI8/s1600/TCSAppDelegate.m+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567-2.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="132" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAmuahgyho-Czxtt0K-l3DGzTKA5ZF64J0cMbZWV-NkbSv7ZZi1uSV93DeUQE8qLWigpKszrjKT5XXQX0GCXGnpnjvZqPJQWu47xMMRGLz4sZ2keqfbtpqFu3WAFFJJ_3e410kNQw4oI8/s320/TCSAppDelegate.m+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567-2.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">AppCode lets you see your project as regular files</td></tr>
</tbody></table>
<div>
<span style="font-family: Verdana, sans-serif;">This can be useful when you want to add something to your project that was already copied to the directory.</span></div>
<div>
<span style="font-family: Verdana, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Verdana, sans-serif;">Also, in Xcode the <b>order of the files</b> in each group matters. <b>Why?</b> I'm really not sure, but all I know is that I end up reordering everything and scrolling stuff around whenever I add a new file and it really annoys me. <b>In AppCode</b>, everything is <b>sorted alphabetically</b>.</span></div>
<br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<hr />
<span style="color: #274e13; font-family: Verdana, sans-serif; font-size: large;"><b><u>Code Inspection (AppCode)</u></b></span><br />
<span style="font-family: Verdana, sans-serif;">Once you fiddle with the compiler settings of <b>Xcode</b>, you can have it warn you about quite some stuff it doesn't warn you about by default. You can also (and should!) tell it to <b>treat warnings as errors</b>:</span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglzU2qscxUTTB2EkPza-mBhMdWoScIs5QDX0a1VONr8zxpfNE6Ar-42EseRzxtd-YlAvZumJF-Y_RZFaTv_ZCaFHVwS3Iyi090fvLVJDN0nky9bmzW1_r6TrLfFSGVHwXDs6h9nmwYMfI/s1600/Xcode-9.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="367" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglzU2qscxUTTB2EkPza-mBhMdWoScIs5QDX0a1VONr8zxpfNE6Ar-42EseRzxtd-YlAvZumJF-Y_RZFaTv_ZCaFHVwS3Iyi090fvLVJDN0nky9bmzW1_r6TrLfFSGVHwXDs6h9nmwYMfI/s400/Xcode-9.png" width="400" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Xcode's warnings section in build settings.</td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">You can also run <b>"Analyze"</b> for your project in Xcode using </span><span style="font-family: Verdana, sans-serif;"><b>⇧</b></span><span style="font-family: Verdana, sans-serif;"><b>⌘B</b>, which will run the clang tool and find mistakes that are not necessarily something the compiler finds on a regular basis.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">These 2 features by Xcode would probably be enough in catching most of the stuff you need. However, <b>AppCode's code inspection feature </b>takes it to the next level:</span><br />
<br />
<ul>
<li><span style="font-family: Verdana, sans-serif;">Finds <b>unused</b> <b>code</b> (class/method/property) and not only unused local variables.</span></li>
<li><span style="font-family: Verdana, sans-serif;">Finds <b>unused imports</b></span></li>
<li><span style="font-family: Verdana, sans-serif;">Finds <b>spelling typos</b> in comments and in variable names.</span></li>
<li><span style="font-family: Verdana, sans-serif;">Finds <b>memory management errors</b> (e.g. alloc with no release)</span></li>
<li><span style="font-family: Verdana, sans-serif;">and many other new inspections...</span></li>
</ul>
<div>
<span style="font-family: Verdana, sans-serif;">Inspection is triggered whenever you change a file. But you can run inspection on your entire project (no key binding, you'll have to use "Find Action..."), which gives you a very nice summary of all errors:</span></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP1P15vOC16WtlMMGszv6Wum65HdZ5I33VnAQu1k94Orfxz5SHnoK8i2vornhsvkQgRfwXrphXmvp-t8P_CThT63mLzKFOr83cwJQ1CjmXde8QJxpSIzrhSUXARs3q4HVw_ksP38lgn7M/s1600/InfoPlist.strings+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="260" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP1P15vOC16WtlMMGszv6Wum65HdZ5I33VnAQu1k94Orfxz5SHnoK8i2vornhsvkQgRfwXrphXmvp-t8P_CThT63mLzKFOr83cwJQ1CjmXde8QJxpSIzrhSUXARs3q4HVw_ksP38lgn7M/s640/InfoPlist.strings+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">AppCode's inspection view</td></tr>
</tbody></table>
<div>
<span style="font-family: Verdana, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Verdana, sans-serif;">You also have <b>a square indicator</b> in the corner of the file you're editing that tells you the overal inspection status of that file:</span></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhh6euRX16WAb4aybBngAmpiXVkFnisSL7A0lKKsT8goQjMlSekMxsUWFe9Bz6JinwlPXfR4Xk5oa8Ql96gWvY_uNBsfry_OMxpz9Uw2wDiFzGokONA-BEgft7bMsDd3ywsnvju7hSUhsA/s1600/InfoPlist.strings+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567-1.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhh6euRX16WAb4aybBngAmpiXVkFnisSL7A0lKKsT8goQjMlSekMxsUWFe9Bz6JinwlPXfR4Xk5oa8Ql96gWvY_uNBsfry_OMxpz9Uw2wDiFzGokONA-BEgft7bMsDd3ywsnvju7hSUhsA/s1600/InfoPlist.strings+-+%5B~_dev_sandboxes_AppCodeSandbox%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567-1.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">AppCode: a green/yellow/red indicator tells you the overal inspection status of the file.</td></tr>
</tbody></table>
<div>
<span style="font-family: Verdana, sans-serif;">Inspections are of course <b>configurable</b> via settings.</span></div>
<div>
<span style="font-family: Verdana, sans-serif;"><br /></span></div>
<div>
<span style="font-family: Verdana, sans-serif;">The only problem with AppCode's advanced inspections system, is that it gives too many <b>false alarms</b>:</span></div>
<div>
<ul>
<li><span style="font-family: Verdana, sans-serif;">Sometimes the default category for private methods is recognized as an unused interface</span></li>
<li><span style="font-family: Verdana, sans-serif;">If I release an iVar in tearDown of tests and not in dealloc it warns, you can configure it to warn only if it's not released at all, but it's buggy</span></li>
</ul>
</div>
<br />
<hr />
<span style="color: #274e13; font-family: Verdana, sans-serif; font-size: large;"><b><u>Unit Tests Support (AppCode)</u></b></span><br />
<span style="font-family: Verdana, sans-serif;">If you're reading my blog, you won't be surprised to know that this is one of the most important things I look for in an IDE.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Xcode 4 added <b>built-in support for unit-tests</b> via the <b>OCUnit</b> testing framework. This was quite a big deal for me when I heard about it.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">The built-in support means basically that you can add a checkmark to "<b>include unit-tests</b>" when you start a new project, it sets up an <b>additional test target</b> for your project, and then you can<b> run all the tests</b> in the project with <b>⌘U</b> (you actually need to fiddle with the settings a bit to make it run without launching the simulator, but that's a different topic).</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">This is how the it looks when you run all your tests:</span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPSA8P7fzl0rtqGt27sEG7g0YhD2yVoGcN6NuSHa_DDY5J9reLXPFGwtV-F3DJkkj-dnVVWI7J8Uh3ltYwtbT28unG4ePZnrsuYKusmXddFshEJz9PDGJKG9jz-Igr8_xazBTuKJYQCNw/s1600/Xcode-11.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="284" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPSA8P7fzl0rtqGt27sEG7g0YhD2yVoGcN6NuSHa_DDY5J9reLXPFGwtV-F3DJkkj-dnVVWI7J8Uh3ltYwtbT28unG4ePZnrsuYKusmXddFshEJz9PDGJKG9jz-Igr8_xazBTuKJYQCNw/s640/Xcode-11.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td class="tr-caption" style="font-size: 13px;">Xcode runs tests: Only tells you failed/succeeded and you have to look at console for amount of tests etc.</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;"></span><br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<span style="font-family: Verdana, sans-serif;">The biggest <b>problems</b> of the testing mechanism in Xcode: </span><br />
<br />
<ul>
<li><span style="font-family: Verdana, sans-serif;">You <b>can't</b> really <b>run a specific test</b>, must run them all.</span></li>
<li><span style="font-family: Verdana, sans-serif;">If you want to look at the <b>logs of a single test</b> (e.g. for debugging a failed test), you must find it in the <b>console manually</b>, as it contains the log for the entire test-suite run.</span></li>
</ul>
<div>
<span style="font-family: Verdana, sans-serif;"><b>AppCode solved both </b><b>problems</b>: it allows you to <b>run a single test</b> (either ctrl+click the function that you want to run or add a new run configuration for a single class), and when a test fail, you can click it and see the <b>log for the failing run</b>:</span></div>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQhuSVOR05rOuYxOFeqe0PrQ9V7lF9dWY2BdOW7qYrzsudW29IPep4-QFiMvdZQNfeVy9x6XoRTB7-6VV-kakk7xuXEk3AorX3WCnus43T64wlRAV-d7FPNYpgiO_ExaHAieWZbsY6zPE/s1600/SPDisplayObject.m+-+Sparrow+-+%5B~_sdks_Sparrow-Framework_sparrow_src%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="122" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQhuSVOR05rOuYxOFeqe0PrQ9V7lF9dWY2BdOW7qYrzsudW29IPep4-QFiMvdZQNfeVy9x6XoRTB7-6VV-kakk7xuXEk3AorX3WCnus43T64wlRAV-d7FPNYpgiO_ExaHAieWZbsY6zPE/s640/SPDisplayObject.m+-+Sparrow+-+%5B~_sdks_Sparrow-Framework_sparrow_src%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">AppCode's Test Results View: Green/Red bar + only relevant logs</td></tr>
</tbody></table>
<div>
<span style="font-family: Verdana, sans-serif;">Notice you also get a <b>green/red bar</b> instead of a simple popup with test succeeded/failed - good for TDD.</span></div>
<br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">So this is why I think AppCode is better for unit tests.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">2 small wins for Xcode though in this category:</span><br />
<br />
<ul>
<li><span style="font-family: Verdana, sans-serif;">It paints the <b>failing asserts</b> in red in the code:</span><span style="font-family: Verdana, sans-serif;"><br /></span></li>
</ul>
<br />
<span style="font-family: Verdana, sans-serif;"></span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY0DL7EnzTQ6aPDZg6UeH-o2S3oQk45OIhGdljYijYYk0LTEv-fs4-kPejYN4ppoIEseQrHXfWe4CPOmL4O_60cwT9CZ1y5QqTL5E72mxG2TBf88GHF-0WD1jtI3wj1Sb3FVjy6nIe5dQ/s1600/Xcode-12.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="176" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY0DL7EnzTQ6aPDZg6UeH-o2S3oQk45OIhGdljYijYYk0LTEv-fs4-kPejYN4ppoIEseQrHXfWe4CPOmL4O_60cwT9CZ1y5QqTL5E72mxG2TBf88GHF-0WD1jtI3wj1Sb3FVjy6nIe5dQ/s640/Xcode-12.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Xcode makes it easier to see what assert failed in the code</td></tr>
</tbody></table>
<br />
<ul>
<li><span style="font-family: Verdana, sans-serif;">In AppCode, if I have special dependencies for the test target (e.g. OCMock framework), after running my regular target, <b>code inspection will go crazy</b> on me for my tests:</span></li>
</ul>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGNRxp_OOs-Zm_rz2JFnHD23-ExynySJhm0zzW8ay32R9BWT6tWrWA7SbAGTytS_Z1TKWWK7IB-23U1VsRRC9qBhXbtFZePHreelPxu3beZ73R2_CxWtS2hZtkhVOSPr7Ftp1dSo4JGz0/s1600/mock.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGNRxp_OOs-Zm_rz2JFnHD23-ExynySJhm0zzW8ay32R9BWT6tWrWA7SbAGTytS_Z1TKWWK7IB-23U1VsRRC9qBhXbtFZePHreelPxu3beZ73R2_CxWtS2hZtkhVOSPr7Ftp1dSo4JGz0/s1600/mock.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">AppCode: if test target is not the last target I ran, errors are flying all over the tests code</td></tr>
</tbody></table>
<hr />
<span style="color: #274e13; font-family: Verdana, sans-serif; font-size: large;"><b><u>Git Integration (tie, simplicity vs. robustness)</u></b></span><br />
<span style="font-family: Verdana, sans-serif;">I must admit I like <b>Xcode's git integration</b>. It's <b>very simplistic</b> and therefore it's easy to use and understand. </span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;"><b>Simply type ⌘⌥C </b>and it opens a commit pane with the ability to diff everything and commit when you're done:</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOyyCuTTEfUEretPXHV2TN4JUp29UnQp2r81eKTC05fT2rZNAfC1Nt3qXqn3QXcIHg1m2Q8wMheT59Ia82Bh4oFwI8KlH298YJPLm6hvZI8WDosTMYPkJe8UTyBtRK83CTjXc6KzVCRg4/s1600/Xcode-13.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="403" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOyyCuTTEfUEretPXHV2TN4JUp29UnQp2r81eKTC05fT2rZNAfC1Nt3qXqn3QXcIHg1m2Q8wMheT59Ia82Bh4oFwI8KlH298YJPLm6hvZI8WDosTMYPkJe8UTyBtRK83CTjXc6KzVCRg4/s640/Xcode-13.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Xcode's commit windows: do everything from one place</td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">So if you're looking for simplicity, and not afraid to use command line or a different GUI for the more complex git operations, Xcode is the better choice. </span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">However, if you're looking for <b>robustness</b> and doing-everything-from-one-place, <b>AppCode's git integration</b> is better.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHRYasytazSgZ1QT1jlER_PgQBPqx9rEDX_jBYwLIb1gqAJU9eK7RvOEYmWr0oCW8Bd2dAlNxQUP8ahwHxgAeuivfVF9wAmJOdkpt2OGFkoTJwE_SBuXb4GmSIgPupefj6TRweFOr8JUk/s1600/MyNewClass.h+-+%5B~_dev_code_examples_tweejump%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="167" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHRYasytazSgZ1QT1jlER_PgQBPqx9rEDX_jBYwLIb1gqAJU9eK7RvOEYmWr0oCW8Bd2dAlNxQUP8ahwHxgAeuivfVF9wAmJOdkpt2OGFkoTJwE_SBuXb4GmSIgPupefj6TRweFOr8JUk/s320/MyNewClass.h+-+%5B~_dev_code_examples_tweejump%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567.png" width="320" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">AppCode's Changes view</td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">First of all, AppCode has <b>o</b></span><span style="font-family: Verdana, sans-serif;"><b>ther source-control systems</b> supported, like SVN (didn't try them though)</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Second, you pretty much get <b>full git support</b> and not simply diff/status/commit like in Xcode. You can stash, annotate, push, rebase, etc.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Finally, the commit window itself is very powerful:</span><br />
<br />
<ul>
<li><span style="font-family: Verdana, sans-serif;">Unlike Xcode, it <b>saves the previous commit message</b> you entered, even if you cancelled a commit because you remembered you need to add something.</span></li>
<li><span style="font-family: Verdana, sans-serif;">You can tell it to <b>automatically</b> Optimize Imports, run code inspection, or warn you about TODOs you added (which is good if you regard your TODOs as "TODO before committing") on affected files <b>before committing </b>them</span></li>
</ul>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1arCDs8dvxGiiE2cknZP8dKDlROF7SzZXeYAtFYG_u6Fv6QyI4ZcjTvU11BOK6jLgFbYCC9B9X2Uncx970sN8rKa_5Qyud5hRK5TPXV92LgMrvj5iIvi1fTiKMNZ6rUxA0K8sD7L6cV4/s1600/AppCode.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="527" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1arCDs8dvxGiiE2cknZP8dKDlROF7SzZXeYAtFYG_u6Fv6QyI4ZcjTvU11BOK6jLgFbYCC9B9X2Uncx970sN8rKa_5Qyud5hRK5TPXV92LgMrvj5iIvi1fTiKMNZ6rUxA0K8sD7L6cV4/s640/AppCode.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">AppCode's commit dialog - cool "Before Commit" options</td></tr>
</tbody></table>
<div>
<span style="font-family: Verdana, sans-serif;"><br /></span></div>
<br />
<span style="font-family: Verdana, sans-serif;">The final parameter that Xcode and AppCode differs by, and there's a small win for AppCode in, is <b>the diff window</b>.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Both IDEs has a <b>full-featured editor</b> in the diff window, which is something I find extremely important and lacking in some other IDEs (like Eclipse for Java).</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">The reason AppCode wins here, is because you have <b>special keyboard shortcuts</b> for going to the next diff ( <b>F7</b> ), or to the next file in diff ( <b>⌘⇧] </b>).</span><br />
<hr />
<span style="color: #274e13; font-family: Verdana, sans-serif; font-size: large;"><b><u>Disaster Recovery (AppCode)</u></b></span><br />
<span style="font-family: Verdana, sans-serif;">Local history and snapshots are a very important thing, especially when you lack the "commit often" discipline when working with version-control.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Both have this feature (called <b>Local History</b> in <b>AppCode</b> and <b>snapshots</b> in <b>Xcode</b>). </span><br />
<span style="font-family: Verdana, sans-serif;">The difference is that Xcode snapshot are pretty much only if you told it to make them (which is the default for operations like rename or massive replace), and in AppCode they are done by default for every 'git pull', refactor, a run of all the tests or even regular edit:</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYtazixi0O5hEYazSm9DagW3wV12UbdkNhVG0BRvaU8GMuYYguExKzCQVCjMzsHD_geVVbG5w-f-R22_ngw3uhzAG4WNLDw3qqZlws07_-wGmk2yc0kqMwYyEWdfkaFHtjP5WoaAMZG1o/s1600/_Users_yonits_sdks_Sparrow-Framework_sparrow_src_Classes_SPDisplayObject.m.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" height="310" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYtazixi0O5hEYazSm9DagW3wV12UbdkNhVG0BRvaU8GMuYYguExKzCQVCjMzsHD_geVVbG5w-f-R22_ngw3uhzAG4WNLDw3qqZlws07_-wGmk2yc0kqMwYyEWdfkaFHtjP5WoaAMZG1o/s640/_Users_yonits_sdks_Sparrow-Framework_sparrow_src_Classes_SPDisplayObject.m.png" width="640" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">AppCode's Local History view: saved my ass in many occasions...</td></tr>
</tbody></table>
<hr />
<span style="color: #274e13; font-family: Verdana, sans-serif; font-size: large;"><b><u>Run Configurations (tie)</u></b></span><br />
<span style="font-family: Verdana, sans-serif;">Xcode makes it <b>easier to switch</b> between device/simulator/tests (you simply choose from the schemes menu). </span><br />
<span style="font-family: Verdana, sans-serif;">Also, <b>running all the unit tests</b> in the project is always done via </span><span style="font-family: Verdana, sans-serif;">⌘U and you <b>don't need to define it</b>. </span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;"><b>AppCode 1.5 </b>improved from its predecesor in this area, but still you need to go through a <b>configuration pane</b> in order to define a new run configuration (on device/on simulator/all tests/...). </span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">However, this needs to be done <b>only once</b>. Once you configure it, you can quickly choose from your configurations using <b>⌃⌥R</b> (or </span><span style="font-family: Verdana, sans-serif;"><b>⌃</b></span><span style="font-family: Verdana, sans-serif;"><b>⌥D</b> for debug), and that's fun:</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtDcDye9-ud8IBj7GqTdBYJ_7nVE02IWHs0umOXDFiSSpdHfwpYun7hg36pdx04bG3_rzgy0UVMh4pd92xetvQJSRROEWETGfcUrr4ZjFRrD3FsbL2KwQ-xY37pKRkcVv_4rUI9AI-8TE/s1600/SPPoolObjectTest.m+-+Sparrow+-+%5B~_sdks_Sparrow-Framework_sparrow_src%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtDcDye9-ud8IBj7GqTdBYJ_7nVE02IWHs0umOXDFiSSpdHfwpYun7hg36pdx04bG3_rzgy0UVMh4pd92xetvQJSRROEWETGfcUrr4ZjFRrD3FsbL2KwQ-xY37pKRkcVv_4rUI9AI-8TE/s1600/SPPoolObjectTest.m+-+Sparrow+-+%5B~_sdks_Sparrow-Framework_sparrow_src%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">AppCode 1.5's "Run..." Menu: Activated with <span style="font-family: Verdana, sans-serif; text-align: -webkit-auto;"><span style="font-size: xx-small;">⌃⌥R</span></span> </td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<hr />
<span style="font-family: Verdana, sans-serif;"><b><u><span style="color: #274e13; font-size: large;">Debugger (Xcode)</span></u></b></span><br />
<span style="font-family: Verdana, sans-serif;">Both debuggers are <b>pretty similar</b>. I think AppCode's debugger may have a little more options, but I admit I never found myself using them too much.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">The one thing I do like better about Xcode's debugging abilities, is<b> exception handling</b>. This is not the default behavior, but something that is crucial and I did not find a way of achieving in AppCode, is the ability to <b>stop the program before it crashes with an uncaught Exception</b>, and figure out where the exception came from.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">In Xcode it is achieved as described in the following screenshot:</span><br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK9WV5iAugHbciS7fEVerOm0xkf_YKPVoLRlqj4bvYS9WMNDeIQlQxSyaewWSs5vealVBEXP0QJuRRgUr-P5JaFrFdEt4IjCqJgZQ9Fv7NbpXoXa92X_EuKqyuG_HaedRKwEJNxdAeoq8/s1600/Menubar.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK9WV5iAugHbciS7fEVerOm0xkf_YKPVoLRlqj4bvYS9WMNDeIQlQxSyaewWSs5vealVBEXP0QJuRRgUr-P5JaFrFdEt4IjCqJgZQ9Fv7NbpXoXa92X_EuKqyuG_HaedRKwEJNxdAeoq8/s1600/Menubar.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Xcode's exception breakpoint. Could not find this in AppCode</td></tr>
</tbody></table>
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<hr />
<span style="color: #274e13; font-family: Verdana, sans-serif; font-size: large;"><b><u>Auto Line Wrapping and Indentation (Xcode)</u></b></span><br />
<span style="font-family: Verdana, sans-serif;">Both have pretty good auto-indentations features. Auto indenting a line or block key bindings are <b>⌃I in Xcode</b> and <b>⌃⌥I in AppCode</b>.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;"><b>AppCode's main advantage</b> is that you can tell it to<b> wrap automatically </b>when you pass the<b> right margin</b>.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;"><b>Xcode's win</b> here is because it simply <b>wraps smarter</b> most of the time (just try and see for yourselves...). I guess it might be configurable in AppCode, but still...</span><br />
<span style="font-family: Verdana, sans-serif;">Another cool thing in Xcode is that you can <b>increase or decrease indentation</b> <b>level</b> when your cursor is at the <b>middle</b> of the line, with </span><span style="font-family: Verdana, sans-serif;"><b>⌘]</b></span><span style="font-family: Verdana, sans-serif;"> or </span><span style="font-family: Verdana, sans-serif;"><b>⌘[</b> respectively.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">And of course, there's the awful <b>bug in AppCode</b> that causes it to <b>join long method names into one line</b> if you refactor->change signature for them (mentioned earlier).</span><br />
<span style="font-family: Verdana, sans-serif;"><b><u><br /></u></b></span><br />
<hr />
<span style="color: #274e13; font-family: Verdana, sans-serif; font-size: large;"><b><u>Miscellaneous Wins for Xcode</u></b></span><br />
<ul>
<li><span style="font-family: Verdana, sans-serif;"><b>You MUST use Xcode</b> if you want to use interface builder, plist editor, creating an .ipa file, and lots of other features you need during app development cycle.</span></li>
<li><span style="font-family: Verdana, sans-serif;"><b>Memory consumption</b> is generally lower, and often you need both Xcode and AppCode open so if you have less than 8GB RAM you're in a real trouble running AppCode.</span></li>
<li><span style="font-family: Verdana, sans-serif;">In Xcode, <b>command+click</b> goes either to the <b>definition or</b> to the <b>declaration</b> of a method, depending on the context. <b>In AppCode</b> it will always go to the declaration (⌘B will also work), and it was <b>harder for me to find</b> the "go to definition" shortcut because it's called "go to implementation", and it's <b>⌥⌘B</b>, but thanks to an anonymous commenter on this post now I updated this here and everybody knows so it's not so bad :)</span></li>
<li><span style="font-family: Verdana, sans-serif;">Easier to configure the <b>print margin</b>. In Xcode once you do it it's configured. In AppCode, took me some time to find it, but eventually I figured out that the special color of the print margin was off by default (configurable in the settings, search for "right margin" there).</span></li>
</ul>
<hr />
<span style="color: #274e13; font-family: Verdana, sans-serif; font-size: large;"><b><u>Miscellaneous Wins for AppCode</u></b></span><br />
<ul>
<li><span style="font-family: Verdana, sans-serif;">Has an </span><b style="font-family: Verdana, sans-serif;">indicator for the column number</b><span style="font-family: Verdana, sans-serif;"> the cursor is at (a must for any editor if you ask me... Xcode simply doesn't have it).</span></li>
<li><span style="font-family: Verdana, sans-serif;">I can't really prove it, but seems to <b>crash less often</b>. Especially when switching a lot between running unit-tests to running the app on the device.</span></li>
<li><span style="font-family: Verdana, sans-serif;">You can easily know if a method is implementing/overriding/doesn't have a declaration:</span></li>
</ul>
<br />
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdHIoUDTWR5zNORmliUgKdVVMHDO_b7MrvkrsQFB46H81wbbXz81PdtnDWvUIcd-I2KDpZgPwcQOHCrcRylE6CwJummyTvQi_WmlTICOCFo_auRRCAqC9wgYGtg5XLp3rE1uJJ7IMX2j4/s1600/KLBSongsListRefreshingFromWebTableViewController.m+-+%5B~_dev_personal_KaraokeLiveBand-iOS_backstage_KaraokeLiveBand-BackStage%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdHIoUDTWR5zNORmliUgKdVVMHDO_b7MrvkrsQFB46H81wbbXz81PdtnDWvUIcd-I2KDpZgPwcQOHCrcRylE6CwJummyTvQi_WmlTICOCFo_auRRCAqC9wgYGtg5XLp3rE1uJJ7IMX2j4/s1600/KLBSongsListRefreshingFromWebTableViewController.m+-+%5B~_dev_personal_KaraokeLiveBand-iOS_backstage_KaraokeLiveBand-BackStage%5D+-+JetBrains+AppCode+(AppCode)+OC-112.567.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">AppCode's "Go To..." Icons. <br />
If there's no icon you know it's not declared anywhere and you should use quick-fix to add it to your private category.</td></tr>
</tbody></table>
<hr />
<b><span style="color: purple; font-family: Verdana, sans-serif; font-size: x-large;"><u>Conclusion</u></span></b><br />
<span style="font-family: Verdana, sans-serif;"><b>AppCode</b>, like other products from JetBrains, has <b>pretty much everything you expect</b> from a decent IDE and more.</span><br />
<span style="font-family: Verdana, sans-serif;"><b>Xcode</b> is no sucker as well, but really <b>lacks</b> when it comes to <b>refactoring</b>, <b>quick-fix</b>, etc.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Also, like other products from JetBrains - all the <b>project structure</b>, dependencies, etc. is <b>very cumbersome</b>. In Xcode it's no picnic as well, but at least everything works eventually.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;"><b><u>My recommendation: </u></b></span><br />
<span style="font-family: Verdana, sans-serif;">If you haven't done so, <b>try out AppCode</b> and enjoy it.</span><br />
<span style="font-family: Verdana, sans-serif;">Then, <b>s</b></span><span style="font-family: Verdana, sans-serif;"><b>tart your projects in Xcode</b> - configure everything there, but when you're on a <b>streak of writing a lot of code</b> and not too much messing with project configuration and hardcore debugging - <b>do it in AppCode</b>. Whenever you do an operation that requires some special configuration (such as introducing new frameworks or a new project dependency) - move to Xcode, do the necessary stuff - and go back to AppCode.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<span style="font-family: Verdana, sans-serif;">Maybe the most important win for AppCode it that it is <b>fully Xcode compatible</b>, meaning that the move between the IDEs is so smooth that I wouldn't worry about <b>at least giving it a try</b> - you can always change your mind and go back and forth to Xcode smoothly.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span><br />
<hr />
<span style="font-family: Verdana, sans-serif;">Liked this post? Great!</span><br />
<span style="font-family: Verdana, sans-serif;">Please spread the word, <a href="http://codesheriff.blogspot.com//feeds/posts/default" target="_blank">subscribe to my feed</a> and <a href="http://twitter.com/#%21/theyonibomber" target="_blank">follow me on twitter</a>.</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span>
<br />
<hr />
<span style="font-family: Verdana, sans-serif;"><b>EDIT (updates since writing the post):</b></span><br />
<br />
<ul>
<li><span style="font-family: Verdana, sans-serif;">The bug of AppCode removing line wraps when renaming a long method is solvable by configuring it in Settings -> Code Style -> Objective C -> Wrapping and Braces</span></li>
<li><span style="font-family: Verdana, sans-serif;">Xcode DOES have a Find Action feature, it's the "Search" in the Help menu. Unfortunately - no default key bindings.</span></li>
<li><span style="font-family: Verdana, sans-serif;">Found something else? Write it in the comments, and I promise to monitor it and keep this post as updated as possible.</span></li>
</ul>Anonymoushttp://www.blogger.com/profile/06100813770559493046noreply@blogger.com31tag:blogger.com,1999:blog-3833072356413502019.post-3065841254172486552011-12-28T07:35:00.000+02:002014-01-04T13:29:29.214+02:00Excuse #6 - We are such good programmers, we don't need tests!Welcome to the 6th excuse in the <a href="http://codesheriff.blogspot.com/2011/03/testing-why-bother-introduction.html" target="_blank">Testing: Why Bother?</a> series.<br />
<br />
I'm going to address this excuse a little bit differently than the other ones and be more personal about it.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdDFMMZcPWOMjwodGxZMCBUQw1XcyqAtv_rVT5Y_K_htWnzr_pOKRUaUqqYaoPIQ40vfX89PEwVJoR2V1sjs-m_hI6C3dXyy3P4tgYPVwRhQnLjYVij0V8HO7_HFKtO8eRiWt8iJqaaDp_/s1600/StoryTimeIcon.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdDFMMZcPWOMjwodGxZMCBUQw1XcyqAtv_rVT5Y_K_htWnzr_pOKRUaUqqYaoPIQ40vfX89PEwVJoR2V1sjs-m_hI6C3dXyy3P4tgYPVwRhQnLjYVij0V8HO7_HFKtO8eRiWt8iJqaaDp_/s1600/StoryTimeIcon.gif" /></a></div>
<br />
<br />
Reading the headline of this excuse may sound dubious to some of you, but I assure you it's not something I made up. I actually heard this excuse while I was looking for a job a while back and was interviewing for a startup company.<br />
<br />
<a name='more'></a><br /><br />
Something I tend to do during interviews (and I think all job candidates must do as well), is to <b>be a little bit of an interviewer </b>myself - asking some questions about the nature of the team I'm about to join, to see if there's a good fit to what I'm looking for in a work environment.<br />
<br />
For me, one of these questions will always be <b>"How do you feel about unit tests?"</b><br />
I often get an answer like: "we don't really write those, but we are open for change in that matter". This is actually the common answer I get and one of the answers that I live with quite happily. However, I once got a completely different answer, that inspired some of the excuses in this series, and this excuse in particular, as I did not meet any other interviewer so confident to claim such a statement.<br />
<br />
<b>"</b><i><b>Our recruitment process is one of the hardest there is. It's simply impossible to get accepted if you're not a 'rockstar', and therefore we have a team of amazing developers. This way we ensure excellent code quality and zero bugs, and therefore writing tests is simply superfluous".</b></i><br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.amazon.com/gp/product/B001V9OCR6/ref=as_li_tf_il?ie=UTF8&tag=thecodshe-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=B001V9OCR6" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://images4.cpcache.com/product/82606044v4_240x240_Front_Color-Black.jpg" /></a></div>
<br />
<br />
<br />
While I believe it's true that a challenging job candidate screening process is an excellent way to ensure better quality products in any field and any company, I found this reasoning a bit absurd, for 3 reasons:<br />
<br />
<span style="font-size: large;"><b>1) Consider the opposite situation</b></span><br />
The first odd thing about this claim, is that by this reasoning, all mediocre developers should write a lot more tests than those 'rockstars', because they NEED those tests in order to reveal all the bugs they cause. <br />
<br />
However, you actually <b>must be a decent developer </b>in order to be successful in writing good tests that reveal bugs, or else, the <a href="http://codesheriff.blogspot.com/2011/04/excuse-2-writing-tests-is-too-hard.html" target="_blank">writing tests is too hard excuse</a> is probably justified in your case.<br />
<br />
Also, developers who write tests are usually the ones who care enough and are passionate enough about software development in order to make that extra effort, and IMO that alone makes them better in what they do.<br />
I mean, <b>can you honestly tell me there's a development job you wouldn't hire names like Uncle Bob Martin and Kent Beck, etc. to do?</b><br />
<br />
So, I might have not proved my interviewer's claim wrong by this explanation, but I think you'll agree that by looking at the argument from this angle you see it's quite paradoxical, as it's not likely that if the entire team were lousy developers the team's attitude towards tests would improve.<br />
<br />
On a side note about this reason, there was a similar claim by Tomas in the comment of <a href="http://codesheriff.blogspot.com/2011/11/excuse-5-frequent-refactoring-excuse.html">my previous post in the series</a>. I think you'll find the discussion interesting.<br />
<br />
<span style="font-size: large;"><b>2)</b> <b>Everyone has bugs!</b></span><br />
I'm sure that was the immediate response for most of you.<br />
You are simply misleading yourself if you think that the people you hired aren't going to have bugs.<br />
<br />
We are all human, we all make mistakes, and heck - I'm sure even if we build a perfect robot programmer it would have some bugs in its software, as the definition of a bug might be simply a change in requirements, and not a human error of forgetting to deal with a null pointer.<br />
<br />
It's true - better developers are often quicker on catching bugs. they tend to make less mistakes and get to working software faster (therefore - they are better developers), but sometimes <b>the way they achieve that special ability of writing bug-less code quickly, is simply by testing it</b>. Does this by definition make them worse developers? I think not.<br />
<br />
<span style="font-size: large;"><b>3) REGRESSION!</b></span><br />
If you are following my list of excuses, you should be familiar with this "excuse killer" by now. <br />
It's not only about finding the bug now, it's about ensuring the programmer who comes after you is not going to encounter it again.<br />
Sure, now your team is assembled from amazing programmers who know all about their code and never make mistakes. But what's going to happen when a new programmer enters the project? Even if she is a rockstar developer herself, she still might lack the understanding of what the original author of that piece of code had in mind, and therefore might make a mistake in interpretation = a bug.<br />
<br />
<div class="separator" style="clear: both; text-align: right;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4dGPyXVFHQTeUG4OBawu3Tz-HWoN_OxcrQk5v227QnYV3tvlasRLbLHaCrPZ2-vMXm1NW7jEhFTMfkUZFkBfw0oOC0m6QqzoSd5ox_7bdNsAbPIR5ZnkcNfjY_Fr8ltdbbvgKDG425IE/s1600/how_do_you_feel_about_tests.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4dGPyXVFHQTeUG4OBawu3Tz-HWoN_OxcrQk5v227QnYV3tvlasRLbLHaCrPZ2-vMXm1NW7jEhFTMfkUZFkBfw0oOC0m6QqzoSd5ox_7bdNsAbPIR5ZnkcNfjY_Fr8ltdbbvgKDG425IE/s320/how_do_you_feel_about_tests.png" width="320" /></a></div>
<br />
<br />
So, I hope you take something from this post. If it's the idea of asking "how do you feel about unit tests" in your job interview (great ice breaker on the "do you have any questions for us?" phase), if it's understanding that better developer != doesn't write tests, or if it's just getting to know me better by a personal story about a job I didn't take.<br />
<br />
Anyways, it would be awesome if you'll spread the word about my blog, <a href="http://codesheriff.blogspot.com//feeds/posts/default%20" target="_blank">subscribe to my feed </a>and <a href="http://twitter.com/#%21/theyonibomber" target="_blank">follow me on twitter</a> :)Anonymoushttp://www.blogger.com/profile/06100813770559493046noreply@blogger.com4tag:blogger.com,1999:blog-3833072356413502019.post-71645027449658267252011-12-12T14:49:00.000+02:002014-01-04T13:29:52.275+02:00Excuse #5 - The Frequent Refactoring ExcuseWelcome to the 5th excuse in the <a href="http://codesheriff.blogspot.com/2011/03/testing-why-bother-introduction.html" target="_blank">Testing: Why Bother?</a> series:<br />
<b><i>"We <a href="http://en.wikipedia.org/wiki/Code_refactoring" target="_blank">refactor</a> our code so frequently, that the time we invest in tests just isn't worth it - they are going to change and be irrelevant anyhow"</i></b> <b><br /></b><br />
<br />
This excuse is one of my favorites, because it's so ironic, yet surprisingly quite common.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVQbALvlA1HlxZMK6FCkVz4N7OIlGp4018o5dEFOpBy9f7T0Ra_cpLDn-bMgKeIH3BovcOcbq6oj34gJz6q5oGwsJ7iUYfUfam8LW8-axIWLvxaij9jGL5Il7QjjnEpbUx7A1wr3EnYx8/s1600/refactoring_irony.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVQbALvlA1HlxZMK6FCkVz4N7OIlGp4018o5dEFOpBy9f7T0Ra_cpLDn-bMgKeIH3BovcOcbq6oj34gJz6q5oGwsJ7iUYfUfam8LW8-axIWLvxaij9jGL5Il7QjjnEpbUx7A1wr3EnYx8/s400/refactoring_irony.png" width="400" /></a></div>
<br />
<a name='more'></a><br /><br />
<br />
<b>You are constantly refactoring your code? Without tests?? How can you be certain you didn't break anything???</b><br />
As I mentioned in previous posts, the number one reason for automated tests as I see it, is <b>REGRESSION</b>. It gives the programmer the <b>confidence </b>of changing a piece of code without being afraid of possible side-effects, because if change introduces new bugs - good regression tests will immediately find them.<br />
<br />
I totally agree that constantly improving your code quality and the design is a very important phase of developing dynamic software that responds well to changes in requirements. But <b>it's that simple </b>- you should <b>NEVER refactor without tests </b>to back you up.<br />
Quoting from Martin Fowler & Kent Beck's great book <a href="http://www.amazon.com/gp/product/B000OZ0N4Y/ref=as_li_tf_tl?ie=UTF8&tag=thecodshe-20&linkCode=as2&camp=217145&creative=399373&creativeASIN=B000OZ0N4Y" target="_blank">Refactoring: Improving the Design of Existing Code</a>: <i>"If you want to refactor, the <b>essential precondition </b>is having solid tests."</i><br />
<br />
<br />
Furthermore, for most refactoring operations, when you use refactor-friendly IDEs, performing a simple refactoring operations such as rename, change method signature, etc. will be almost painless, as it will make the necessary changes in your tests' code as well.<br />
<br />
<b><i>"Yeah but... Still... Every time I change my code I feel like I have to re-write all my tests, and then the ROI of testing vs. debugging seems to not be worthwhile any more".</i></b><br />
Well... If you are talking from actual experience, and these are more than just fears, you may be "doing it wrong", and should ask yourself the following questions:<br />
<br />
<b>1) Are my tests too much low-level?</b><br />
Often, tests that you feel you need to maintain too much and change for every little change in production code, present a <b>code smell</b>.<br />
Is this test passing if your implementation was with a for loop, but when you replaced it with recursion it failed? This means you were testing too low.<br />
<br />
If a refactoring step caused a test that shouldn't care about inner implementation but only about the final outcome to fail, try re-writing the test by <b>using your code at a higher level</b> (e.g. test the public method and not the "helper" that should be only used internally)<br />
<br />
<b>2) Do I have irrelevant data in my tests?</b><br />
This does not refer only to refactoring, but to a very common cause for high-maintenance test code, are tests that fail because you changed the value of data that should be irrelevant to the functionality you are checking for.<br />
I highly recommend <b><a href="http://blog.thecodewhisperer.com/2010/01/14/what-your-tests-dont-need-to-know-will-hurt-you" target="_blank">the following post</a> </b>by <b>@jbrains</b> for further information about what the problem exactly is and how to deal with it.<br />
<br />
<b>3) Are your refactoring steps too big? (Is it actually a "rewrite"?)</b><br />
I often got to hear the frequent refactoring excuse referred to as frequent "re-writes". Rewrites, as opposed to refactoring, is something I suffered a lot of pain from in the past.<br />
Instead of working your way one small change at a time, you decide to "<i>throw all this subsystem's code away and start over</i>".<br />
<br />
This usually turns out to be an adventure you regret every moment of getting into: all the old bugs (and many new ones) you encountered while developing the subsystem in the first place come back, and slowly but steady, the <b>spaghetti situation in your code reoccurs</b>, until you decide to have another rewrite - which starts the same cycle once again.<br />
<br />
I don't believe on rewriting working software. I believe in <b>refactoring in small steps</b>, making sure nothing was broken after each step by running all tests. This way - the pain of maintaining the tests now becomes a piece of cake - as <b>you know exactly what was changed in the latest step </b>and you can deal with it.<br />
<br />
If you don't have tests - well... I would start by adding them, making the minimal changes in production code to make it testable, and only then getting into this whole refactoring process (well.. that's my point in this whole post).<br />
<br />
<b>EDIT:</b> actually, this is a bit harsh, in some cases rewrite may be the right thing to do. Read Nimi's comment and my response for it.<br />
<br />
<span style="font-size: x-large;"><b>In conclusion</b></span><br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoS0ENZN7Aud4A5Z74lA7Yeih8vmScWNQWP5P1wT6a8dOTNxfUZ6vDO0PLP2vcVpBHIZCxQEb8rObDHEaZld3vRYYK0-lEha04i5j-1jCJdc_U5-V8xe5qKKvHRjos7UiigOHXbro47is/s1600/ironic.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="212" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoS0ENZN7Aud4A5Z74lA7Yeih8vmScWNQWP5P1wT6a8dOTNxfUZ6vDO0PLP2vcVpBHIZCxQEb8rObDHEaZld3vRYYK0-lEha04i5j-1jCJdc_U5-V8xe5qKKvHRjos7UiigOHXbro47is/s320/ironic.png" width="320" /></a></div>
<br />
Tests should be a prerequisite for any refactoring adventure, so this excuse is <b>full of irony, </b>and if you really feel the pain of maintaining your tests while refactoring, <b>not writing tests is definitely not the solution.</b><br />
<br />
Another problem this excuse reveals, is <b>why do you feel you are frequently changing everything in your code in the first place? </b>Should you develop a better response-to-change-in-requirements mechanism? Or maybe you don't invest enough time to ensure quality of code in the first round of writing it? Maybe if you were using <b>TDD </b>it would help?<br />
<br />
Think about it...<br />
<br />
In the meanwhile, you should make sure you read all the previous excuses in the series, stay tuned for more, and <a href="http://twitter.com/#%21/theyonibomber" target="_blank">follow me on twitter</a>.Anonymoushttp://www.blogger.com/profile/06100813770559493046noreply@blogger.com16tag:blogger.com,1999:blog-3833072356413502019.post-51473951761947217732011-11-04T23:52:00.000+02:002014-01-04T13:30:08.112+02:00Excuse #4 - Running the tests takes foreverSo, after a long break (been focusing my time on <i>reading</i> about new technologies rather than <i>writing</i> - started a new job @ <a href="http://www.joytunes.com/" target="_blank">JoyTunes</a>...) I'm back with the next excuse in the "<a href="http://codesheriff.blogspot.com/2011/03/testing-why-bother-introduction.html" target="_blank">Testing, Why Bother?</a>" series.<br />
<br />
<a href="http://tasap.files.wordpress.com/2010/10/daylight-savings-time11.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="190" src="http://tasap.files.wordpress.com/2010/10/daylight-savings-time11.jpg" width="200" /></a><b><span class="Apple-style-span" style="font-size: large;"><i>"Running the tests takes too much time, </i></span></b><br />
<b><span class="Apple-style-span" style="font-size: large;"><i>so we never run them anyhow."</i></span></b><br />
<b><span class="Apple-style-span" style="font-size: large;"><i><br /></i></span></b>
<b><br /></b>
Well, this excuse is less common than the other ones on the list, and to tell the truth - if that's your case, you're in a pretty good spot - because, <b>at least you have tests to run</b>!<br />
<br />
However, if you have tests and you're not running them, they obviously have little merit, so the effort of writing them goes to waste, which is definitely a shame.<br />
<br />
So here are a few tips on how you can solve this tricky situation.<br />
<br />
<a name='more'></a><br /><br />
<b><span class="Apple-style-span" style="font-size: large;">You don't have to run the tests yourself!</span></b><br />
<b><span class="Apple-style-span" style="font-size: large;"><span id="goog_768188017"></span><span id="goog_768188018"></span></span></b><br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiezQmyA4cVeRzLeUq-G2W4BMjMzWuCqBUg9lSDwlUPVNSl6O3dHZMiLgUGyBVb5wf7NcpUoTWVPzLLW40aCYyytWoArcNUjMD1tKYZXOiOQ4G4YY0kyNcnARUjYGAR6aD3R8ocMUDJjZ0/s1600/jenkins-tests.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="157" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiezQmyA4cVeRzLeUq-G2W4BMjMzWuCqBUg9lSDwlUPVNSl6O3dHZMiLgUGyBVb5wf7NcpUoTWVPzLLW40aCYyytWoArcNUjMD1tKYZXOiOQ4G4YY0kyNcnARUjYGAR6aD3R8ocMUDJjZ0/s320/jenkins-tests.jpg" width="320" /></a></div>
<br />
The word <b>"automated"</b> in "automated testing" is the key. It means the <i>whole process</i> must be automatic, not only the tests themselves.<br />
If you don't have a <b>Continuous Integration</b> (CI) server that runs the tests yet, such as <a href="http://jenkins-ci.org/" target="_blank">Jenkins</a>, you should hurry up and setup one, because tests are just not the same without it.<br />
<br />
If you haven't heard of continuous integration, I highly recommend you read the book:<br />
<a href="http://www.amazon.com/gp/product/B0026772IS/ref=as_li_qf_sp_asin_il?ie=UTF8&tag=thecodshe-20&linkCode=as2&camp=217145&creative=399373&creativeASIN=B0026772IS"><img border="0" src="http://ws.assoc-amazon.com/widgets/q?_encoding=UTF8&Format=_SL110_&ASIN=B0026772IS&MarketPlace=US&ID=AsinImage&WS=1&tag=thecodshe-20&ServiceVersion=20070822" /></a><img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=thecodshe-20&l=as2&o=1&a=B0026772IS&camp=217145&creative=399373" style="border: none !important; margin: 0px !important;" width="1" />
<br />
<br />
In a nutshell, it means that <b>for each new revision</b> pushed into the source control management system (such as Subversion, git, ...), the <b>CI server wakes up </b>and starts a "build" for the project. Builds can automate very complicated things that are often done manually in the release process, and that's probably something I can write a whole set of blog posts about, but what is often done at the beginning of the CI build, is <b>running all the automated tests in the repository</b>, and sending e-mails to everyone involved in case the tests failed.<br />
<br />
This way, tests that are running for too long are a much lesser pain, as you don't really have to run them manually and wait for them to finish in order to know if they passed or not.<br />
<br />
<span class="Apple-style-span" style="font-size: large;"><b><i>"But I want to be able to run the tests manually as well"</i></b></span><br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://thenextweb.com/files/2009/11/manually.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="155" src="http://thenextweb.com/files/2009/11/manually.jpg" width="320" /></a></div>
<span class="Apple-style-span" style="font-size: large;"><b><i><br /></i></b></span>
That's a very good point. Tests are not only to be run automatically by a CI server <b>after</b> they are already in the repository. You often want to run them while you're working, from your IDE, in order to know that the latest line of code you changed didn't break any logic that was working previously.<br />
<br />
Well, here are a few tip regarding how to speed up your automated tests:<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Make sure you don't set up any unnecessary environment</span></b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjg02Vpc0IcZy6LIJ9LYcEj0kLtF-nkUHV-z2nlirjgy7OdpbKJf2CMiz9irmAk1WZlEdhSE3Ed97cOD_bmI79klQojE9vSIYkJQL8A4jlHeG43kZ-2wAu6NYlvp2-LugLt83yM6v-x-5A/s1600/mock_environment.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjg02Vpc0IcZy6LIJ9LYcEj0kLtF-nkUHV-z2nlirjgy7OdpbKJf2CMiz9irmAk1WZlEdhSE3Ed97cOD_bmI79klQojE9vSIYkJQL8A4jlHeG43kZ-2wAu6NYlvp2-LugLt83yM6v-x-5A/s200/mock_environment.jpg" width="196" /></a></div>
<br />
Unit tests should be testing a single component separated from its context. So - if your tests have to set up 5 DB connections, open some sockets, read a bunch of XMLs and instantiate 100 objects just to run a simple functionality test on the tested component - you're doing it wrong!<br />
<br />
If you design your code in a way that you don't have to use real environment and you can easily substitute external interfaces with mock objects (e.g. avoid evil DbConnectionManager singletons), it should be easy to save a lot of setup time for your tests.<br />
<br />
If however, you feel you MUST use real environment for a specific test - make sure you only set it up once, in the global setup of your Test Suite (e.g. @BeforeClass in JUnit), and not before every test function...<br />
<b><br /></b>
<b><span class="Apple-style-span" style="font-size: large;">Mock irrelevant operations that take to much time</span></b><br />
<a href="http://www.amazon.com/gp/product/0262720310/ref=as_li_qf_sp_asin_il?ie=UTF8&tag=thecodshe-20&linkCode=as2&camp=217145&creative=399369&creativeASIN=0262720310" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://ws.assoc-amazon.com/widgets/q?_encoding=UTF8&Format=_SL110_&ASIN=0262720310&MarketPlace=US&ID=AsinImage&WS=1&tag=thecodshe-20&ServiceVersion=20070822" /></a><img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=thecodshe-20&l=as2&o=1&a=0262720310&camp=217145&creative=399369" style="border: none !important; margin: 0px !important;" width="1" />
<br />
<div style="direction: ltr;">
<br />
This is pretty much similar to the previous tip, but this time I'm talking about mocking calls to some kind of 3rd party API or external interface.</div>
<div style="direction: ltr;">
<br /></div>
<div style="direction: ltr;">
Simply replace calls to the external interfaces with a mock that returns a value, without having to wait for the small 3rd party calls to finish before moving on with your test.</div>
<div style="direction: ltr;">
<br /></div>
<div style="direction: ltr;">
One interesting way of achieving this, is by taking an <b>Integration Test</b> that's already testing your component from a higher level, <b>recording</b> all the calls to external interfaces and APIs, and then <b>replaying</b> all the results in a unit-test of your component, that takes much less time.</div>
<div style="direction: ltr;">
There are some frameworks that may help you with this, like <a href="http://texttest.carmen.se/index.php?page=capturemock" target="_blank">CaptureMock</a> for python.</div>
<b><br /></b>
<b><span class="Apple-style-span" style="font-size: large;">Separate the Integration Test Suite from the Unit Test Suite</span></b><br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYdNbuHkB5bt8fUy1sd8VMuH0s_MGXnvOdZUy44T96Z9A-DI3b_PIH3zuGUrp4HWK189pvMc8XtbNGbQvGlLuEkMxs32bpyzDyiQ5ka9wWy6jtj2UQBy6kOPUPUayz31I2lbP9zOMK-Zk/s1600/unit-tests-in-line.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYdNbuHkB5bt8fUy1sd8VMuH0s_MGXnvOdZUy44T96Z9A-DI3b_PIH3zuGUrp4HWK189pvMc8XtbNGbQvGlLuEkMxs32bpyzDyiQ5ka9wWy6jtj2UQBy6kOPUPUayz31I2lbP9zOMK-Zk/s320/unit-tests-in-line.jpg" width="296" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Unit Tests in line for some CPU time...</td></tr>
</tbody></table>
<br />
This may come as trivial for a lot of you, but I've seen many violations of this principal.<br />
As said, the Unit Test Suite should be no more than a few seconds to run, in order for us to be able to quickly run them and make sure we didn't break anything in our code.<br />
<br />
If you have integration tests that take a lot of time - you don't need to run each time. Have a separate TestSuite for them, and make it run only in the CI server - and probably not after each build, but only before release candidates.<br />
<br />
<span class="Apple-style-span" style="font-size: large;"><b><br /></b></span>
<span class="Apple-style-span" style="font-size: large;"><b><br /></b></span>
<span class="Apple-style-span" style="font-size: large;"><b><br /></b></span>
<span class="Apple-style-span" style="font-size: large;"><b><br /></b></span>
<span class="Apple-style-span" style="font-size: large;"><b>In conclusion</b></span><br />
Having slow tests is much better than having no tests at all, but is still a real pain - but a very treatable one. If you have any more ideas of how to speed up your tests, don't hesitate and share it in the comments!<br />
<br />
Stay tuned for more blog posts in the series, and make sure you read all the previous ones as well. I will try keeping 'em coming. If you haven't already, you should <a href="http://twitter.com/#!/theyonibomber" target="_blank">Follow me on twitter</a>.Anonymoushttp://www.blogger.com/profile/06100813770559493046noreply@blogger.com1tag:blogger.com,1999:blog-3833072356413502019.post-32631417028275594912011-08-22T21:29:00.020+03:002014-01-04T13:31:51.988+02:00TDD and Unit-Testing for Python DevelopersA few days ago, I gave a 1:30 hours long talk (in Hebrew) in my company about TDD and Unit-Testing for python developers.<br />
<br />
The idea was to focus both on what is TDD, including a 45 minutes demo, and to give some concrete tips for unit-testing in python.<br />
<br />
Usually when I give a talk about TDD, I use some kind of simple kata as a demo, like the prime factors kata of Uncle Bob. The problem with that, is I usually get responses like "TDD works only for calculators examples". I tried to be a little more original here and demonstrate a more real-life like example, and I tried not to come prepared too much, so I could demonstrate a genuine way of thinking about the design and letting it drive my code.<br />
Looking back, I think this caused the demo to be a little messy - I told the audience to participate and throw ideas in the middle, and this caused things to advanced a little bit too slowly, and we didn't really get to real value by the end of the demo (as opposed to using a simple kata when you get value by the end of 5-10 tests).<br />
<br />
For the tips sections, I took most of the material from Michael Foord's great blog and mocking framework: <a href="http://www.voidspace.org.uk/">http://www.voidspace.org.uk/</a>, and I think it should be very useful. So thank you for that Michael!<br />
<br />
Anyhow, apart from the messy demo - which I think is still educational - I feel like the talk went fine, and decided to share it.<br />
<br />
<span class="Apple-style-span" style="font-size: x-large;">The Talk</span><br />
Here's an unedited <b>screen and sound capture</b> of the talk, for the Hebrew speakers of you.<br />
<object data="http://content.screencast.com/users/theyonibomber/folders/Default/media/971481fd-245f-4a78-b741-815395920989/mp4h264player.swf" height="480" id="scPlayer" type="application/x-shockwave-flash" width="640"> <param name="movie" value="http://content.screencast.com/users/theyonibomber/folders/Default/media/971481fd-245f-4a78-b741-815395920989/mp4h264player.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#000000" />
<param name="flashVars" value="thumb=http://content.screencast.com/users/theyonibomber/folders/Default/media/971481fd-245f-4a78-b741-815395920989/FirstFrame.jpg&containerwidth=1024&containerheight=768&content=http://content.screencast.com/users/theyonibomber/folders/Default/media/971481fd-245f-4a78-b741-815395920989/tdd_and_ut_for_python_dev.mp4&blurover=false" />
<param name="allowFullScreen" value="true" />
<param name="scale" value="showall" />
<param name="allowScriptAccess" value="always" />
<param name="base" value="http://content.screencast.com/users/theyonibomber/folders/Default/media/971481fd-245f-4a78-b741-815395920989/" />
<iframe type="text/html" frameborder="0" scrolling="no" style="overflow:hidden;" src="http://www.screencast.com/users/theyonibomber/folders/Default/media/971481fd-245f-4a78-b741-815395920989/embed" height="480" width="640" ></iframe> </object><br />
If you can't watch it through this shaky flash plugin, you can download it from <a href="http://content.screencast.com/users/theyonibomber/folders/Default/media/971481fd-245f-4a78-b741-815395920989/tdd_and_ut_for_python_dev.mp4?downloadOnly=true">here</a><br />
<br />
<a name='more'></a><br /><br />
Unfortunately, you can barely hear what the audience is saying so you can't catch up on the audience interaction - I wanted to edit it a bit and add subtitles of these parts but I really can't see myself getting to do so any time soon, so I decided to share it as it is now rather than sharing an edited video never :)<br />
Also, there were some off screen interactions, unfortunately the video camera didn't work well so you wont be able to see them.<br />
<br />
If you only want <b>the slides (in English)</b>, you can access them here:<br />
<a href="https://docs.google.com/present/edit?id=0AaAaoNed4IPFZGZ2cHJocHZfMWQ2NmNmdGdr&hl=en_US">https://docs.google.com/present/edit?id=0AaAaoNed4IPFZGZ2cHJocHZfMWQ2NmNmdGdr&hl=en_US</a><br />
<br />
<span class="Apple-style-span" style="font-size: x-large;">Additional TDD material</span><br />
Per audience request, some useful links:<br />
<br />
<u><span class="Apple-style-span" style="font-size: large;">Recommended books:</span></u><br />
<u><a href="http://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530?ie=UTF8&tag=thecodshe-20&link_code=bil&camp=213689&creative=392969" imageanchor="1" target="_blank"><img alt="Test Driven Development: By Example" src="http://ws.amazon.com/widgets/q?MarketPlace=US&ServiceVersion=20070822&ID=AsinImage&WS=1&Format=_SL160_&ASIN=0321146530&tag=thecodshe-20" /></a><img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=thecodshe-20&l=bil&camp=213689&creative=392969&o=1&a=0321146530" style="border: none !important; margin: 0px !important; padding: 0px !important;" width="1" /><a href="http://www.amazon.com/Growing-Object-Oriented-Software-Guided-Tests/dp/0321503627?ie=UTF8&tag=thecodshe-20&link_code=bil&camp=213689&creative=392969" imageanchor="1" target="_blank"><img alt="Growing Object-Oriented Software, Guided by Tests" src="http://ws.amazon.com/widgets/q?MarketPlace=US&ServiceVersion=20070822&ID=AsinImage&WS=1&Format=_SL160_&ASIN=0321503627&tag=thecodshe-20" /></a><img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=thecodshe-20&l=bil&camp=213689&creative=392969&o=1&a=0321503627" style="border: none !important; margin: 0px !important; padding: 0px !important;" width="1" /></u><br />
<u><br />
</u><br />
<u><span class="Apple-style-span" style="font-size: large;">Additional TDD demos:</span></u><br />
<br />
<ul>
<li><b>A great one hour screencast by TekPub, hosting Brad Wilson: </b><a href="http://tekpub.com/view/ft_tdd_wilson/1">http://tekpub.com/view/ft_tdd_wilson/1</a><br />
It's a .NET TDD demo. What's so great about it is it's more of a real-life design example and not some calculator-like algorithmic example.<br />
</li>
<li><b>The string calculator kata in python:</b><br />
<u>requirements:</u> <a href="http://osherove.com/tdd-kata-1/">http://osherove.com/tdd-kata-1/</a><br />
<u>video:</u> <a href="http://katas.softwarecraftsmanship.org/?p=128">http://katas.softwarecraftsmanship.org/?p=128</a><br />
</li>
<li><b>Some Uncle Bob presentations:</b><br />
<a href="http://butunclebob.com/files/downloads/Prime%20Factors%20Kata.ppt">http://butunclebob.com/files/downloads/Prime%20Factors%20Kata.ppt</a><br />
<a href="http://butunclebob.com/files/downloads/Bowling%20Game%20Kata.ppt">http://butunclebob.com/files/downloads/Bowling%20Game%20Kata.ppt</a><br />
</li>
<li><b>The bowling kata as a script of a real demo:</b><br />
<a href="http://www.objectmentor.com/resources/articles/xpepisode.htm">http://www.objectmentor.com/resources/articles/xpepisode.htm</a><br />
</li>
</ul>
<div>
<span class="Apple-style-span" style="font-size: large;">Hope you found it useful...</span></div>
<div>
If you did, you should check out some other posts in this blog, and <a href="http://twitter.com/theyonibomber">follow me on twitter</a>.</div>
Anonymoushttp://www.blogger.com/profile/06100813770559493046noreply@blogger.com0tag:blogger.com,1999:blog-3833072356413502019.post-52680817225645333242011-08-02T23:29:00.007+03:002014-01-04T13:32:56.551+02:00Getting started with iOS developmentSo... In the last couple of weeks, I've been researching iOS development - reading some blogs, going to some lectures or watching them on iTunes U, searching for answers to common questions on stackoverflow, etc.<br />
This doesn't make me an expert on the subject, but I think if like me - you're thinking about starting with iOS development or mobile development in general, this post might save you some time and make sure you're not missing any of the important technologies available today (August 2011), and the information you need to know in order to get started.<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">Before You Start...</span></b><br />
<br />
<b>Do I have to own a Mac in order to develop for iOS?</b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://library.creativecow.net/articles/wilson_tim/win-mac2/mac128.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="230" src="http://library.creativecow.net/articles/wilson_tim/win-mac2/mac128.jpg" width="320" /></a></div>
<b><br />
</b><br />
<ul>
<li>In a word: <b>YES</b>.</li>
<li>There might be frameworks that will let you develop the applications without a Mac, but when you'll want to deploy on a real device, or to the app-store, you're going to need a Mac for that.</li>
<li>Even if you succeeded in creating a Hackintosh on a VM (I personally had a really hard time trying to do so...), it is not recommended - as you are going to have troubles once you'll need to update your software/OS version, etc.</li>
<li>I tried to find online solutions for "Mac for rent", and found macincloud.com, but 2 days after sending a request for a trial they announced they closed the site for new users.</li>
</ul>
<b></b><br />
<a name='more'></a><b><br /></b><br />
<b>Does it cost me money to develop iOS applications?</b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://t3.gstatic.com/images?q=tbn:ANd9GcTveWigU67yM3Sp5EWp5z-kj9PX6DrAilf8MBt2lvw8ft1kTM9n8Q" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://t3.gstatic.com/images?q=tbn:ANd9GcTveWigU67yM3Sp5EWp5z-kj9PX6DrAilf8MBt2lvw8ft1kTM9n8Q" /></a></div>
<b><br />
</b><br />
<ul>
<li>The <a href="http://developer.apple.com/programs/ios/">iOS Developer Program</a> costs 99$/year. It lets you have the development environment for free, and the ability to install your apps on up to 100 personal device, and deploying them to the App Store.</li>
<li>You can however, obtain xCode (the development environment) for 5$ in the Mac App Store, or get the 4.1 version comes free if you have OS X Lion. This will let you develop apps freely, and test them on the iPhone/iPad simulators. If you'd like to test them on a real device as well without paying the 99$, you'll have to jailbreak it first (which is a big No No if you're planning on deploying it to the App Store in the future).</li>
</ul>
<b>I'm considering deploying my app to android or other platforms as well. <br />
What kind of options do I have?</b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://t2.gstatic.com/images?q=tbn:ANd9GcQJOFhVxk1sfnEp7uO7r6khqtsMGn5BnzD6T7YsamNV-J5ijCK0NQ" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://t2.gstatic.com/images?q=tbn:ANd9GcQJOFhVxk1sfnEp7uO7r6khqtsMGn5BnzD6T7YsamNV-J5ijCK0NQ" /></a></div>
<b><br />
</b><br />
<ul>
<li>Well, it seems as if the most popular choice is simply to re-write your app for the other platforms using the platform's native framework + SDK. This might sound surprising, but understandable once you think about the downsides of the cross-platform solutions available today.</li>
<li>Notice that because both Java (Android) and Objective-C (iOS) can integrate with C/C++ code, writing at least some layers of your application in C/C++ will make it easier to port it to other platforms.</li>
<li>This is also true about web applications. Nowadays, all smartphones and tablets have the capability of displaying web content such as HTML5/CSS3/Javascript. Therefore, writing your app as a web application or at least having a web container that runs web content as part of your native app, will make it available for other platforms freely, or at a very low cost. There are also some frameworks that will facilitate your efforts writing such apps, that will be discussed later on this post.</li>
<li>Even though there are some downsides, there is a variety of available frameworks for developing cross-platform apps, and I'm going to discuss all the notable ones later on this post.</li>
</ul>
<b>So, what are the downsides of using a cross-platform solution?</b><br />
<ul>
<li><b>Native Features:</b> Most of the available cross-platform solutions won't let you access all the native features of the hardware. For instance, if you want to record real-time data from your microphone or camera, you'll have to write native code that does it, even if your basic framework is cross-platform.</li>
<li><b>Performance:</b> Like cross-platform solutions on the PC, a cross-platform solution in mobile devices comes with a performance overhead, some more than others.</li>
<li><b>User Experience:</b> Your UI will fail to address the special look-and-feel and the specific features of a given platform, like the 4 physical buttons that exist in Android vs. the single home button in iPhone, which will surely feel awkward to the user.</li>
</ul>
<b>Why iOS and not Android?</b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://t1.gstatic.com/images?q=tbn:ANd9GcRZtxaO1eD0S-6hxbyOmTyb3PunBmwboEtnBMBMm5fNeWfqDweeIg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://t1.gstatic.com/images?q=tbn:ANd9GcRZtxaO1eD0S-6hxbyOmTyb3PunBmwboEtnBMBMm5fNeWfqDweeIg" /></a></div>
<b><br />
</b><br />
<ul>
<li>While following smule, a great music-related iOS app developers, I found an interesting post they shared about why they don't develop applications to Android:<br />
<a href="http://tech.fortune.cnn.com/2011/05/27/why-its-harder-to-make-money-on-android-than-on-apples-ios/">http://tech.fortune.cnn.com/2011/05/27/why-its-harder-to-make-money-on-android-than-on-apples-ios/</a></li>
<li>Another thing they claimed, is that it's impossible to do real-time audio processing in Android due to high latency: <i>"right now if you create an app for android that just routes the audio from the microphone to the speaker, there will be a noticeable delay, even on the devices with fast processors. This is a problem because if you want to make an app like 'I Am T-Pain' then it becomes impossible from a user experience standpoint to do live vocal processing. Put another way, hearing your voice come out of the speaker delayed creates a user experience that is not on par with that which we've been able to create on iOS.</i> - this is a major problem if -- like I do -- you want to include real-time audio processing in your applications.</li>
<li>On the other hand, it seems that the majority of the mobile devices in the market is soon going to be Android's: <a href="http://www.mofonu.com/2011/07/15/android-devices-130-million-and-growing-%E2%80%93-550000-devices-activated-everyday/">http://www.mofonu.com/2011/07/15/android-devices-130-million-and-growing-%E2%80%93-550000-devices-activated-everyday/</a></li>
</ul>
<b><span class="Apple-style-span" style="font-size: large;">Native iOS Development Technologies</span></b><br />
<br />
<b>Some useful links to get you started</b><br />
<ul>
<li>I highly recommend Stanford's iOS development videos in iTunes U: <a href="http://itunes.apple.com/us/podcast/cs193p-student-final-projects/id395605774?i=90218598">http://itunes.apple.com/us/podcast/cs193p-student-final-projects/id395605774?i=90218598</a><br />
Which covers both Objective-C basics and the iPhone's SDK. It's from Fall 2010 and there might be newer ones in iTunes U, but I personally watched the first few videos and I am really pleased with them.</li>
<li>A great blog with a variety of tutorials on iOS and game development: <a href="http://www.raywenderlich.com/">http://www.raywenderlich.com</a></li>
<li>Another great source for Objective-C and iOS related tips and issues: <a href="http://iphonedevelopertips.com/archives">http://iphonedevelopertips.com/archives</a></li>
<li>If you speak Hebrew, a great intro by Hezi Cohen, focusing on objective C and xCode: <a href="http://www.youtube.com/watch?v=GVAWfqTyhcA">http://www.youtube.com/watch?v=GVAWfqTyhcA</a></li>
<li>iOS Dev Center: <a href="http://developer.apple.com/devcenter/ios/index.action.">http://developer.apple.com/devcenter/ios/index.action</a><br />
You should read the iOS development guide, and all the different guidelines there. It may look long and boring, but it pays off!</li>
</ul>
<b>Objective-C</b><br />
<ul>
<li>An additional layer to C that introduces objects</li>
<li>Syntax is ugly (smalltalk like), but not something you can't get used to</li>
<li>Memory management is better than C, but you still need to be very aware, unlike modern languages. However, iOS 5 will support Automatic Reference Counting (ARC), so this should alleviate the pain. (See <a href="http://developer.apple.com/technologies/ios5/">http://developer.apple.com/technologies/ios5/</a>)</li>
<li>Has some very features of modern languages, like automatic getters&setters, nil objects that do not causes a crash if referenced, and dynamic language features - altering existing classes, invoking methods dynamically, etc.</li>
<li>The iPhone SDK and all APIs are written in Objective-C (Including the UI layers), and as said before - you are probably going to write at least one layer of your application in it, so you definitely should learn Objective-C if you are planning on developing for iOS.</li>
<li>A GREAT summary about Objective-C's basics: <a href="http://www.otierney.net/objective-c.html">http://www.otierney.net/objective-c.html</a></li>
</ul>
<b>IDE (xCode)</b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://t3.gstatic.com/images?q=tbn:ANd9GcQx7l8ruWR3fpuj9fcmzK_b7k_LM7vXPEAy4UWPBwJi9d5geo4IjQ" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://t3.gstatic.com/images?q=tbn:ANd9GcQx7l8ruWR3fpuj9fcmzK_b7k_LM7vXPEAy4UWPBwJi9d5geo4IjQ" /></a></div>
<b><br />
</b><br />
<ul>
<li>Basically, it's like VisualStudio for iPhone applications. Seems like a decent tool - autocompletion works very nicely, and there are built-in UnitTests support which is great (no green bar though...)</li>
<li>Comes with a set of tools, like the iPhone simulator which is a very good way to feel how your app is going to appear on the device without actually deploying it, and other important tools like a profiler, a memory debugger, etc.</li>
<li>Will take some time to adjust to, and from first look - it's powerful, but lacks some advanced refactoring features IDEs like Eclipse have.</li>
<li>I heard some that claimed that even if you develop in other IDEs, you'll still have to compile them eventually in xCode before submitting to Apple. However, I guess this was true prior to a change in Apple's policy regarding development tools, in September 2010.</li>
<li>One prominent alternative for xCode is Appcode by JetBrains (IntelliJ dudes): <a href="http://www.jetbrains.com/objc/">http://www.jetbrains.com/objc/</a> - haven't thoroughly checked it out yet, so no review.</li>
</ul>
<b>OpenGL ES</b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://t1.gstatic.com/images?q=tbn:ANd9GcS7tR01CLk0771Df5V19rQUgoEOa2KfGDu15ZzxgZ393dAwTaod" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="124" src="http://t1.gstatic.com/images?q=tbn:ANd9GcS7tR01CLk0771Df5V19rQUgoEOa2KfGDu15ZzxgZ393dAwTaod" width="320" /></a></div>
<b><br />
</b><br />
<ul>
<li>Official website: <a href="http://www.khronos.org/opengles/">http://www.khronos.org/opengles/</a></li>
<li>OpenGL ES is a subset of the OpenGL 3D graphics API, designed for embedded devices, including mobile phones. A subset - meaning some of the features of OpenGL such as floating point operations might not be available, and you'll have to replace them with alternatives if you're planning on porting an existing desktop OpenGL application.</li>
<li>The upside of developing in OpenGL ES, besides being a strong and popular 3D graphics engine, is that it supports many platforms. Implementations always have a platform-specific part, and the OpenGL API which is the same on all platforms for a specific OpenGL API version (which unfortunately may differ between the Android SDK and the iOS SDK). So while your code won't be 100% cross-platform, it should be easily portable, especially if you create proper abstractions between the platform-specific and non platform-specific part.</li>
<li>A great set of OpenGL ES tutorials for iPhone can be found at <a href="http://iphonedevelopment.blogspot.com/2009/05/opengl-es-from-ground-up-table-of.html">http://iphonedevelopment.blogspot.com/2009/05/opengl-es-from-ground-up-table-of.html</a></li>
</ul>
<b>Cocos2D</b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://t2.gstatic.com/images?q=tbn:ANd9GcQ-599ZAQzM3sCCHCJ7kralGidpLbNOFK0uPkcibvUA9fm60AT3" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://t2.gstatic.com/images?q=tbn:ANd9GcQ-599ZAQzM3sCCHCJ7kralGidpLbNOFK0uPkcibvUA9fm60AT3" /></a></div>
<b><br />
</b><br />
<ul>
<li>Link: <a href="http://www.cocos2d-iphone.org/">http://www.cocos2d-iphone.org/</a></li>
<li>An open source objective-C based framework for easily developing 2D games for iOS and Mac. Based on OpenGL ES.</li>
<li>Contains nice features such as scene managements, menus and buttons, tile map support, high score server, and many more.</li>
<li>Very popular - has a large community and lots of cool games created with the framework.</li>
<li>The tutorial in the official site seems very effective, and there are lots of other books and tutorials out there.</li>
</ul>
<b><span class="Apple-style-span" style="font-size: large;">Cross-Platform Solutions</span></b><br />
<br />
<b>Web Based Cross-Platform Solutions</b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://t0.gstatic.com/images?q=tbn:ANd9GcRTtgOlqMHJ8fw16ql9rhQ5YJb8m8mIWm4SUAZwpT21OYSKzk6eFw" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://t0.gstatic.com/images?q=tbn:ANd9GcRTtgOlqMHJ8fw16ql9rhQ5YJb8m8mIWm4SUAZwpT21OYSKzk6eFw" /></a></div>
<b><br />
</b><br />
<ul>
<li>There are a lot of platforms that let you develop native apps in html5/javascript/etc.</li>
<li>This is a good solution for developers who already experienced in web, and do not wish to learn objective-c or other similar technologies.</li>
<li>On the other hand, although some of these frameworks allow you access to the hardware of the devices, it is limited in comparison to real native apps. Also, there are major performance limitations, and of course there's the native look-and-feel issue I mentioned earlier.</li>
<li>The most popular examples of such frameworks are: <a href="http://www.phonegap.com/">PhoneGap</a> and <a href="http://www.appcelerator.com/">Appcelerator Titanium</a>. I must admit my research less focused on them so I can't really say how they are, but I do know they are popular and has a large community, and on the other hand - they have the known limitations mentioned earlier.</li>
<li>To sum it up, here's a nice presentation by Onavo about the dilema of Native apps vs. Web Apps: <a href="http://www.slideshare.net/onavo/advanced-ios-engineering-the-junction-talk">http://www.slideshare.net/onavo/advanced-ios-engineering-the-junction-talk</a></li>
</ul>
<b>Rhodes Rhomobile</b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://t0.gstatic.com/images?q=tbn:ANd9GcS7IV_0-XkYn2QiLn189zQlizbSAJrwLv7lYU_bzYOiJvNN442W" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://t0.gstatic.com/images?q=tbn:ANd9GcS7IV_0-XkYn2QiLn189zQlizbSAJrwLv7lYU_bzYOiJvNN442W" /></a></div>
<b><br />
</b><br />
<ul>
<li>Link: <a href="http://rhomobile.com/">http://rhomobile.com/</a></li>
<li>A bit similar to the rest of the web-based cross platforms solution, except that it's <b>Ruby</b> based, and should be more powerful regarding hardware capabilities.</li>
<li>Personally I'm more of a python guy, but from the little I know, ruby is a really fun dynamic language.</li>
<li>According to their claim, apps written with rhodes are faster than Android apps written in Java, because it's written </li>
<li>Hardware capabilities currently include access to GPS, camera (only still pictures), bluetooth, audio playback, barcode recognition, and more. Audio/Video capture is planned in future releases.</li>
<li>Integrates nicely to all popular IDEs, with a built in unit-testing framework, etc.</li>
<li>All in all, seems like a good option if your app doesn't require intensive graphics or performance, and you like ruby, or at least prefer it over objective-C.</li>
</ul>
<b>Marmalade</b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://t3.gstatic.com/images?q=tbn:ANd9GcRb2p9VXvgflw0tG0Zw2rNY5xK_rOgc6FbbzCrIo3ETFScBnoCKgw" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://t3.gstatic.com/images?q=tbn:ANd9GcRb2p9VXvgflw0tG0Zw2rNY5xK_rOgc6FbbzCrIo3ETFScBnoCKgw" /></a></div>
<b><br />
</b><br />
<ul>
<li>Link: <a href="http://www.madewithmarmalade.com/">http://www.madewithmarmalade.com/</a></li>
<li>Until recently known as 'Airplay SDK'</li>
<li>A cross-platform infrastructure in C++ - mainly targeting game development but according to them "Marmalade’s sweet spot is 'rich' apps, by which we mean any combination of: great graphics; audio processing; use of device APIs such as camera, GPS, and microphone; deep C/C++ codebase; or anything else that raises your app above the level of a simple mobile website wrapper"</li>
<li>They have a plugin for the existing IDEs: either Visual Studio in Windows, or xCode in Mac - which makes it very comfortable to develop.</li>
<li>The support for platform-specific code (called EDK) gives an automatic layer of abstraction that makes it very easy to write a cross-platform app that takes advantage of native features.</li>
<li>There is a very impressive portfolio of games developed with this SDK, like games by Electronic Arts, or PES by Konami.</li>
<li>All in all, this looks like one of the top choices for developing cross-platform applications.</li>
</ul>
<b>Unity</b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://t0.gstatic.com/images?q=tbn:ANd9GcTpBqK4LUI5ohAjOlTClwBP1NCYzHmTbaTrNUp__5ijT57jawUE" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://t0.gstatic.com/images?q=tbn:ANd9GcTpBqK4LUI5ohAjOlTClwBP1NCYzHmTbaTrNUp__5ijT57jawUE" /></a></div>
<b><br />
</b><br />
<ul>
<li>Seems like a very powerful cross-platform game engine. Has good documentation and a good community of Q&A. <a href="http://unity3d.com/">http://unity3d.com/</a></li>
<li>Most of the development is done with an editor, and the engine supports scripts in Javascript, C# and <a href="http://boo.codehaus.org/">Boo</a>. There are also many native plugins in the Pro version, and you can write them yourself in c/c++ / objective-c / java, etc. (but using it will make your game non-cross-platform of course).</li>
<li>In general, seems like this is a very strong option for game development, especially if you are developing 3D games for multiple platforms. However, accessing the microphone/camera of the mobile device + other advanced features will require using native plugins.</li>
</ul>
<b>Flash CS5</b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.isralab.com/wp-content/uploads/2010/02/adobe-flash.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="227" src="http://www.isralab.com/wp-content/uploads/2010/02/adobe-flash.jpg" width="320" /></a></div>
<b><br />
</b><br />
<ul>
<li>It seems that Flash is a decent cross platform solution for developing native iOS applications. Surprised? So was I. Here is a summary about that: <a href="http://www.adobe.com/devnet/logged_in/abansod_iphone.html">http://www.adobe.com/devnet/logged_in/abansod_iphone.html</a></li>
<li>Here are some nice tutorials:<a href="http://www.paultrani.com/blog/index.php/2010/11/tutorial-creating-mobile-apps-using-flash-cs5/">http://www.paultrani.com/blog/index.php/2010/11/tutorial-creating-mobile-apps-using-flash-cs5/</a><a href="http://active.tutsplus.com/tutorials/mobile/flash-for-iphone/">http://active.tutsplus.com/tutorials/mobile/flash-for-iphone/</a></li>
<li>In general - seems like a great solution if you are an experienced Flash developer, or you already have a Flash version of your application that you want to deploy it to the iPhone. The open question is: is the performance going to be good enough?</li>
</ul>
<b>Corona SDK</b><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://t0.gstatic.com/images?q=tbn:ANd9GcQll6ZJyg8FHBQdOW78QpFpa9ZIjxJvRdTn-bto6t9g-mWXUcNK" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://t0.gstatic.com/images?q=tbn:ANd9GcQll6ZJyg8FHBQdOW78QpFpa9ZIjxJvRdTn-bto6t9g-mWXUcNK" /></a></div>
<b><br />
</b><br />
<ul>
<li>Link: <a href="http://www.anscamobile.com/corona">http://www.anscamobile.com/corona</a></li>
<li>Based on the <a href="http://www.lua.org/about.html">Lua</a> scripting language, should be similar to ActionScript. There's a nice blogpost regarding how to port a Flash application to Corona: <a href="http://blog.anscamobile.com/2011/01/flash-to-corona-porting-guide/">http://blog.anscamobile.com/2011/01/flash-to-corona-porting-guide/</a></li>
<li>Claims to focus on performance and from the showcase seems like there are very impressive games developed with Corona.</li>
<li>Has access to many of the device capabilities, including camera, microphone, GPS, etc.</li>
<li>There's a free unlimited trial, but you need to buy a subscription in order to distribute apps.</li>
</ul>
<b><span class="Apple-style-span" style="font-size: large;">Afterword</span></b><br />
<br />
That's about all I have researched and can share with you currently. I hope that with time, after gaining some hands-on experience, I'll have some more useful knowledge to share in this blog. So if you're interested - stay tuned: subscribe to the blog, or <a href="http://twitter.com/theyonibomber">follow me on twitter</a>.<br />
<br />
I would like to welcome any comments you have about the information written here: if you feel I left some important information out, if you spotted a mistake or two in the data, or if you have a personal opinion about some of the frameworks I mentioned. Please leave your comments as a reply to this post. I promise to take them into account.<br />
<hr />
<b>Edit:</b> Thanks <a href="http://twitter.com/#!/philxan">@philxan</a> for mentioning I forgot about MonoTouch<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://t1.gstatic.com/images?q=tbn:ANd9GcTTYQyLozWjW4LARaHNdQCIfgJHHExMDZMjJWLQAULO4Jd73kwKlAWEOMJw" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://t1.gstatic.com/images?q=tbn:ANd9GcTTYQyLozWjW4LARaHNdQCIfgJHHExMDZMjJWLQAULO4Jd73kwKlAWEOMJw" /></a></div>
<br />
<ul>
<li>Official Site: <a href="http://ios.xamarin.com/">http://ios.xamarin.com/</a></li>
<li>Part of the Mono Project (<a href="http://www.mono-project.com/Main_Page">http://www.mono-project.com/Main_Page</a>) - a solution that allows you to write cross-platform C# application.</li>
<li>Basically, it's a C# framework that integrates with the desktop Mono SDK and the iPhone SDK and lets you create native applications in C# and the .NET framework. Should be interesting mostly if you're looking to port an existing C# application for iOS, or if you're an experienced C# developer and want to save yourself the efforts of learning and adapting to new technologies.</li>
<li>The IDE is MonoDevelop for OS X - looks a solid IDE, but I can't say I tried it personally.</li>
<li>Cost begins at 399$ for a personal license...</li>
<li>Has a version for Android (and naturally Windows Phone) as well</li>
<li>Here's a good site with code samples: <a href="http://monotouchexamples.com/">http://monotouchexamples.com</a></li>
</ul>
Anonymoushttp://www.blogger.com/profile/06100813770559493046noreply@blogger.com63tag:blogger.com,1999:blog-3833072356413502019.post-6929993968902237292011-07-27T12:29:00.002+03:002014-01-04T13:31:11.049+02:00Excuse #3 - Isn't it QA's job to test my code?<div>
Sorry for the delay in publishing this one guys, had been busy, but finally - the 3rd excuse of the <a href="http://codesheriff.blogspot.com/2011/03/testing-why-bother-introduction.html">"Testing: Why Bother?"</a> series is finally up.</div>
<div>
<br /></div>
<div>
So... We are going to address an excuse that is a bit less commonly asked out loud, but I think many of us programmers secretly think it without even knowing.</div>
<div>
<br /></div>
<div>
I assume you stumbled at least once before across arguments like:</div>
<div>
<ul>
<li>"<i>Well... I could write a test for this, but QA has to perform some heavy testing on this feature anyhow, so why bother?</i>"</li>
<li>"<i>I don't have the environment I need to run a test for this right now, and QA have their own testing environment, it would be much more cost-effective to just leave the job of testing this to them"</i></li>
<li>"<i>Our QA guys are not doing anything right now anyhow... We are on a lot of pressure and have tons of new features to implement before deadline - why not speed up things a bit by skipping the testing part and leaving it to QA?</i>"</li>
</ul>
<div>
Well, I must admit these are all thoughts that ran through my head at least once or twice.</div>
<div>
Here are some of my key points on what I've come to learn from my experience with other programmers and even myself cutting corners about testing the code because we're on a hurry and "QA are going to test it anyhow":<br />
<br />
<a name='more'></a><br /><br />
<b><span class="Apple-style-span" style="font-size: large;">The Longer you wait testing the code - the harder it is to fix it</span></b><br />
<div class="separator" style="clear: both; text-align: left;">
<a href="http://t3.gstatic.com/images?q=tbn:ANd9GcQasumxQFyd9LqHjNQJ7ir9KLBv8R7HOTmK0i259l1BEgZytKTrgg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="http://t3.gstatic.com/images?q=tbn:ANd9GcQasumxQFyd9LqHjNQJ7ir9KLBv8R7HOTmK0i259l1BEgZytKTrgg" /></a></div>
<br />
There are different types of ways collaborating between development and QA teams.<br />
I've seen many kinds of ways, but I think they generally fall into the following 2 categories:<br />
<br />
<ol>
<li>Dev and QA teams are working separately, on separate iterations. For example: the dev team are working for 2 weeks on the current release candidate, releasing it to QA, and start working on the next iteration. When QA guys find a bug with the last released version, they report it to the dev guys, and the latter have to decide if they are going to fix it for the upcoming version or not.<br />
When there's a release candidate QA feels is stable enough - it's being released to customer.</li>
<li>There is only one team, made of both QA and dev personnel. Each iteration, the dev guys are working on a small feature, and as soon as they are done with it, </li>
</ol>
<div>
Now, of course the 2nd option is more "agile", and I personally prefer it, but that's not the issue here. What I want to say - is that if you wait until the QA guys kick in until you get feedback on your feature and know if it works well. This time arrives at least after you decide you're done with the current feature in the better scenario (#2), or might even wait until the end of the iteration (#1), which might be weeks away.</div>
<div>
<br /></div>
<div>
That's awful. Because when the bug will be opened, you already forgot about what you did, how the code exactly work, and you are already keen on finishing the development of the next feature in the list.</div>
<div>
<br /></div>
<div>
If instead you have written a unit test for the feature during (or before) implementing it, you would have a much easier time fixing the bugs that were found.</div>
<div>
<br /></div>
<div>
<b><span class="Apple-style-span" style="font-size: large;">Every bug might be hiding a long list of more complex ones!</span></b></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://images.fanpop.com/images/image_uploads/A-Bug-s-Life-a-bugs-life-626992_1024_768.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="240" src="http://images.fanpop.com/images/image_uploads/A-Bug-s-Life-a-bugs-life-626992_1024_768.jpg" width="320" /></a></div>
<div>
When you release your product with a kind of a "blocker" bug, like a bug in installation or a crash in the beginning of the application, you are blocking the ability of QA to reach the really interesting bugs of your application.</div>
<div>
<span class="Apple-style-span"><br />
</span></div>
<div>
<span class="Apple-style-span">This means that until you fix your installation bug, QA can pretty much go to the beach and catch some sun! So much for efficiency</span><span class="Apple-style-span"> and maximizing productivity. </span></div>
<div>
<br /></div>
<div>
If you make sure to heavily test those critical part of the application that will block the ability to use it at all, you avoid these evil scenarios.</div>
<div>
<br /></div>
<div>
<div>
<b><span class="Apple-style-span" style="font-size: large;"><br />
</span></b><br />
<b><span class="Apple-style-span" style="font-size: large;"><br />
</span></b><br />
<b><span class="Apple-style-span" style="font-size: large;">Help The QA team focus on what they're good at</span></b></div>
</div>
<div>
Related to the previous point...</div>
<div>
<br /></div>
<div>
As I see it, QA are very important even if you have 100% code coverage in your unit tests. They help you find the nasty bug that you would have never thought of testing automatically, like "<i>your application crashes when I'm running it on Windows 2008 R2 SP1 when the USB dongle was plugged in before you disable the video camera</i>", and additionally - they provide a more user oriented point of view developers sometimes lack.</div>
<div>
<br /></div>
<div>
If you keep the QA team busy with recreating bugs of basic functionality you could have easily found with a simple unit test, you are not taking full advantage of their services.</div>
<div>
<br /></div>
<div>
<b><span class="Apple-style-span" style="font-size: large;">Collaborate with QA for gain of both sides</span></b></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="http://t0.gstatic.com/images?q=tbn:ANd9GcRGgXWJaFDZcuyUFosxuAWKOoZg8LgEuV9zomCw5lGnVtRuXtLJ" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://t0.gstatic.com/images?q=tbn:ANd9GcRGgXWJaFDZcuyUFosxuAWKOoZg8LgEuV9zomCw5lGnVtRuXtLJ" /></a></div>
<div>
This is an important tip, especially if you feel that the pressure on development while QA have some slack.</div>
<div>
<br /></div>
<div>
Something you CAN do, is use QA for assistance while writing your code. You can pair with them while writing the unit tests, and even the code itself. This way - development gains the QA point of view of what their code should do and what to test for, and the QA gains the better understanding of the code and the ability to spot weaknesses in it.</div>
<div>
<br /></div>
<div>
Also, QA usually have a list of tests they run for each build before declaring it a stable product. When you write along with the QA guys automation for some of these tests, and include it in the test suite that runs after every build, you save them the effort and increase confidence of both sides with the stability of the product.</div>
<div>
<br /></div>
<div>
<b><span class="Apple-style-span" style="font-size: large;">To sum things up</span></b></div>
<div>
<span class="Apple-style-span">Leaving all the testing to QA will NOT save you time. It will either cause you to delay your deadlines, or simply cause you to release low quality products.</span></div>
<div class="separator" style="clear: both; text-align: left;">
<a href="http://t3.gstatic.com/images?q=tbn:ANd9GcRTH2OOnu310O128DcsmkGzxkCEluJSzegMCB-cLqwJ1FeGEER7gg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://t3.gstatic.com/images?q=tbn:ANd9GcRTH2OOnu310O128DcsmkGzxkCEluJSzegMCB-cLqwJ1FeGEER7gg" /></a></div>
<div>
<span class="Apple-style-span"><br />
</span></div>
<div>
<span class="Apple-style-span"><br />
</span></div>
<div>
<span class="Apple-style-span">More posts in the series are coming, and some new content!</span></div>
<div>
<span class="Apple-style-span">You should subscribe to this blog and <a href="http://twitter.com/theyonibomber">follow me on twitter</a>.</span></div>
</div>
</div>
Anonymoushttp://www.blogger.com/profile/06100813770559493046noreply@blogger.com13tag:blogger.com,1999:blog-3833072356413502019.post-66946765560136613872011-06-22T19:19:00.001+03:002014-01-04T13:34:30.321+02:00A test with no assert is better than no test at allSorry about the delay since my last post.<br />
Now that I've freed some spare time, I hope to get back to the "Testing: Why Bother?" series. So stay tuned.<br />
<br />
Anyhow, wanted to share a quick insight I had about what to do when you need quick feedback about a feature that you find hard to write a good test for, through an example.<br />
<br />
<span class="Apple-style-span" style="font-size: large;"><b>Some Background</b></span><br />
<iframe align="left" frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=thecodshe-20&o=1&p=8&l=bpl&asins=B002S9KDKS&fc1=000000&IS2=1&lt1=_blank&m=amazon&lc1=0000FF&bc1=000000&bg1=FFFFFF&f=ifr" style="align: left; height: 245px; padding-right: 10px; padding-top: 5px; width: 131px;"></iframe><br />
I was pairing with my buddy on a cool feature of our project for some time now.<br />
The feature is basically some kind of a "<b>Device Prettifier</b>", that receives a local device path, performs some inquiries about it, and when its __repr__ (toString() equivalent) is called, it displays all the data it gathered from the inquiries prettily.<br />
<br />
So, we actually test-driven-developed the mentioned DevicePrettifier, unit-testing everything by creating mock devices returning whatever we want the DevicePrettifier to do. Basic TDD+Mocking, went very smoothly and was a lot of fun.<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;"><br />
</span></b><br />
<b><span class="Apple-style-span" style="font-size: large;"></span></b><br />
<a name='more'></a><b><span class="Apple-style-span" style="font-size: large;"><br />
</span></b><br />
<b><span class="Apple-style-span" style="font-size: large;">The Tricky Part</span></b><br />
<b><span class="Apple-style-span" style="font-size: large;"><iframe align="left" frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=thecodshe-20&o=1&p=8&l=bpl&asins=0307276538&fc1=000000&IS2=1&lt1=_blank&m=amazon&lc1=0000FF&bc1=000000&bg1=FFFFFF&f=ifr" style="align: left; height: 245px; padding-right: 10px; padding-top: 5px; width: 131px;"></iframe></span></b><br />
<br />
Unit testing here was not enough for us. We mocked what the inquiries returned according to known examples we know about, and we pretty much tailor-made the responses to the logic we wanted to implement. Perfectly reasonable way to implement a feature using TDD. However, we never tested <b>how the DevicePrettifier behaves on a REAL device</b>, on various operating systems and environments.<br />
<br />
So... The correct way to go about this, is to write an <b>integration test</b>. An integration test that uses <b>real devices</b> and that tests how the DevicePrettifier works on them.<br />
<b>The problem: </b>without the proper testing framework that will allow us to automatically allocate hosts and real devices to test, we would have to put a lot of effort on such integration test - effort that might take us <b>too much time</b>, as we need to release this feature on a tight deadline.<br />
<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;">What Could We Do?</span></b><br />
<iframe align="right" frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=thecodshe-20&o=1&p=8&l=bpl&asins=B002Q4KQMK&fc1=000000&IS2=1&lt1=_blank&m=amazon&lc1=0000FF&bc1=000000&bg1=FFFFFF&f=ifr" style="align: left; height: 245px; padding-right: 10px; padding-top: 5px; width: 131px;"></iframe><br />
<br />
We could have made a <b>manual test</b>... But then we would lose the important <b>regression</b> capabilities we gain when making our tests (including integration tests) <b>automatic</b>.<br />
<br />
Or, we could have done something a little bit in between: An integration test with <b><span class="Apple-style-span" style="font-size: large;">no asserts</span></b>.<br />
<br />
<b><span class="Apple-style-span" style="font-size: large;"><br />
</span></b><br />
<b><span class="Apple-style-span" style="font-size: large;"><br />
</span></b><br />
<b><span class="Apple-style-span" style="font-size: large;">Are You Crazy?</span></b><br />
<b><i><iframe align="left" frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=thecodshe-20&o=1&p=8&l=bpl&asins=B000H2MDRY&fc1=000000&IS2=1&lt1=_blank&m=amazon&lc1=0000FF&bc1=000000&bg1=FFFFFF&f=ifr" style="align: left; height: 245px; padding-right: 10px; padding-top: 5px; width: 131px;"></iframe></i></b><br />
<b><i>"No asserts?? What do you mean? What do you test when you do that? If a human needs to go over the results of the test run - it's not automatic, and it's of no use."</i></b><br />
<br />
OK, I knew you guys would say that. But actually there are<b> 2 things</b> to notice here:<br />
<br />
<b>1. </b>For the purpose of testing your code for the first time - it's better to write <b>an automatic test with no asserts</b> than to write a <b>manual main()</b>. This way you have the structure of the test that you can later <b>add asserts</b> to more easily. Also - when you run it for the first time and manually check the output, you can quickly find the problems, and write <b>a more specific test</b> for them - even go back to the unit tests and alter them for this purpose.<br />
<br />
<b>2. </b>Even a test with no asserts automatically tests something. It tests that<b> no exceptions are thrown</b>. This is a VERY important thing to test for, and -- let me tell you -- it founds a decent amount of bugs!<br />
<br />
So, here's the test we made (code almost untouched before uploading):<br />
<script src="https://gist.github.com/900694.js?file=device_prettifier_test.py">
</script><br />
<br />
<br />
We simply logged on to a few hosts of different type, ran this test, and it found <b>the most important bugs we had</b>. May be surprising, but <b>really cost-effective</b>!<br />
<br />
Now, we can add this test to all of our continuous integration slaves, and if for instance a new type of device is suddenly connected to one of the slaves -- we'll immediately know if out prettifier couldn't parse the inquiry responses it returned. Coolness!<br />
<br />
<br />
<span class="Apple-style-span" style="font-size: large;"><b>In Conclusion</b></span><br />
<iframe align="right" frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=thecodshe-20&o=1&p=8&l=bpl&asins=B004NGL4TS&fc1=000000&IS2=1&lt1=_blank&m=amazon&lc1=0000FF&bc1=000000&bg1=FFFFFF&f=ifr" style="align: left; height: 245px; padding-right: 10px; padding-top: 5px; width: 131px;"></iframe><br />
<br />
The next time you feel like writing a complicated integration test and give up because you just don't have time, think about the <b>"assert free"</b> approach. It might be easier, save you a lot of time, and still find most of the bugs!<br />
<br />
Stay tuned for more posts on the "Testing: Why Bother?" series, and <a href="http://twitter.com/theyonibomber">follow me on twitter</a> :).Anonymoushttp://www.blogger.com/profile/06100813770559493046noreply@blogger.com6tag:blogger.com,1999:blog-3833072356413502019.post-33708382129793226302011-04-05T00:54:00.011+03:002014-01-04T13:35:47.998+02:00Excuse #2 - Writing tests is too hard<a href="http://www.codeodor.com/images/frustrated.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="258" src="http://www.codeodor.com/images/frustrated.jpg" width="320" /></a><span class="Apple-style-span" style="font-size: large;"><b>Introduction</b></span><br />
<span class="Apple-style-span" style="font-size: large;"><b><br />
</b></span><br />
So, after talking about the famous <a href="http://codesheriff.blogspot.com/2011/03/excuse-1-writing-tests-takes-too-much.html">too-much-time</a> excuse, I am going to address the next excuse in the <i><a href="http://codesheriff.blogspot.com/2011/03/testing-why-bother-introduction.html">Testing: Why Bother?</a> </i>series: We don't write tests because <b>it's too hard!</b><br />
<br />
I will try to make this post a little more practical than the previous one, but because it's still aimed more to the <i>why</i> and not the <i>how</i>, I'm not going to dive too much into the "how to write tests for beginners" techniques. If you feel you need some prior background for this, I can recommend the following great books:<br />
<table style="text-align: center;"><tbody>
<tr> <td><br />
<a href="http://www.amazon.com/gp/product/0974514012/ref=as_li_tf_tl?ie=UTF8&tag=thecodshe-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0974514012"><img height="200" src="http://ecx.images-amazon.com/images/I/41LWK9E5a9L._SL500_AA300_.jpg" width="200" /></a></td> <td><br />
<a href="http://www.amazon.com/gp/product/1933988274/ref=as_li_tf_tl?ie=UTF8&tag=thecodshe-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=1933988274"><img height="200" src="http://ecx.images-amazon.com/images/I/51VAZ9BwcvL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_OU01_.jpg" width="200" /></a></td> <td><br />
<a href="http://www.amazon.com/gp/product/0321146530/ref=as_li_tf_tl?ie=UTF8&tag=thecodshe-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0321146530"><img height="200" src="http://ecx.images-amazon.com/images/I/513PZWJDH7L._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_OU01_.jpg" width="200" /></a></td> </tr>
</tbody></table>
<br />
<br />
<span class="Apple-style-span" style="font-size: large;"><b>So... I guess in your pretty world testing is a piece of cake...</b></span><br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil6Tqc5lWFJNsGBOnaQ6qmQ1cuVoqNKfg2gTdtCf1HGsgqtA2iQhKXNJtRi70Drkc3UKHyPGG-hOur3TkC5ReZM68iMQ-tO5JmwWNgIOkimgZH74vCYWhbSI2PIn7jZO3qIkMqZqQforE/s1600/testing+is+an+art.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEil6Tqc5lWFJNsGBOnaQ6qmQ1cuVoqNKfg2gTdtCf1HGsgqtA2iQhKXNJtRi70Drkc3UKHyPGG-hOur3TkC5ReZM68iMQ-tO5JmwWNgIOkimgZH74vCYWhbSI2PIn7jZO3qIkMqZqQforE/s200/testing+is+an+art.png" width="150" /></a>Once again, you guess wrong my friends...<br />
<br />
<a name='more'></a><br /><br />
Testing isn't easy at all. <b>Writing tests is a delicate art</b>, and can be a very difficult task, especially for beginners with no experience in it.<br />
<div style="direction: ltr;">
<br /></div>
<div style="direction: ltr;">
However, if you consider the alternative, you'll eventually figure out that <b>writing code that works without bugs, without a single line of test code, is even harder!</b></div>
<div style="direction: ltr;">
<b><br />
</b></div>
<div style="direction: ltr;">
One might say: <i>"Well... Still.. It's not cost-effective! You go through all the hard work to discover a few bugs you would find out about later anyhow?"</i></div>
<div style="direction: ltr;">
<i><br />
</i></div>
<div style="direction: ltr;">
I have 2 answers to this claim:</div>
<div style="direction: ltr;">
<br /></div>
<div style="direction: ltr;">
<b>1.</b> <b>Later? How later?</b></div>
<div style="direction: ltr;">
If you have read <a href="http://codesheriff.blogspot.com/2011/03/excuse-1-writing-tests-takes-too-much.html">my previous post</a>, you probably remember that finding out about a bug <b>"later" </b>can be<b> </b>actually<b> really later</b>, like when it's already at the customer's hands. In this case it can cost you WAY more. So cost-effectiveness isn't really a valid excuse here.</div>
<div style="direction: ltr;">
<br /></div>
<div style="direction: ltr;">
<b>2. It's not THAT hard!</b></div>
<div style="direction: ltr;">
<b></b>After you practice a little, read some books, become more comfortable with writing the tests, you'll see it's not that bad, and it will become a natural skill of yours. </div>
<div style="direction: ltr;">
<br />
<b>However, </b>there still might be several cases that you really think <i>"this is a piece of code I simply CAN'T test"</i>. In this case - you've come to the right place! I'll try to tackle down the common difficulties you might be having.</div>
<div style="direction: ltr;">
<br /></div>
<div style="direction: ltr;">
<br /></div>
<div style="direction: ltr;">
<span class="Apple-style-span" style="font-size: large;"><b>The Common Difficulties</b></span></div>
<br />
Here's a list of some common difficulties taken from my personal experience and of the anti-testers around me:<br />
<br />
<ul><a href="http://www.actionsoft.com/games/midnightmansion/difficulty.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="150" src="http://www.actionsoft.com/games/midnightmansion/difficulty.jpg" width="200" /></a>
<li><b>The code has too much dependencies</b>: <i>"I need to instantiate 50 different classes to write a measly test case."</i></li>
<li><b>There's a lot of environment to initialize</b>: <i>"Before I can invoke this method, I need to acquire a DB connection, and run 4 different processes..."</i></li>
<li><b>The code is behaving in an unpredictable way</b>: <i>"I have 20 threads running here, I should expect a different result in each run!"</i></li>
<li><b>The code involves a lot of manual operations</b>: <i>"Most of this logic is invoked when a button is pressed in the GUI, I can't automate a test for it!"</i></li>
</ul>
Lets' try to find a solution for these difficulties:<br />
<br />
<span class="Apple-style-span" style="font-size: large;"><b><br />
</b></span><br />
<span class="Apple-style-span" style="font-size: large;"><b>Tightly coupled code is evil! Regardless of testing!</b></span><br />
<br />
This is true for the first 2 bullets. If your <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><b>UltraUberDoesEverythingManager</b></span><span class="Apple-style-span" style="font-family: inherit;"><b> </b>is really hard to test because on its constructor it receives 20 different classes, or worse: it instantiates 20 different classes by itself, that's a real <b>code smell</b>.</span><br />
<span class="Apple-style-span" style="font-family: inherit;"><br />
</span><br />
<a href="http://blog.chinatells.com/wp-content/uploads/2009/09/BFF8F-decouple.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://blog.chinatells.com/wp-content/uploads/2009/09/BFF8F-decouple.jpg" /></a><span class="Apple-style-span" style="font-family: inherit;"><b>Remember, if it's difficult to test, it is difficult to maintain and use!</b></span><br />
<span class="Apple-style-span" style="font-family: inherit;">If you find it hard to infer the class from its context and write a good unit test for it, having to pass real instances, having to initialize a real DB connection or insert the USB dongle for the test to run, it means that later when you'll want to extract the useful piece of algorithm or reuse the objects, you are going to have the exact same difficulties. <b>That's just bad OOP.</b></span><br />
<span class="Apple-style-span" style="font-family: inherit;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: inherit;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: inherit;"><b>Decouple! Use interfaces so you can replace them with mocks.</b></span><br />
<br />
Consider the following code:<br />
<script src="https://gist.github.com/900694.js?file=StringSerializerBad.java">
</script><br />
<span class="Apple-style-span" style="font-family: inherit;">This code will be very hard to test. We simply want to test that </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">serializeString()</span><span class="Apple-style-span" style="font-family: inherit;"> stores the string in DB using the </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">dump()</span><span class="Apple-style-span" style="font-family: inherit;"> method, but in order to do so, we have to start a connection to DB using the horrible </span><span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">ConnectionManager</span><span class="Apple-style-span" style="font-family: inherit;"> singleton.<br />
</span><br />
<br />
<span class="Apple-style-span" style="font-family: inherit;"> Instead, consider the following:<br />
</span><br />
<script src="https://gist.github.com/900694.js?file=StringSerializerBetter.java">
</script><br />
<a href="http://www.odetocode.com/aimages/mock.gif" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="http://www.odetocode.com/aimages/mock.gif" /></a><span class="Apple-style-span" style="font-family: inherit;">This way, we pass an implementation of ourselves to the Serializer interface. We can use one of the many mocking frameworks (like <a href="http://mockito.org/">Mockito </a>for Java, or <a href="http://www.voidspace.org.uk/python/mock/">Michael Foord's Mock</a> for Python), and easily test that serializeString() called our mock's dump() method.</span><br />
<span class="Apple-style-span" style="font-family: inherit;"><br />
</span><br />
<span class="Apple-style-span" style="font-family: inherit;">Notice that this was an example of taking existing code and making it more testable by decoupling the classes and introducing an interface in the middle. If we had <b>tested our code first</b>, whether by applying full <b>TDD </b>techniques or simply a <b>test-first</b> approach, we would have already seen this design defect earlier and it would have saved us some time... </span><br />
<span class="Apple-style-span" style="font-family: inherit;">But I'm not saying you MUST use<b> </b>TDD in order to test your code. Even without it, and without tests whatsoever, your code will be better if it's testable. </span><br />
<br />
<br />
<span class="Apple-style-span" style="font-family: inherit; font-size: large;"><b>Preparing for the unpredictable</b></span><br />
<span class="Apple-style-span" style="font-family: inherit;">Well, If you remember the <a href="http://codesheriff.blogspot.com/2011/03/testing-why-bother-introduction.html">list of excuses</a>, you might remember the <i>"</i><span class="Apple-style-span" style="line-height: 15px;"><i>It's hard to tell how the code behaves each time, so I can't write a test for it"</i> excuse. We are going to talk more about this subject there.</span></span><br />
<span class="Apple-style-span" style="font-family: inherit; line-height: 15px;"><br />
</span><br />
<span class="Apple-style-span" style="font-size: 15px; line-height: 15px;"><span class="Apple-style-span" style="font-family: inherit;">But for now, I'll focus on a few useful tips about multithreaded testing:</span></span><br />
<div>
<ul>
<li><span class="Apple-style-span" style="font-size: 15px; line-height: 15px;">Add sleeps + polling to make your assertions more predictable. You can use the following <b>delayedAssert </b>idiom:</span></li>
</ul>
<script src="https://gist.github.com/900694.js?file=DelayedAssert.java">
</script></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<ul style="list-style-image: initial; list-style-position: initial; list-style-type: disc; margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 0.5em; padding-bottom: 0px; padding-left: 2.5em; padding-right: 2.5em; padding-top: 0px;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmYoGtO8z6oG-PACw9ae29BMHwawcE_uzyXDNSJUJLEGQc78tAcuLDij-bA2d7Ti3AWxD3v3UeMk5Y0-cdvUJDXRGbX1LrfHTrAi7ERvcw-lEZ933XKlW_ebTxMJAAF1I5t1ulhKWbr48/s1600/multithreaded.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmYoGtO8z6oG-PACw9ae29BMHwawcE_uzyXDNSJUJLEGQc78tAcuLDij-bA2d7Ti3AWxD3v3UeMk5Y0-cdvUJDXRGbX1LrfHTrAi7ERvcw-lEZ933XKlW_ebTxMJAAF1I5t1ulhKWbr48/s200/multithreaded.jpg" width="200" /></a>
<li><span class="Apple-style-span"><b style="font-size: 15px; line-height: 15px;">Multithreaded testing is possible!</b><span class="Apple-style-span" style="font-size: 15px; line-height: 15px;"> I guarantee that every deadlock and race-condition can eventually be isolated and tested with the proper sleeping and locking.</span></span></li>
</ul>
<ul style="list-style-image: initial; list-style-position: initial; list-style-type: disc; margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 0.5em; padding-bottom: 0px; padding-left: 2.5em; padding-right: 2.5em; padding-top: 0px;">
<li><span class="Apple-style-span" style="font-size: 15px; line-height: 15px;"><b>Use mocks</b> instead of some of the threads that don't belong to the scenario you're testing.</span></li>
</ul>
<ul style="list-style-image: initial; list-style-position: initial; list-style-type: disc; margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 0.5em; padding-bottom: 0px; padding-left: 2.5em; padding-right: 2.5em; padding-top: 0px;">
<li><span class="Apple-style-span" style="font-size: 15px; line-height: 15px;">Don't forget to have some kind of </span><span class="Apple-style-span" style="font-size: 15px; line-height: 15px;"><b>ExceptionHandler </b></span><span class="Apple-style-span" style="font-size: 15px; line-height: 15px;">that catches exceptions thrown on other threads. You don't want one of your thread to crash and your test to keep going without noticing it.</span></li>
</ul>
<ul style="list-style-image: initial; list-style-position: initial; list-style-type: disc; margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 0.5em; padding-bottom: 0px; padding-left: 2.5em; padding-right: 2.5em; padding-top: 0px;">
<li><span class="Apple-style-span" style="font-size: 15px; line-height: 15px;"><b>Search for frameworks</b> that may help you. I couldn't find any I really liked, but there are a few of them out there.</span></li>
</ul>
<span class="Apple-style-span" style="font-size: 15px; line-height: 15px;"><br />
</span><br />
<span class="Apple-style-span" style="font-size: 15px; line-height: 15px;"><br />
</span><br />
<span class="Apple-style-span" style="font-size: large; line-height: 15px;"><b>Testing UI</b></span><br />
<span class="Apple-style-span" style="line-height: 15px;">Well, that's a tough one, I must admit. I must also say I'm not an expert of testing GUI. However, as tough as it can be, there are a few points to remember:</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.chrismadden.co.uk/computer-cartoons/computer-intuitive.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="320" src="http://www.chrismadden.co.uk/computer-cartoons/computer-intuitive.jpg" width="252" /></a></div>
<ul>
<li><span class="Apple-style-span" style="line-height: 15px;">Think about whether you REALLY need to test the UI? Or should it be enough to <b>use decoupling</b> so that the UI part is trivial and you already tested all the logic behind it?</span></li>
</ul>
<div>
<ul>
<li><span class="Apple-style-span" style="line-height: 15px;">There are <b>frameworks </b>like <a href="http://seleniumhq.org/"><b>Selenium </b></a>that can help you. Maybe even a cool <a href="http://www.autoitscript.com/site/autoit/"><b>AutoIt </b></a>script. Don't give up on automation simply because it's hard... They might not help you with unit tests, but it's still something you can use for sanity and regression.</span></li>
</ul>
</div>
<div>
<ul>
<li style="direction: ltr;"><span class="Apple-style-span" style="line-height: 15px;"><b>Write your own in-house testing framework</b>. For example, if your part of your system combines VUI (voice user interface) - write a framework that injects WAV files to your system, etc. It might be a lot of work, but eventually it can really pay off, and free some QA engineer's time for some harder-to-find bugs.</span></li>
</ul>
</div>
<br />
<span class="Apple-style-span" style="font-size: 15px; line-height: 15px;"><br />
</span><br />
<span class="Apple-style-span" style="font-size: large;"><span class="Apple-style-span" style="line-height: 15px;"><b><br />
</b></span></span><br />
<span class="Apple-style-span" style="font-size: large;"><span class="Apple-style-span" style="line-height: 15px;"><b>Remember: High level automation is better than no automation!</b></span></span><br />
<span class="Apple-style-span" style="line-height: 15px;">Unit tests are the most effective way to test your code: They are fast to run, if they fail you know exactly the place in the code that caused it, and they make your design better.</span><br />
<span class="Apple-style-span" style="line-height: 15px;"><br />
</span><br />
<a href="http://www.l2gracia.ge/forum/LevelUP.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="156" src="http://www.l2gracia.ge/forum/LevelUP.png" width="200" /></a><span class="Apple-style-span" style="line-height: 15px;">However, sometimes unit tests are not suitable for what you are testing. </span><br />
<span class="Apple-style-span" style="line-height: 15px;">That doesn't mean you should give up on an automated regression suite! Write tests in a higher level!</span><br />
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<span class="Apple-style-span" style="line-height: 15px;"><br />
</span></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<span class="Apple-style-span" style="line-height: 15px;">For example, you are trying to test the behavior of a windows networking related driver in the case a network cable disconnected. Unit testing this can be practically impossible in conventional matters. Instead, you should write some kind of script that turns off the relevant port of the networking switch, and tests the behavior is still OK. This might not be perfect, but it's better than no automation for the bug at all.</span></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<span class="Apple-style-span" style="line-height: 15px;"><br />
</span></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<span class="Apple-style-span" style="line-height: 15px;"><br />
</span></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<span class="Apple-style-span" style="line-height: 15px;"><span class="Apple-style-span" style="font-size: large;"><b><br />
</b></span></span></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<span class="Apple-style-span" style="line-height: 15px;"><span class="Apple-style-span" style="font-size: large;"><b>Are you finally finished with your testing nonsense now?</b></span></span></div>
<span class="Apple-style-span" style="line-height: 15px;"><br />
</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.marathon-training-authority.com/images/Marathon%20Finish%20Line.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="274" src="http://www.marathon-training-authority.com/images/Marathon%20Finish%20Line.jpg" width="320" /></a></div>
<div style="direction: ltr;">
<span class="Apple-style-span" style="line-height: 15px;">Sorry, you'll have to put up some more excuses :) The next one is going to be : "It's QA's job, and they're going to test the code anyhow".</span></div>
<div style="direction: ltr;">
<span class="Apple-style-span" style="line-height: 15px;"><br />
</span></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div style="direction: ltr;">
<span class="Apple-style-span" style="line-height: 15px;">If for some reason you decided that after these last posts you still want to read the next ones, you might want to subscribe to this blog and <a href="http://twitter.com/theyonibomber">follow me on twitter</a>.</span></div>
<div style="direction: ltr;">
<a href="http://www.blogger.com/"></a><span id="goog_75181966"></span><span id="goog_75181967"></span></div>
Anonymoushttp://www.blogger.com/profile/06100813770559493046noreply@blogger.com5tag:blogger.com,1999:blog-3833072356413502019.post-940646996056417802011-03-29T01:51:00.001+02:002014-01-04T13:36:11.719+02:00Excuse #1 - Writing tests takes too much time<div class="separator" style="clear: both; text-align: left;">
<a href="http://t2.gstatic.com/images?q=tbn:ANd9GcRUAS6289poAwK06GjcypSNx5fa1Q_LBRXDJ-HMdzgLuH7xPXipKg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="http://t2.gstatic.com/images?q=tbn:ANd9GcRUAS6289poAwK06GjcypSNx5fa1Q_LBRXDJ-HMdzgLuH7xPXipKg" /></a></div>
This is the most common excuse in the "<i>Testing: Why Bother?</i>" series, so I'm going to address it first.<br />
It turned out to be a pretty long post (and only the second of several more), but I really think if you'll read everything through it will give you some new insights.<br />
<br />
<span class="Apple-style-span" style="font-size: large;"><b>So... are you claiming testing doesn't take time?</b></span><br />
Well... Of course I'm not. Testing is not free, and you don't HAVE to write automated tests in order to write code that eventually works. But is it really not cost-effective?<br />
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
When I demonstrate unit-testing or TDD to developers new to the field, I frequently get reactions such as "<i>well, that's nice, but I could have implemented the same code much faster without tests.</i>"</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
This statement might be true, but there are several reasons why I think by testing <b>you actually <u style="font-style: italic;">save</u> time</b>:<br />
<br />
<ul>
<li>You don't have to start thinking how to verify that your code works (you already did this)</li>
<li>You are already after the debugging phase</li>
<li>You ensure having automated tests that can run later on</li>
</ul>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
There's also the concept of <b>improving design and usability</b> of your code by testing it, which may also save you time in future, but that's something I'm going to talk about more in the next posts of this series. </div>
</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br />
So lets' dig in and elaborate on all of these points.</div>
<div>
<br />
<a name='more'></a><br /></div>
<div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<span class="Apple-style-span" style="font-size: large;"><b>Your code isn't finished until you have verified it works!</b></span></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<a href="http://upload.wikimedia.org/wikipedia/commons/thumb/7/70/Computer_bug.svg/520px-Computer_bug.svg.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="200" src="http://upload.wikimedia.org/wikipedia/commons/thumb/7/70/Computer_bug.svg/520px-Computer_bug.svg.png" width="173" /></a>I have seen many reckless developers forget this rule. It's sometimes so easy to figure out exactly where is the piece of code you have to change and how you have to change it. You simply change the code quickly and commit it, pretty confident your fix doesn't affect anything else and it works beautifully.</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br />
So many times I've seen this happen, and so many times I found myself covering up for these nasty untested fixes of my irresponsible teammates. Dude! Test your fix before you "mark as done"! Why do I need to rethink what you've done 4 months ago now that you're on the beach in Thailand?</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
When you write tests along with your code, you make sure you get the verification you need to gain confidence in your code and save yourself and your teammates the pain of dealing with this later.</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br />
<br />
<div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<b><span class="Apple-style-span" style="font-size: large;">Don't forget debugging as a part of the equation. </span></b></div>
</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
I have worked in teams that did not test the code during development, and the story was always the same: We allocated way too little slack time for the next release, adding more and more content with little time to test and debug it, and we always ended up either really late on the deadline or working impossible hours to make it on time.</div>
</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
Continuous testing during the development period, preferably TDD, will significantly narrow the debugging time, lower the fixing cost, and help you make it to your deadlines.</div>
</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<a href="http://www.superwebdeveloper.com/wp-content/uploads/relativecostbugfix.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="285" src="http://www.superwebdeveloper.com/wp-content/uploads/relativecostbugfix.png" style="cursor: move;" width="320" /></a>You probably heard already that the earlier a bug is discovered, the easier and cheaper it is to fix it. Take a look on <a href="http://www.superwebdeveloper.com/2009/11/25/the-incredible-rate-of-diminishing-returns-of-fixing-software-bugs/">this excellent post</a> (and chart) as an example.</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
Well, when you test your code immediately along with writing it, you discover a lot of nasty bugs early, that would otherwise result in much higher fixing costs.</div>
</div>
</div>
<div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<span class="Apple-style-span" style="font-size: large;"><b><br />
</b></span></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<span class="Apple-style-span" style="font-size: large;"><b><br />
</b></span></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<span class="Apple-style-span" style="font-size: large;"><b><br />
</b></span></div>
</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<span class="Apple-style-span" style="font-size: large;"><b><br />
</b></span><br />
<span class="Apple-style-span" style="font-size: large;"><b><br />
</b></span><br />
<span class="Apple-style-span" style="font-size: large;"><b>So, I can just test the code manually, isn't it good enough?</b></span></div>
</div>
<div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
The developers that are less reckless than the ones I mentioned earlier, would at least make a manual test to make sure they got the bugfix right. They'll write a main that uses their new code, or at least run the entire system and make sure the new cool feature actually works.</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
Well... If you took the effort to write the main or run the entire system as a manual test, why don't make better use of this time?<br />
Instead - without putting up a much greater amount of time and effort - write an automated reusable test, that could be used for <b>regression</b>!<br />
This way, you will save the future maintainer (mostly, the future <i>you</i>) the pain of manual testing again the next time, and make sure this bug you fixed is not only fixed now, but will remain fixed for as long as the regression tests are being run..</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
</div>
<div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
An automated regression test suite will help you gain confidence for the code, allow you to take responsibility for it, and eliminate <b>the fear factor</b>.</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<span class="Apple-style-span" style="font-size: large;"><b>Fear Factor? What do you mean by that?</b></span><br />
<div class="separator" style="clear: both; text-align: left;">
</div>
</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<a href="http://t3.gstatic.com/images?q=tbn:ANd9GcSnN4gFuef0dH0AuYwUcRqzG0tU0uoZAmfOoRKgsUuWOmkbE2AsZQ" imageanchor="1" style="clear: left; display: inline !important; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://t3.gstatic.com/images?q=tbn:ANd9GcSnN4gFuef0dH0AuYwUcRqzG0tU0uoZAmfOoRKgsUuWOmkbE2AsZQ" /></a>Consider the following story by a close friend of mine:</div>
</div>
<div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
When he was first assigned to work on a legacy untested project, while browsing the code to understand how it works, he came across the following piece of code:</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"><br />
</span></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<span class="Apple-style-span" style="background-color: white; color: #274e13; font-family: 'Courier New', Courier, monospace;">for (int i = 0; i < size; j++) {</span></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<span class="Apple-style-span" style="background-color: white; color: #274e13; font-family: 'Courier New', Courier, monospace;"> // do stuff</span></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<span class="Apple-style-span" style="background-color: white; color: #274e13; font-family: 'Courier New', Courier, monospace;">}</span></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
Wow! Noticed that sneaky <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">j</span> there? It's obvious that something is really wrong here. This is 99% NOT the original intention of the developer. </div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
But what to do? This was code of a production system that seemed to do its job just fine. How could he possibly know if this is a possible bug that needs to be fixed, or an important factor to why the code actually works?</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<br /></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
If he had a TestSuite he could run, after changing that <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">j</span> to an <span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;">i</span><span class="Apple-style-span" style="font-family: inherit;">, he would happily do so! But without it, it's plain scary!</span></div>
<div>
<br /></div>
</div>
<span class="Apple-style-span" style="font-size: large;"><b>The X lines of code misconception</b></span><br />
<a href="http://rlv.zcache.com/typing_is_not_the_bottleneck_dark_colors_tshirt-p235146352940037118q6ws_400.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="http://rlv.zcache.com/typing_is_not_the_bottleneck_dark_colors_tshirt-p235146352940037118q6ws_400.jpg" width="200" /></a>Another common misconception about testing, is a sentence such as: "<i>If a developer writes X lines of code a day, and you want him to spend half of his time and code on tests, he'll go twice as slow writing production code.</i>"<br />
Sounds like plain common sense? Absolutely not!<br />
<div style="direction: ltr;">
Well, I won't write too much about this one, because many words were said on the subject before me. Here's <a href="http://anarchycreek.com/2009/05/26/how-tdd-and-pairing-increase-production/">a great post</a> by GeePawHill about TDD + Pairing, explaining why typing code is NOT the bottleneck.</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<span class="Apple-style-span" style="font-size: large;"><b>OK, I'm convinced... But my manager isn't :(</b></span><br />
When your manager says "<i>Testing is nice, but you have better things to with the little time you have</i>", it can be a real bummer, I would know. But not all is lost!<br />
<br />
<a href="http://kenspen.com/images/bad-boss.jpg" imageanchor="1" style="clear: right; display: inline !important; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="256" src="http://kenspen.com/images/bad-boss.jpg" width="320" /></a>Try not to present "adding tests to our untested code" as a mission by itself. This will almost always get negative reactions from management, and won't be a reasonable justification to postpone development of the next feature by a few days/weeks.<br />
<br />
Instead, just write tests as part of the time frame allocated to you to work on your regular tasks! No one can tell you not to write tests along with your code, as long as you still make it to the deadline. Heck, when they'll see how faster you respond to changes when you have tests - your managers will probably change their negative view and encourage you!<br />
<br />
<div style="direction: ltr;">
A good example of this is how I justified increasing code coverage of a legacy project I inherited (lets call it Project A).</div>
<div style="direction: ltr;">
One of my first tasks in this project, was updating the version of a dependency project (lets' call it Project B). Project B had a bunch of important bugfixes that were relevant for A's next maintenance release, but it also had some major API and behavior changes. I couldn't possibly know what was broken without testing the code heavily, so we allocated time for a task called "upgrading project B to version 1.5", which about 90% of it was used to "adding tests to project A to see what was broken". I ended up writing about a 100 new tests (both unit and integration), catching some nasty bugs we might had found only after the release reached the customers.</div>
<br />
<span class="Apple-style-span" style="font-size: large;"><b><br />
</b></span><br />
<span class="Apple-style-span" style="font-size: large;"><b>That's it for today... What's next?</b></span><br />
<a href="http://t2.gstatic.com/images?q=tbn:ANd9GcQJDYq0y2-O3Xa33qJlOZhEijVWF_klSwyEew-dweEucSRLr1NU" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://t2.gstatic.com/images?q=tbn:ANd9GcQJDYq0y2-O3Xa33qJlOZhEijVWF_klSwyEew-dweEucSRLr1NU" /></a>Whew! That was long...<br />
I hope you learned some new answers to why tests are NOT a waste of time. I can think of more points to make here but this post is already way too long :)<br />
On the next post (which hopefully would be shorter), we'll attend excuse #2, "writing tests is too hard".<br />
The "too hard" excuse is actually closely related to the "takes to much time" one we discussed here, for obvious reasons: The harder it is to test the code, the more time is will take. Eventually, not being cost-effective any more.<br />
<br />
<br />
<br />
Want to know why I think differently? Subscribe to this blog, <a href="http://twitter.com/theyonibomber">follow me on twitter</a>, and you'll know as soon as I publish the next one :)Anonymoushttp://www.blogger.com/profile/06100813770559493046noreply@blogger.com12tag:blogger.com,1999:blog-3833072356413502019.post-43098057590364048242011-03-27T00:36:00.002+02:002011-12-28T08:02:35.146+02:00Testing: Why Bother? - IntroductionI stumbled upon an interesting discussion this week in the <a href="http://lists.idyll.org/listinfo/testing-in-python">testing-in-python mailing list</a>, asking how to explain why testing is important to a "we do not write tests" audience. Because this is something I had to do a few times already, I thought about writing a blog post about it (actually, a series of posts...)<br />
<br />
<span class="Apple-style-span" style="font-size: large;"><b>Testing? What do you mean by that?</b></span><br />
Well, there's a lot of things that can be related as "testing" when talking about software development. There's <a href="http://www.agiledata.org/essays/tdd.html">TDD</a>, Unit tests, Integration tests, having a QA engineer test your code, and more.<br />
In these posts, I'm talking about justifying writing any kind of <b><i>automated</i></b> tests that can be run through a CI (Continuous Integration) system after each commit. It doesn't matter if they were originally written during practicing TDD, the important thing is making sure there's something that's always there to test nothing was broken after each little changeset in the code.<br />
<br />
<span class="Apple-style-span" style="font-size: large;"><b>So, what's the deal? Why do I need to write tests?</b></span><br />
Well, the advantages of testing your software are usually clear and aren't really debatable.<br />
Every one will agree that when you write and run automated tests for your code, you become more confident that your code works, and when you run your tests after each change you make you can gain confidence that you didn't break anything.<br />
The problem is, though these advantages are pretty much obvious and clear to anyone, the majority of developers do NOT write automated tests.<br />
<br />
<span class="Apple-style-span" style="font-size: large;"><b>But, if testing is so awesome, why wouldn't everyone write tests?</b></span><br />
Well, there are 2 kinds of anti-testing developers (that's how I'm going to refer to them from now on).<br />
<div style="direction: ltr;">
One type of anti-testers, are the kind that simply lack the education. Most programmers don't learn how to write tests as part as their formal education, and therefore when they start at their first software industry job, they usually don't write tests unless exposed to this subject as part of the company's training and mentoring. Because concepts like TDD and CI are relatively new, a lot of old-fashioned team leaders and R&D managers are not exposed to the importance of testing as well, and they don't demand this from new employees and don't include this in training them to the job.</div>
<div style="direction: ltr;">
These kind of anti-testing developers are the relatively easy kind. They did not already develop antagonism towards testing, and they <i>may </i>be easily persuaded by fellow pro-testing developers, teammates, managers or external preachers.</div>
The other type of anti-testing developers, is the type that I'm targeting these blog posts towards. These are developers that are already exposed to the concepts, maybe even experimented with testing a little bit in the past, but claim to have some solid reasons why testing is a waste of time for them, and simply do not believe in it. There's usually a list of excuses they give to justify their hostility towards testing.<br />
<br />
<span class="Apple-style-span" style="font-size: large;"><b>The list of excuses</b></span><br />
In my experience as a pro-testing preaching developer, I've come across some various types of resistance. I've collected a list of common excuses for justifying the anti-testing approach:<br />
<ul>
<li><a href="http://codesheriff.blogspot.com/2011/03/excuse-1-writing-tests-takes-too-much.html">Writing tests takes too much time</a></li>
<li><a href="http://codesheriff.blogspot.com/2011/04/excuse-2-writing-tests-is-too-hard.html">Writing tests is too hard</a></li>
<li><a href="http://codesheriff.blogspot.com/2011/07/excuse-3-isnt-it-qas-job-to-test-my.html">It's QA's job, and they are going to test our code anyhow</a></li>
<li><a href="http://codesheriff.blogspot.com/2011/11/excuse-4-running-tests-takes-forever.html" target="_blank">Running the tests takes forever, so we never run them anyhow</a></li>
<li><a href="http://codesheriff.blogspot.com/2011/11/excuse-5-frequent-refactoring-excuse.html" target="_blank">We frequently refactor everything heavily, all the test code is going to break and be irrelevant anyhow</a></li>
<li><a href="http://codesheriff.blogspot.com/2011/12/excuse-6-we-are-such-good-programmers.html" target="_blank">We hire only extremely talented developers. We never have bugs</a></li>
<li>Even if we'll write tests for everything, we're still going to have bugs</li>
<li>It's hard to tell how the code behaves each time, so I can't write a test for it</li>
<li>Writing tests is boooring!</li>
</ul>
<div>
<br /></div>
<div>
In my next posts, I'll try to attend all of these excuses, and clarify why I think they are plain misconceptions.</div>
<div>
<br /></div>
<div>
Can you think of any more excuses? Please let me know in the comments.</div>Anonymoushttp://www.blogger.com/profile/06100813770559493046noreply@blogger.com6tag:blogger.com,1999:blog-3833072356413502019.post-17564266580299695932011-03-26T19:52:00.000+02:002011-03-26T19:52:27.830+02:00First PostHello,<br />
I'm Yoni Tsafir and I'm a software developer from Israel, currently working at IBM (XIV Storage Systems).<br />
<div style="direction: ltr;">Throughout my years as a software developer, I commonly found myself in the position where I'm aspiring to find ways of making myself and my teammates work better and more effectively, applying agile practices such as unit-testing, pair-programming, TDD, continuous integration, and so on. </div><div style="direction: ltr;">Because of my passion to the subject, insisting of everyone writing an informative commit message, not changing code without making sure there's a test for it first, and so on, in one of my teams I even earned the nickname "The Bad Cop of Code", hence the idea for a name for my blog.</div><br />
Following the lead of many great minds I appreciate, I decided to start my own blog and share my thoughts.<br />
<br />
This blog is going to talk about all these subjects I mentioned, and more. It's going to contain tips I gathered from my experience and try to make it easier for fellow "bad cops of code" like me to explain to their fellow teammates why these concepts are important.<br />
<br />
Something else that I have a lot of passion to is music. I'm a music composer, recently composed some TV shows, DVD and musicals for children in Israel. This is something I'll try to take advantage of in order to spice up my posts and share some off-topic interesting content related to the intersection between music and software.<br />
<br />
Hope you'll enjoy reading.<br />
<br />
Finally, I would like to acknowledge some of the other software related blogs, as they were the main inspiration source I had for starting my own.<br />
<br />
<ul><li>Aviv Ben-Yosef's <a href="http://www.codelord.net/">The Code Dump</a>. Aviv is one of the most, if not <i>the-most</i> talented developers I've ever met, and I even had the pleasure of working and pairing with him for a few years. His blog has some amazing posts and ideas.</li>
<li>Iftach Bar's <a href="http://barnashcode.blogspot.com/">Nash Code Bar</a>. Contains an amazing post about hudson/jenkins. Hope to see some more posts like this in the near future!</li>
<li><a href="http://www.irefactor.net/">Uri Lavi's Blog</a>. Founder of the Software Craftsmanship group in Israel (<a href="http://www.linkedin.com/groups?gid=2578449">SCIL</a>).</li>
<li><a href="http://cleancoder.posterous.com/">Uncle Bob's Blog</a>. Author of Clean Code. Contains excellent videos and posts.</li>
<li>GeePawHill's <a href="http://anarchycreek.com/">Situated Geekery</a>. Some of the bests posts I've read about TDD.</li>
<li>Lior Friedman's <a href="http://imistaken.blogspot.com/">IMistaken</a>. Lior gave a very impressive talk in <a href="http://www.linkedin.com/groups?gid=2578449">SCIL</a>, and since then I started reading his very good blog.</li>
<li>Ran Tavory's <a href="http://prettyprint.me/">PrettyPrint</a>. Ran is a fellow member of <a href="http://www.linkedin.com/groups?gid=2578449">SCIL</a>, besides a great podcast (reversim) he runs, he also has a great blog.</li>
</ul>Anonymoushttp://www.blogger.com/profile/06100813770559493046noreply@blogger.com2