<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-8412831559140848595</atom:id><lastBuildDate>Sun, 19 Feb 2012 10:09:31 +0000</lastBuildDate><category>NUnit</category><category>PostSharp</category><category>Resharper</category><category>AOP</category><category>Performance</category><category>TFS</category><category>Podcast</category><category>ALT.NET</category><category>CI</category><category>Thoughts</category><category>VB.NET</category><category>F#</category><category>Mock objects</category><category>MSTest</category><category>Typemock</category><category>Refactoring</category><category>Visual Studio 2010</category><category>Open Source</category><category>Blogging</category><category>C++</category><category>C#</category><category>Reflection</category><category>Productivity</category><category>Multi-threading</category><category>TDD</category><category>Unit tests</category><category>Agile</category><category>BDD</category><category>DSL</category><category>Book review</category><category>Conference</category><category>Tools</category><category>IronRuby</category><category>Presentation</category><category>.NET 4</category><category>Software Craftmanship</category><category>IronPython</category><category>DirectX</category><category>WPF</category><category>Tips and Tricks</category><category>.NET</category><title>Helper Code</title><description /><link>http://blog.drorhelper.com/</link><managingEditor>noreply@blogger.com (Dror Helper)</managingEditor><generator>Blogger</generator><openSearch:totalResults>178</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/HelperCode" /><feedburner:info uri="helpercode" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><creativeCommons:license>http://creativecommons.org/licenses/by/3.0/</creativeCommons:license><image><link>blog.drorhelper.com</link><url>http://blogs.microsoft.co.il/blogs/dhelper/Art/logo_small.png</url><title>Helper Code</title></image><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-6426505831009755642</guid><pubDate>Wed, 15 Feb 2012 20:50:00 +0000</pubDate><atom:updated>2012-02-15T22:54:38.008+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Unit tests</category><category domain="http://www.blogger.com/atom/ns#">Thoughts</category><category domain="http://www.blogger.com/atom/ns#">TDD</category><title>Why you need to make your tests fail</title><description>Test Driven Development (TDD) have many benefits. For start it’s a design methodology that help avoiding “&lt;a href="http://en.wikipedia.org/wiki/Analysis_paralysis" target="_blank"&gt;Analysis paralysis&lt;/a&gt;” and make sure that you only have the needed code to solve a problem.&lt;br /&gt;
Yesterday I found another benefit of writing the tests before the code – you get to see them fail!&lt;br /&gt;
A while back I wrote about another shortcoming of MSTest – how it does not have any built in facility to &lt;a href="http://blog.drorhelper.com/2009/08/checking-expected-exception-message.html" target="_blank"&gt;test against expected exception message&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Unknown to me at the time there was a bug hidden in the code I’ve published – see if you can spot it:
&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;public static class MyAssert
{
    public static void BadThrows;&amp;lt;T&amp;gt;(Action action) where T : Exception
    {
        try
        {
            action();

            Assert.Fail("Exception of type {0} should be thrown.", typeof(T));
        }
        catch (T exception)
        {
     // All is well!
        }
    }
}&lt;/pre&gt;
BTW this example was simplified for your viewing pleasure - I want to make a point here, not stick to the facts. have you found the bug yet? &lt;br /&gt;
&lt;br /&gt;
Consider the following test:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;[TestMethod]
public void ThisTestWouldNeverFail()
{
    MyAssert.BadThrows&amp;lt;exception&amp;gt;(() =&amp;gt; Dummy.SomeMethod());
}&lt;/pre&gt;
Have you guessed it? (hint: its in the test name) &lt;br /&gt;
&lt;br /&gt;
That's right! this test would never have failed. If we take a closer look at &lt;em&gt;BadThrows&lt;/em&gt; we’ll see the problem.&lt;br /&gt;
&lt;br /&gt;
MSTest just like any other .NET unit testing framework throws an exception when assertions fails. In this case because we’re expecting an exception of type &lt;em&gt;Exception&lt;/em&gt; any other exception thrown including the AssertFailedException would be caught – causing the test to pass.&lt;br /&gt;
&lt;br /&gt;
That’s right – because the user expects an exception of type”Exception” to be thrown plus a minor bug the test is completely useless – if you want to see the working code just &lt;a href="http://blog.drorhelper.com/2009/08/checking-expected-exception-message.html" target="_blank"&gt;head to this post&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
I did not find this bug mainly because I don’t like to throw and assert for &lt;em&gt;Exception&lt;/em&gt; seems like a bad practice and in retrospective I should have avoided my co-workers from doing so by throwing exception of my own in case they try to do it.&lt;br /&gt;
&lt;br /&gt;
The guy that did find this bug found it because he wrote a test and wanted to see it fail. That’s right it wasn’t enough for him to know that his code made the test pass – he had to make sure that it failed first – some people…&lt;br /&gt;
A quick search in our code found multiple tests that did exactly that which means two things:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;These test were not written using TDD&lt;/li&gt;
&lt;li&gt;The authors did not even bother to see the tests fail&lt;/li&gt;
&lt;/ol&gt;
After fixing the bug we found one test that started failing – which means that not only was the test wrong – so was the code it was testing.&lt;br /&gt;
&lt;br /&gt;
I’ve talked to the team, explained why throwing “Exception” is not a best practice and why tests need to be “tested” by seeing them fail and we’ve fixed the tests and the code.&lt;br /&gt;
&lt;br /&gt;
I think I learnt quite a lot from this experience, I know now who does TDD and who doesn’t and I found a new problem that occurs when developers write their tests after the code.&lt;br /&gt;
&lt;br /&gt;
Happy coding…&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-6426505831009755642?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=E4uBhWKGZpc:2_J_Fu9CbeQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=E4uBhWKGZpc:2_J_Fu9CbeQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=E4uBhWKGZpc:2_J_Fu9CbeQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=E4uBhWKGZpc:2_J_Fu9CbeQ:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=E4uBhWKGZpc:2_J_Fu9CbeQ:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=E4uBhWKGZpc:2_J_Fu9CbeQ:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=E4uBhWKGZpc:2_J_Fu9CbeQ:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=E4uBhWKGZpc:2_J_Fu9CbeQ:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/E4uBhWKGZpc" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/E4uBhWKGZpc/why-you-need-to-make-your-tests-fail.html</link><author>noreply@blogger.com (Dror Helper)</author><thr:total>1</thr:total><feedburner:origLink>http://blog.drorhelper.com/2012/02/why-you-need-to-make-your-tests-fail.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-8502705576886929494</guid><pubDate>Sat, 28 Jan 2012 15:54:00 +0000</pubDate><atom:updated>2012-01-28T17:54:54.984+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Thoughts</category><title>The developer’s perspective</title><description>&lt;p&gt;You’re lucky you know, said the developer to the consultant. You get to come and save the day and leave before all hell breaks loose.&lt;/p&gt; &lt;p&gt;You got it all wrong said the consultant to the developer. I solve problems, teach best practices and explain what should be done and then they change and twist everything I said and done 5 seconds after I’m gone.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;em&gt;I wanted to share part of a conversation I had with a consultant I know.&lt;/em&gt;&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-8502705576886929494?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=OjtFaqu9VRY:CkHlSSMWUi4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=OjtFaqu9VRY:CkHlSSMWUi4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=OjtFaqu9VRY:CkHlSSMWUi4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=OjtFaqu9VRY:CkHlSSMWUi4:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=OjtFaqu9VRY:CkHlSSMWUi4:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=OjtFaqu9VRY:CkHlSSMWUi4:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=OjtFaqu9VRY:CkHlSSMWUi4:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=OjtFaqu9VRY:CkHlSSMWUi4:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/OjtFaqu9VRY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/OjtFaqu9VRY/developers-perspective.html</link><author>noreply@blogger.com (Dror Helper)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.drorhelper.com/2012/01/developers-perspective.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-1391001044887479353</guid><pubDate>Thu, 26 Jan 2012 20:58:00 +0000</pubDate><atom:updated>2012-01-26T22:58:35.964+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Agile</category><category domain="http://www.blogger.com/atom/ns#">Software Craftmanship</category><title>SCISR Meeting with Corey Haines</title><description>&lt;p&gt;Today I attended a meeting of the &lt;a href="http://www.linkedin.com/groups?home=&amp;amp;gid=2578449&amp;amp;trk=anet_ug_hm"&gt;Software Craftsmanship in Israel&lt;/a&gt; group with &lt;a href="http://coreyhaines.com/"&gt;Corey Haines&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Corey gave a talk about agile practices and how to decide which to choose.&lt;/p&gt;  &lt;p&gt;The talk went something like this:&lt;/p&gt;  &lt;p&gt;Our objective is to reduce the time between doing something and doing the right thing and the time between doing one thing and starting the next one. And thus the goal of every single methodology is to make the feedback loop smaller – at all levels.&lt;/p&gt;  &lt;p&gt;The main reason we want to reduce the feedback loop and provide value as soon as possible is that we want to minimize the cost of change. The cost of adding feature decrease over time – the promise of agile/code craftsmanship is that that time would not be exponentially – it would still be fairly easy to add a new feature a year from now.&lt;/p&gt;  &lt;p&gt;Usually systems begin simple and beautiful and over time as the features accumulate it becomes more and more complicated. This can be handled by using evolution design/Iterative design which means that you take the time to clean your work after adding a feature instead of rushing to the next task on your to do list.&lt;/p&gt;  &lt;p&gt;Early feedback by giving product early. Because it’s much nicer to change a system when its small. Thus reducing the time between doing something and finding out what you should have done.&lt;/p&gt;  &lt;p&gt;The second part of the session was about testing and on how to reduce the Dev-QA feedback cycle which is why too long. In essence the objective is to know if the code today works as well as our code yesterday or even if our code work as well as 5 min. ago. Corey has talked a while about testing and automation and how to reduce the time to deployment.&lt;/p&gt;  &lt;p&gt;One of the key points I liked was that we shouldn’t discuss whether or not a methodology A is better than methodology B we should discuss the value we’ll receive from using that methodology.&lt;/p&gt;  &lt;p&gt;And finally a simple rule: &lt;strong&gt;If you choose not to use a practice, you must replace it with another of equal value.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;Corey has answered a few questions from the audience about how to evaluate the cost of certain practices, mocking and working with legacy code followed by a short exercise – we had to parse &lt;a href="http://www.dangermouse.net/esoteric/piet.html"&gt;Piet&lt;/a&gt; code by hand – namely the following “program”:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dangermouse.net/esoteric/piet/samples.html" target="_blank"&gt;&lt;img style="display: inline; margin-left: 0px; margin-right: 0px" src="http://www.dangermouse.net/esoteric/piet/Piet_hello_big.png" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I caught two of Typemock’s finest – &lt;a href="http://www.gilzilberfeld.com/" target="_blank"&gt;Gil Z.&lt;/a&gt; and &lt;a href="http://eli-shalom.blogspot.com/" target="_blank"&gt;Elisha&lt;/a&gt; writing a parser using unit tests and what looks to be a new soon to be released tool.&lt;/p&gt;  &lt;p&gt;All in all an evening well…   &lt;br /&gt;&lt;/p&gt;  &lt;h3&gt;Just a quick reminder &lt;/h3&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://agilepractitioners2012.com/conference-program/" target="_blank"&gt;&lt;img src="http://agilepractitioners2012.com/wp-content/uploads/2011/11/conflogosmall.jpg" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;I’ll be presenting at the Agile Practitioners conference next week – so don’t forget to come and say hi. And incase you’ve missed Corey’s session or want to hear more of what he has to say about agile and software development in general – come to the Agile Practitioners conference next week.&lt;/p&gt;  &lt;p&gt;Didn’t sign up yet – don’t worry because registration is still open. Just tell them I’ve sent you or better yet &lt;a href="http://www.meda-conferences.com/index.php?option=com_content&amp;amp;view=article&amp;amp;id=101&amp;amp;Itemid=37" target="_blank"&gt;use this link&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;See you there!&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-1391001044887479353?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=mujG9HDSi28:TKqML8DDuLc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=mujG9HDSi28:TKqML8DDuLc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=mujG9HDSi28:TKqML8DDuLc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=mujG9HDSi28:TKqML8DDuLc:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=mujG9HDSi28:TKqML8DDuLc:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=mujG9HDSi28:TKqML8DDuLc:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=mujG9HDSi28:TKqML8DDuLc:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=mujG9HDSi28:TKqML8DDuLc:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/mujG9HDSi28" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/mujG9HDSi28/scisr-meeting-with-corey-haines.html</link><author>noreply@blogger.com (Dror Helper)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.drorhelper.com/2012/01/scisr-meeting-with-corey-haines.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-2026115758280268102</guid><pubDate>Fri, 13 Jan 2012 16:11:00 +0000</pubDate><atom:updated>2012-01-13T18:11:58.708+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Tools</category><category domain="http://www.blogger.com/atom/ns#">Tips and Tricks</category><category domain="http://www.blogger.com/atom/ns#">Agile</category><title>The evolution of a task board</title><description>&lt;p&gt;I’d like to tell you a story about how we manage tasks in my team…&lt;/p&gt;  &lt;p&gt;Once upon a time (about a year and a half ago) I’ve started working in a new place. Since I’ve came from a company with very strong agile practice I wanted my new work place to be as agile as possible – and one of my first “missions” was to improve the way the team’s task tracking.&lt;/p&gt;  &lt;h3&gt;Task Board #1 – Sticky notes&lt;/h3&gt;  &lt;p&gt;I’ve convinced my manager to start using a “task board” which consisted of using sticky notes and one of the walls of the office. And as simple of that we had all of the team’s tasks in a simple, easy to read (and understand) display for the entire world to see. And the improvement was felt immediately. The team members could tell what are the priorities and their current and future work. And the team’s manager was happy because now it was clear what each of us were doing.&lt;/p&gt;  &lt;p&gt;Some of the team liked the idea, some not so much… And over time it was clear who was updating his current progress and who’s tasks didn’t change on the board for the last two iterations.&lt;/p&gt;  &lt;h3&gt;Task board #2 – Distributed&lt;/h3&gt;  &lt;p&gt;I’ve done a quick check with the team to understand how we can improve the task board and one of the problem raised was that because the tasks were displayed on a wall that was less accessible to some of the team members they didn’t update their tasks as often as possible – instead of moving tasks from &lt;em&gt;To-do&lt;/em&gt; to &lt;em&gt;In progress&lt;/em&gt; and then &lt;em&gt;Done&lt;/em&gt; they waited until several such “updates” were accumulated (or until they happen to pass by the wall) before moving the tasks on the board.&lt;/p&gt;  &lt;p&gt;And so we’ve found a solution – each developer had his own task board right above his head. I know it’s not SCRUM but it worked for us.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh6.ggpht.com/-WaTY8cUHVqc/TxBXn4-mj0I/AAAAAAAAC-c/Qgew5vM9vZw/s1600-h/P1030877%25255B7%25255D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="P1030877" border="0" alt="P1030877" src="http://lh4.ggpht.com/-gwUBhnF3KVE/TxBXo9hA6AI/AAAAAAAAC-k/EI362YxofHM/P1030877_thumb%25255B4%25255D.jpg?imgmax=800" width="260" height="200" /&gt;&lt;/a&gt;&lt;a href="http://lh6.ggpht.com/-o3hFLhvkGk8/TxBXqttbSmI/AAAAAAAAC-s/pw5_dxMnxh0/s1600-h/P1030878%25255B5%25255D.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="P1030878" border="0" alt="P1030878" src="http://lh3.ggpht.com/-kUn1NmwdYL4/TxBXrry4pxI/AAAAAAAAC-w/kdx1uZssvFc/P1030878_thumb%25255B2%25255D.jpg?imgmax=800" width="260" height="200" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;And so we’ve continued working this way for a few months until another challenge presented itself…&lt;/p&gt;  &lt;p&gt;From time to time a developer had to work on site which meant that he was out of the office and could not update his backlog another problem was that as the project progressed more and more top managers needed to know what the team is doing and whether or not we were reaching our goals. At about the same time the team has grown and we now were filling two rooms and looking to hire more developers and my manager had problems tracking the team’s goals.&lt;/p&gt;  &lt;h3&gt;Task board #3 – Excel spreadsheet in shared folder&lt;/h3&gt;  &lt;p&gt;Building upon past experience my manager came up with a simple Excel spreadsheet that was placed in a network share and that the team could update. The advantage was that Excel files can be copied, sent on email and shown at meetings a fact that helped explain what we were doing and how much time it would take to project managers, product owners and top management of our company.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh3.ggpht.com/-aVsSbCN3QPw/TxBXs2HjoOI/AAAAAAAAC-8/JQjnsUlI2us/s1600-h/image%25255B4%25255D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/-LMP2NKCAkp8/TxBXt_gnN2I/AAAAAAAAC_E/cRvxRDTInkw/image_thumb%25255B2%25255D.png?imgmax=800" width="1051" height="272" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;We worked with the excel for a few iterations and it worked for us – we could move tasks between the team and everyone knew what everyone did. But the more we’ve used it the more it became clear that this “Excel task board” was holding us back. Since only one user is allowed to update the file – whenever two developers needed to update their progress it caused us grief – especially before start/end of iteration when all of us needed to update the file at once. Another problem was that once an iteration ended another file/book was created and the old iteration data was “archived” never to be seen again.&lt;/p&gt;  &lt;p&gt;We knew we needed a better solution and we’ve found one just under our nose – TFS. We were already using TFS for source control and continuous integration (CI) server so why not use it to track our tasks as well.&lt;/p&gt;  &lt;h3&gt;Task board #4 – TFS + Work Item Manager&lt;/h3&gt;  &lt;p&gt;I was able to update the TFS Task using Visual Studio and we had a simple SCRUM workflow:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://lh5.ggpht.com/-DvbbvRI7hr0/TxBXvrnOZII/AAAAAAAAC_M/bacQk-3G3W8/s1600-h/image%25255B12%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/-XoHqyT6AbE4/TxBXxDdWx-I/AAAAAAAAC_U/YLcr31_J_N4/image_thumb%25255B8%25255D.png?imgmax=800" width="644" height="274" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Using this task we were now able to use TFS as our backlog and task board. Another added bonus is that using &lt;a href="http://www.telerik.com/agile-project-management-tools/wim-and-projectdashboard/tfs-work-item-manager-features.aspx"&gt;Telerik’s TFS Work Item Manager&lt;/a&gt; we were able to see the old task board we were used to see on the office wall:&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-xJzRqEsdhkU/TxBXy7ZMbII/AAAAAAAAC_c/4_Z0ZXTWS2U/image%25255B21%25255D.png?imgmax=800" width="644" height="346" /&gt;&lt;/p&gt;  &lt;p&gt;Now we had it all:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;System that we can update easily – from the comfort of our Visual Studio &lt;/p&gt;    &lt;p&gt;Easy to understand visualization&lt;/p&gt;    &lt;p&gt;Statistics on iteration, remaining tasks and team progress&lt;/p&gt;    &lt;p&gt;Project dashboard&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;And this is how we work today.&lt;/p&gt;  &lt;h3&gt;Conclusion&lt;/h3&gt;  &lt;p&gt;The lesson of this tale is that you should not be afraid to change. Just because we were using a tool that worked for us in the past didn’t mean that that tool cannot be changed if a better alternative is available, or if he required functionality changes. Because being agile is embracing change not just in the product you’re delivering but also the way you deliver it.&lt;/p&gt;  &lt;h3&gt;One final note&lt;/h3&gt;  &lt;p&gt;Using a task board is a simple practice and yet many teams just don’t track their tasks properly. Showing my team to use a task board is only one of the ways I’ve used to make them more “Agile”. If you’d want to learn more about how to make your team more agile or looking for tips and tricks that I found useful – I’ll be talking about it on my &lt;a href="http://agilepractitioners2012.com/conference-program/creating-change-from-within-%E2%80%93-the-agile-developer-story/"&gt;session&lt;/a&gt; at the &lt;a href="http://agilepractitioners2012.com/"&gt;Agile Practitioners Conference&lt;/a&gt; at the end of this month.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Happy Coding…&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-2026115758280268102?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=bkkM1ay-nWU:sIAWJv4ZfIc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=bkkM1ay-nWU:sIAWJv4ZfIc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=bkkM1ay-nWU:sIAWJv4ZfIc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=bkkM1ay-nWU:sIAWJv4ZfIc:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=bkkM1ay-nWU:sIAWJv4ZfIc:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=bkkM1ay-nWU:sIAWJv4ZfIc:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=bkkM1ay-nWU:sIAWJv4ZfIc:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=bkkM1ay-nWU:sIAWJv4ZfIc:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/bkkM1ay-nWU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/bkkM1ay-nWU/evolution-of-task-board.html</link><author>noreply@blogger.com (Dror Helper)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-gwUBhnF3KVE/TxBXo9hA6AI/AAAAAAAAC-k/EI362YxofHM/s72-c/P1030877_thumb%25255B4%25255D.jpg?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.drorhelper.com/2012/01/evolution-of-task-board.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-7522116705452283424</guid><pubDate>Sat, 10 Dec 2011 17:11:00 +0000</pubDate><atom:updated>2011-12-10T19:11:26.652+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Podcast</category><category domain="http://www.blogger.com/atom/ns#">BDD</category><category domain="http://www.blogger.com/atom/ns#">Unit tests</category><category domain="http://www.blogger.com/atom/ns#">Thoughts</category><category domain="http://www.blogger.com/atom/ns#">Agile</category><category domain="http://www.blogger.com/atom/ns#">TDD</category><title>TDD vs. BDD or why can’t we all just get along?</title><description>&lt;p&gt;I was listening to another good Hanselminuets podcast - &lt;a href="http://hanselminutes.com/294/understanding-bdd-and-nspec-with-matt-florence-and-amir-rajan" target="_blank"&gt;Understanding BDD and NSpec with Matt Florence and Amir Rajan&lt;/a&gt;. As always it was a good an informative show. Towards the end of the show one of the interviewees (I think it was Amir) explained why BDD is much better than TDD…&lt;/p&gt;  &lt;div&gt;&lt;a href="http://www.flickr.com/photos/17548912@N00/2267888653/" target="_blank"&gt;&lt;img title="Fight Night Punch Test by djclear904, on Flickr" border="0" alt="Fight Night Punch Test by djclear904, on Flickr" src="http://farm3.static.flickr.com/2408/2267888653_44cba21479_m.jpg" /&gt;&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://creativecommons.org/licenses/by-nc-sa/2.0/" target="_blank"&gt;&lt;img title="Creative Commons Attribution-Noncommercial-Share Alike 2.0 Generic License" border="0" alt="Creative Commons Attribution-Noncommercial-Share Alike 2.0 Generic License" align="left" src="http://i.creativecommons.org/l/by-nc-sa/2.0/80x15.png" /&gt;&lt;/a&gt;&amp;#160; by &lt;a href="http://www.flickr.com/people/17548912@N00/" target="_blank"&gt; djclear904&lt;/a&gt;&lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;For those of you who does not know what I’m talking about – TDD is &lt;strong&gt;T&lt;/strong&gt;est &lt;strong&gt;D&lt;/strong&gt;riven &lt;strong&gt;D&lt;/strong&gt;evelopment (or design) and BDD is &lt;strong&gt;B&lt;/strong&gt;ehavior &lt;strong&gt;D&lt;/strong&gt;riven &lt;strong&gt;D&lt;/strong&gt;evelopment. TDD is more “low level” talking about unit tests and integration tests and how to write code that test code while BDD is about specifications and behaviors. &lt;/p&gt;  &lt;p&gt;In TDD we talk about &lt;a href="http://c2.com/cgi/wiki?ArrangeActAssert" target="_blank"&gt;Arrange Act Assert&lt;/a&gt; while in BDD we have &lt;a href="http://en.wikipedia.org/wiki/Behavior_Driven_Development" target="_blank"&gt;Given When Then&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Each methodology has its own frameworks that help write and run tests (or specifications) that make sure our code does what it meant to do.&lt;/p&gt;  &lt;p&gt;Am I the only one that see a resemblance?&lt;/p&gt;  &lt;p&gt;You might argue that one is better than the other till you blue in the face it does not change the fact that they are two sides of the same coin.&lt;/p&gt;  &lt;p&gt;There are differences – BDD is more “high level” dealing with specifications and was intended to be used by domain experts as well as developers – although I’m yet to find the product manager that would write specifications. On the other side TDD is developer oriented and intended to be used by people who write and read code daily.&lt;/p&gt;  &lt;p&gt;But regardless of these differences I don’t really see a reason why you should choose one over the other. I confess I use TDD and unit/integration tests in most of my projects but I do have several projects where I use both. I like the fact that I can write unit tests as well as specifications – because I need to test both. I also find myself using unit testing framework (i.e. NUnit) to write more “BDD’ish” kind of tests.&lt;/p&gt;  &lt;p&gt;And so I don’t really understand why one is better than the other. Mainly because I prefer to use both – when possible.&lt;/p&gt;  &lt;p&gt;And if you never tried BDD (or TDD) before I suggest you do and see for yourself.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Happy Coding…&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-7522116705452283424?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=yJ0be21Ua8M:8_lRZM5A8jE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=yJ0be21Ua8M:8_lRZM5A8jE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=yJ0be21Ua8M:8_lRZM5A8jE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=yJ0be21Ua8M:8_lRZM5A8jE:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=yJ0be21Ua8M:8_lRZM5A8jE:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=yJ0be21Ua8M:8_lRZM5A8jE:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=yJ0be21Ua8M:8_lRZM5A8jE:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=yJ0be21Ua8M:8_lRZM5A8jE:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/yJ0be21Ua8M" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/yJ0be21Ua8M/tdd-vs-bdd-or-why-cant-we-all-just-get.html</link><author>noreply@blogger.com (Dror Helper)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm3.static.flickr.com/2408/2267888653_44cba21479_t.jpg" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/12/tdd-vs-bdd-or-why-cant-we-all-just-get.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-4810696109019016240</guid><pubDate>Tue, 22 Nov 2011 16:46:00 +0000</pubDate><atom:updated>2011-11-22T18:59:30.126+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Refactoring</category><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">Tips and Tricks</category><category domain="http://www.blogger.com/atom/ns#">C#</category><title>Refactor “if” statements - functional programming style</title><description>Have you ever seen code that look like this:    &lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true;"&gt;public string GetStatusDescription(Model model)
{
    if(model.HasProblemReports)
    {
        return "Errors";
    }

    if(model.SystemState.WorkingMode == WorkingMode.NotManaged)
    {
        return "Manual";
    }

    if(model.SystemState.IsInitializing)
    {
        return "Initialize";
    }

    if(!model.SystemState.InService)
    {
        return "Not in service";
    }

    if(model.SystemState.WorkingMode == WorkingMode.Paused)
    {
        return "Paused";
    }

    if(model.Storage.Objects.Any(obj =&amp;gt; obj.IsMoving))
    {
       return "Movement in storage";
    }

    return string.Empty;
}&lt;/pre&gt;
&lt;br /&gt;
I know I have – yesterday, I’ve changed the variable names and removed a bit of plumbing code but in essence this is a real function I had to work with. &lt;br /&gt;
&lt;br /&gt;
The problem with this kind of code that it start out simple but quickly becomes hard to read and maintain. Because the ordering of the “if” statements matters as much as the condition itself.&lt;br /&gt;
&lt;br /&gt;
One solution is to use the well known &lt;a href="http://www.dofactory.com/Patterns/PatternChain.aspx" target="_blank"&gt;Chain of Responsibility pattern&lt;/a&gt;. although it would probably work in this case, I’ve noticed that developers shy from using it in code similar to this example. It’s as if they feel that they “waste” good code by creating a”whole class for two lines of code”. Another reason not to use CoR is that in this case I don’t want to encapsulate the logic of this method in a lot of classes – I just want to be able to easily understand what the method does and add/remove/update it easily.&lt;br /&gt;
&lt;br /&gt;
I literally felt pain writing each new “if” statement until I could take it no more and so I’ve decided to refactor it.&lt;br /&gt;
&lt;br /&gt;
First I’ve created a class to hold each condition:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true;"&gt;class ModelToMessage
{
    private Func&amp;lt;Model, bool&amp;gt; _predicate;

    public ModelToMessage(Func&amp;lt;model ,="" bool=""&amp;gt; predicate, string message)
    {
        _predicate = predicate;

        Message = message;
    }

    public bool IsValid(Model model)
    {
        return _predicate(model);
    }

    public string Message{get; private set;}
}&lt;/pre&gt;
&lt;br /&gt;
Using this new class I was able to declare the following list and refactor my method:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true;"&gt;private List&amp;lt;modeltomessage&amp;gt; _messageCreators = new List&amp;lt;modeltomessage&amp;gt;
    {
        new ModelToMessage(model =&amp;gt; model.HasProblemReports, "Errors"),
        new ModelToMessage(model =&amp;gt; model.SystemState.WorkingMode == WorkingMode.NotManaged, "Manual"),
        new ModelToMessage(model =&amp;gt; model.SystemState.IsInitializing, "Initialize"),
        new ModelToMessage(model =&amp;gt; !model.SystemState.InService, "Not in service"),
        new ModelToMessage(model =&amp;gt; model.SystemState.WorkingMode == WorkingMode.Paused, "Paused"),
        new ModelToMessage(model =&amp;gt; model.Storage.Objects.Any(obj =&amp;gt; obj.IsMoving), "Movement in storage"),
        new ModelToMessage(model =&amp;gt; true, string.Empty),
    };

public string GetStatusDescription(Model model)
{
   var messageCreator = _messageCreators.First(mc =&amp;gt; mc.IsValid(model));

    return messageCreator.Message;
}&lt;/pre&gt;
&lt;br /&gt;
The last item on the list is the “default” item that is always true and return an empty string.&lt;br /&gt;
&lt;br /&gt;
I really like the fact that it’s easy to understand which message comes before which message and it’s easy to add new conditions and change their priority.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Happy coding…&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-4810696109019016240?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=AyT0IYeaoUE:DiP3817e_1s:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=AyT0IYeaoUE:DiP3817e_1s:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=AyT0IYeaoUE:DiP3817e_1s:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=AyT0IYeaoUE:DiP3817e_1s:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=AyT0IYeaoUE:DiP3817e_1s:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=AyT0IYeaoUE:DiP3817e_1s:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=AyT0IYeaoUE:DiP3817e_1s:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=AyT0IYeaoUE:DiP3817e_1s:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/AyT0IYeaoUE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/AyT0IYeaoUE/have-you-ever-seen-code-that-look-like.html</link><author>noreply@blogger.com (Dror Helper)</author><thr:total>10</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/11/have-you-ever-seen-code-that-look-like.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-1868053183253995223</guid><pubDate>Sun, 06 Nov 2011 18:52:00 +0000</pubDate><atom:updated>2011-11-07T11:02:34.275+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">PostSharp</category><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">C#</category><category domain="http://www.blogger.com/atom/ns#">ALT.NET</category><category domain="http://www.blogger.com/atom/ns#">AOP</category><title>List executed code using PostSharp</title><description>This post was created to answer a question by Laimonas Simutis on the ALT.NET mailing list – &lt;a href="http://tech.groups.yahoo.com/group/altdotnet/message/24501" target="_blank"&gt;how to list all executed code&lt;/a&gt;…&lt;br /&gt;
There where many good ideas and your truly suggested using PostSharp – mainly because this is one of the examples I use in my AOP and PostSharp presentation. And so without further ado here is my solution for your consideration:&lt;br /&gt;
&lt;h3&gt;The “tracing” attribute&lt;/h3&gt;
For this purpose I choose to use &lt;em&gt;OnMethodBoundaryAspect &lt;/em&gt;which enable me to add hooks on method’s enter and exit:&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true;"&gt;[Serializable]
[MulticastAttributeUsage(MulticastTargets.Method, AllowMultiple = true)]
public class TraceMethodCallsAttribute : OnMethodBoundaryAspect
{
    private string _methodName;

    public override void CompileTimeInitialize(System.Reflection.MethodBase method, AspectInfo aspectInfo)
    {
        _methodName = method.DeclaringType.Name + "." + method.Name;
    }
    

    public override void OnEntry(MethodExecutionArgs args)
    {
        Console.WriteLine("&amp;gt;&amp;gt; {0}", _methodName);
    }

    public override void OnExit(MethodExecutionArgs args)
    {
        Console.WriteLine("&amp;lt;&amp;lt; {0}", _methodName);
    }
}&lt;/pre&gt;
This is your simple method boundary aspect which is good to add custom functionality before and after method call as well as on exception and/or successful completion. This time I only needed the enter and exit functionality.&lt;br /&gt;
My attribute has several attribute of it’s own, one simple for serialization and the other is where the magic happens – the &lt;em&gt;MulticastAttributeUsage&lt;/em&gt; that tells PostSharp that this attribute should be automatically applied to every method in the class or assembly.&lt;br /&gt;
Other than that I’ve also used &lt;em&gt;CompileTimeInitialize&lt;/em&gt; in order to save some cycles by “calculating” the method name only once (at compile time) instead of each time the method is called.&lt;br /&gt;
&lt;h3&gt;Using the attribute&lt;/h3&gt;&lt;br /&gt;
Now all I have to do is add this line to the &lt;em&gt;AsseblyInfo.cs&lt;/em&gt; file:&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true;"&gt;[assembly: TraceMethodCalls]&lt;/pre&gt;
And that’s it – running the following program:&lt;br /&gt;
&lt;pre class="brush: csharp; ruler: true;"&gt;class Program
{
    static void Main(string[] args)
    {
        var a = new A();
        for (int i = 0; i &amp;lt; 3; i++)
        {
            a.MethodOne();
            a.MethodTwo();
        }
    }
}

public class A
{
    public void MethodOne()
    {
        Console.WriteLine("I am in method one");
    }

    public void MethodTwo()
    {
        Console.WriteLine("I am in method two");
    }
}&lt;/pre&gt;
Provides the desired result&lt;a href="http://lh3.ggpht.com/-axv64ee-lGk/TrbXg1bhCUI/AAAAAAAAC90/a-Ne7C0-HaE/s1600-h/image%25255B4%25255D.png"&gt;&lt;img alt="image" border="0" height="346" src="http://lh5.ggpht.com/-C7KsXSpdzsU/TrbXibHhabI/AAAAAAAAC98/gJ6tz2-LOxw/image_thumb%25255B2%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="681" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Happy coding…&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-1868053183253995223?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=2wsp2GcVJ-4:DK93QJsn6dU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=2wsp2GcVJ-4:DK93QJsn6dU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=2wsp2GcVJ-4:DK93QJsn6dU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=2wsp2GcVJ-4:DK93QJsn6dU:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=2wsp2GcVJ-4:DK93QJsn6dU:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=2wsp2GcVJ-4:DK93QJsn6dU:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=2wsp2GcVJ-4:DK93QJsn6dU:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=2wsp2GcVJ-4:DK93QJsn6dU:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/2wsp2GcVJ-4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/2wsp2GcVJ-4/list-executed-code-using-postsharp.html</link><author>noreply@blogger.com (Dror Helper)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-C7KsXSpdzsU/TrbXibHhabI/AAAAAAAAC98/gJ6tz2-LOxw/s72-c/image_thumb%25255B2%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/11/list-executed-code-using-postsharp.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-5054535329052495606</guid><pubDate>Sat, 29 Oct 2011 08:09:00 +0000</pubDate><atom:updated>2011-10-29T10:10:49.125+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Tools</category><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">AOP</category><title>Three .NET "tools" that I use every day and you want to know about</title><description>&lt;p&gt;Time is a very limited and expensive resource. As a software developer I feel more often than not that I just don’t have enough of it…&lt;/p&gt;&lt;p&gt;That’s why whenever I find a new library or tool that save me time I embrace it with both hands, especially if they preform tasks that I find boring and tedious.&lt;/p&gt;&lt;p&gt;the following is a short list of three such tools that I find myself using daily because using them means that instead of writing the same code over and over again I get to focus on more interesting aspects of my job.&lt;/p&gt;&lt;h3&gt;&lt;a href="http://csd.codeplex.com/" target="_blank"&gt;Configuration Section Designer&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;&lt;u&gt;What is it&lt;/u&gt;:&lt;/strong&gt; Visual Studio (2008/2010) add-in&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;u&gt;License&lt;/u&gt;:&lt;/strong&gt; Microsoft Public License (Ms-PL)&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;u&gt;Website&lt;/u&gt;:&lt;/strong&gt; &lt;a href="http://csd.codeplex.com"&gt;http://csd.codeplex.com&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Most project I know have some form of configuration, in the .NET world it usually means one or more XML files that have various key-value pairs that are used to store “configurable” application settings. The problem is that if you want to harness the full power of configuration that is available you have to learn quite a lot about &lt;em&gt;configuration sections &lt;/em&gt;and/or write quite a lot of boilerplate code to serialize and de-serialize the configuration files properly. &lt;/p&gt;&lt;p&gt;Enter Configuration section designer – a visual studio add-in that help create and edit configuration sections (structure) visually. It’s really simple to use and about after 5 minuets you’ll be able to use it to create the configuration files you’ve always wanted.&lt;/p&gt;&lt;p&gt;After visually creating your configuration design you get the following:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;XSD schema that you can use to add intelligence to your configuration files creation process &lt;/li&gt;
&lt;li&gt;A &lt;em&gt;config&lt;/em&gt; fie with simple outline that you can fill. &lt;/li&gt;
&lt;li&gt;C# serialize/de-serialize file that is simple and easy to use to load/save the files from your application &lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;CSD saves me hours each week - It slices, it dices and it verifies that your configuration is valid. I can created custom types and converters and it manages to stay simple and easy to use.&lt;/p&gt;&lt;p&gt;This open source project was dormant for quite some time and I’ve started to think its development was stopped, but I’m glad I was wrong with the new version that supports VS2010 CSD seems more alive than ever!&lt;/p&gt;&lt;h3&gt;&lt;a href="http://automapper.codeplex.com/" target="_blank"&gt;AutoMapper&lt;/a&gt;&lt;/h3&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;&lt;u&gt;What is it&lt;/u&gt;:&lt;/strong&gt; .NET library&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;u&gt;License&lt;/u&gt;:&lt;/strong&gt; MIT license&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;u&gt;Website&lt;/u&gt;:&lt;/strong&gt; &lt;a href="https://github.com/AutoMapper/AutoMapper"&gt;https://github.com/AutoMapper/AutoMapper&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;I hate writing conversion code. Converting one class to another class is tedious, error prone and it feels just “wrong”. &lt;/p&gt;&lt;p&gt;The problem is that there are quite a lot of architecture solutions that requires converting object from system A to a different object in system B. Luckily with AutoMapper all of the A.X = B.Y code just go away.&lt;/p&gt;&lt;p&gt;Mapping from the application’s internal object mode to DTO (Data Transfer Objects) or view model has never been easier. With a plethora of conversion abilities from simple property to property mapping up to custom converters. And if you build your classes the right way most of the conversion is done automatically.&lt;/p&gt;&lt;p&gt;It’s well documented and has a very good &lt;a href="https://github.com/AutoMapper/AutoMapper/wiki/Getting-started" target="_blank"&gt;getting started guide&lt;/a&gt; that would get you up and running in no time. Using it at work was a simple matter of &lt;em&gt;Add reference &lt;/em&gt;and I was ready to go. Since then AutoMapper has helped me rid of quite a lot of hard to read, error prone lines of code.&lt;/p&gt;&lt;h3&gt;PostSharp&lt;/h3&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;&lt;u&gt;What is it&lt;/u&gt;:&lt;/strong&gt; .NET library&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;u&gt;License&lt;/u&gt;:&lt;/strong&gt; Commercial (has free edition)&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;u&gt;Website&lt;/u&gt;:&lt;/strong&gt; &lt;a href="http://www.sharpcrafters.com/"&gt;http://www.sharpcrafters.com/&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;I’ve started been using PostSharp extensively and never looked back. I keep finding new ways to harness its power and I’m happy to see that more and more of my co-workers are solving problems easily using AOP (Aspect Oriented Programming). &lt;/p&gt;&lt;p&gt;Using PostSharp I’m able to create “attributes” that encapsulate cross-application concerns and I’ve stopped counting the times that my logging attribute has helped us track a bug in one of our servers.&lt;/p&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;p&gt;With each new tool under my belt I become better at my job. The examples above are only three such tools and I’m always happy to learn about a new one I can use.&lt;/p&gt;&lt;p&gt;So if you enjoy learning new tricks - try them for size and decide if they’re good for you.&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Happy coding…&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-5054535329052495606?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=60y4L7aUuHU:2poKav4bikc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=60y4L7aUuHU:2poKav4bikc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=60y4L7aUuHU:2poKav4bikc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=60y4L7aUuHU:2poKav4bikc:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=60y4L7aUuHU:2poKav4bikc:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=60y4L7aUuHU:2poKav4bikc:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=60y4L7aUuHU:2poKav4bikc:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=60y4L7aUuHU:2poKav4bikc:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/60y4L7aUuHU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/60y4L7aUuHU/three-net-projects-that-i-use-every-day.html</link><author>noreply@blogger.com (Dror Helper)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/10/three-net-projects-that-i-use-every-day.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-5377319610677740747</guid><pubDate>Wed, 05 Oct 2011 18:26:00 +0000</pubDate><atom:updated>2011-10-05T20:26:43.410+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Tools</category><category domain="http://www.blogger.com/atom/ns#">Presentation</category><category domain="http://www.blogger.com/atom/ns#">Agile</category><title>Agile toolkit session at ILTAM</title><description>&lt;p&gt;Today I had the pleasure I had a session at &lt;a href="http://www.iltam.org/info_eng.php?id=sd_abouteng" target="_blank"&gt;ILTAM&lt;/a&gt; where I talked about the tools used in an agile software development. It was&amp;#160; a mixed crowd of software developers, testers, team leads, project managers (and change) and it was fun trying to make the topic relevant to all of the audience at the same time.&lt;/p&gt;  &lt;div style="width: 425px" id="__ss_9561406"&gt;&lt;strong style="margin: 12px 0px 4px; display: block"&gt;&lt;a title="Agile toolkit" href="http://www.slideshare.net/dhelper/agile-toolkit"&gt;Agile toolkit&lt;/a&gt;&lt;/strong&gt;&lt;object id="__sse9561406" width="425" height="355"&gt;&lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=agiletoolkit-111005122915-phpapp01&amp;amp;stripped_title=agile-toolkit&amp;amp;userName=dhelper" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;param name="allowScriptAccess" value="always" /&gt;&lt;embed name="__sse9561406" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=agiletoolkit-111005122915-phpapp01&amp;amp;stripped_title=agile-toolkit&amp;amp;userName=dhelper" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;    &lt;div style="padding-bottom: 12px; padding-left: 0px; padding-right: 0px; padding-top: 5px"&gt;View more &lt;a href="http://www.slideshare.net/"&gt;presentations&lt;/a&gt; from &lt;a href="http://www.slideshare.net/dhelper"&gt;Dror Helper&lt;/a&gt;.&lt;/div&gt; &lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Happy coding…&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-5377319610677740747?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=_nE0ErKlGpc:Gsomt7v88v0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=_nE0ErKlGpc:Gsomt7v88v0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=_nE0ErKlGpc:Gsomt7v88v0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=_nE0ErKlGpc:Gsomt7v88v0:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=_nE0ErKlGpc:Gsomt7v88v0:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=_nE0ErKlGpc:Gsomt7v88v0:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=_nE0ErKlGpc:Gsomt7v88v0:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=_nE0ErKlGpc:Gsomt7v88v0:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/_nE0ErKlGpc" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/_nE0ErKlGpc/agile-toolkit-session-at-iltam.html</link><author>noreply@blogger.com (Dror Helper)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/10/agile-toolkit-session-at-iltam.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-4444737102816043227</guid><pubDate>Tue, 20 Sep 2011 20:54:00 +0000</pubDate><atom:updated>2011-09-20T23:54:23.737+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Thoughts</category><category domain="http://www.blogger.com/atom/ns#">Agile</category><title>Essence of agile</title><description>&lt;p&gt;Recently I had the pleasure to meet two developers with very different “styles” of software development. The first have never heard of SCRUM and never practiced any of the agile methodologies while the second is a certified SCRUM master and has used SCRUM to manage his team.&lt;/p&gt;  &lt;p&gt;Both were given a problem to solve in one hour, although both haven't finished writing when time was up I learnt quite a lot from the bits they did finish.&lt;/p&gt;  &lt;p&gt;Both finished about 50% of the required functionality but while one had one working feature the other only managed to finish the “infrastructure” needed to solve the problem. Although it can be argued who done a better job, it is clear which of the solutions is “more agile” (hint – the one that provide value).&lt;/p&gt;  &lt;p&gt;The weird thing is that the developer without any “formal” agile experience choose to implement the solution vertically one feature at a time while the agile savvy developer got stuck implementing “architecture” showing zero value when his time was up.&lt;/p&gt;  &lt;p&gt;So what do you think – which one knows more about what agile means?&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-4444737102816043227?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=ph7Y1-oA0IE:WwXpF5isHJE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=ph7Y1-oA0IE:WwXpF5isHJE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=ph7Y1-oA0IE:WwXpF5isHJE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=ph7Y1-oA0IE:WwXpF5isHJE:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=ph7Y1-oA0IE:WwXpF5isHJE:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=ph7Y1-oA0IE:WwXpF5isHJE:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=ph7Y1-oA0IE:WwXpF5isHJE:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=ph7Y1-oA0IE:WwXpF5isHJE:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/ph7Y1-oA0IE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/ph7Y1-oA0IE/essence-of-agile.html</link><author>noreply@blogger.com (Dror Helper)</author><thr:total>4</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/09/essence-of-agile.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-7247369068133166260</guid><pubDate>Wed, 07 Sep 2011 19:49:00 +0000</pubDate><atom:updated>2011-09-08T14:14:36.679+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">PostSharp</category><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">Unit tests</category><category domain="http://www.blogger.com/atom/ns#">Tips and Tricks</category><category domain="http://www.blogger.com/atom/ns#">C#</category><category domain="http://www.blogger.com/atom/ns#">MSTest</category><title>Enabling parameterized tests in MSTest using PostSharp</title><description>&lt;p&gt;I have blogged about the shortcoming of Microsoft’s unit testing framework in the past. It has very good Visual Studio (and TYFS) integration out of the box but it seems that in order to use it I have to suffer lack of functionality I’m used to taking for granted when using any other .NET unit testing framework out there. ON the of feature I miss most is RowTest (Theory for you XUnit users). When using MSTest I want to be able to create a test that receive parameters. It shames me to have to tell a co-worker to write 10 (or more) different tests that test the exact functionality with differed conditions.&lt;/p&gt;&lt;p&gt;There is a way to run parameterized tests in MSTest namely &lt;a href="http://codeclimber.net.nz/archive/2008/01/18/How-to-simulate-RowTest-with-MS-Test.aspx" target="_blank"&gt;data-driven tests&lt;/a&gt; the downside is that you have to create an &lt;u&gt;external&lt;/u&gt; file to host the parameters making the test less readable to my taste. Another alternative is to use MSTest that comes with VS2010 and extend it – &lt;a href="http://blog.drorhelper.com/2011/01/how-to-add-rowtest-support-to-mstest.html" target="_blank"&gt;I wrote about it in a previous blog post&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;I’ve decided to create another solution for those of you that do not use VS2010 and .NET 4 or do not want to extend the testing framework – using data-driven test and the power of &lt;a href="http://www.sharpcrafters.com/" target="_blank"&gt;PostSharp&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;The incidents&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;One test marked as a test class no parameters &lt;/li&gt;
&lt;li&gt;One test with the same name with parameters &lt;/li&gt;
&lt;li&gt;One simple RowAttribute to keep the parameters &lt;/li&gt;
&lt;li&gt;One PostSharp OnInvocation attribute to do all of the magic &lt;/li&gt;
&lt;li&gt;Mix &amp;amp; Run &lt;/li&gt;
&lt;/ol&gt;&lt;h3&gt;The Test(s)&lt;/h3&gt;&lt;p&gt;Because of MSTest limitation will need two functions with the same name. The first one without parameters will be used as a host test method to run and the second will contain the actual test code:&lt;/p&gt;&lt;pre class="brush: csharp; ruler: true;"&gt;[TestClass]
public class MyRowTests
{
    public TestContext TestContext { get; set; }

    [TestMethod, RowTest]
    [DeploymentItem(@&amp;quot;..\..\SimpleRowTest.xml&amp;quot;)]
    [DataSource(&amp;quot;Microsoft.VisualStudio.TestTools.DataSource.XML&amp;quot;,
     &amp;quot;|DataDirectory|\\SimpleRowTest.xml&amp;quot;,
     &amp;quot;Row&amp;quot;, DataAccessMethod.Sequential)]
    public void SimpleRowTest()
    {

    }

    [Row(1, 2, 3)]
    [Row(3, 2, 5)]
    [Row(3, 4, 9)]
    [Row(3, 4, 7)]
    public void SimpleRowTest(int x, int y, int result)
    {
        Assert.AreEqual(result, x + y);
    }
}&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;The first method is the one MSTest know and respect and we’re going to use it to run the second method. I’ve added &lt;em&gt;DeploymentItem&lt;/em&gt; and &lt;em&gt;DataSource&lt;/em&gt; attribute to run the xml file that is going to be generated with the data from the &lt;em&gt;Row&lt;/em&gt; attributes.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: It is important that the deployment item would point to the relative path of the test project file from the solution file – this is one nasty bit of code and I wish I could find a way to throw it away.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: It is crucial that you have &lt;em&gt;TestContext&lt;/em&gt; defined in the test class as well – otherwise MSTest won’t be able to access the test’s parameters:&lt;/p&gt;&lt;h3&gt;RowAttribute&lt;/h3&gt;&lt;p&gt;This is a plain old C# attribute – nothing special, just a container to hold the row test data:&lt;/p&gt;&lt;pre class="brush: csharp; ruler: true;"&gt;[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class RowAttribute : Attribute
{
    private readonly object[] _rowParameters;

    public RowAttribute(params object[] rowParameters)
    {
        _rowParameters = rowParameters;
    }

    public object[] Parameters
    {
        get { return _rowParameters; }
    }
}&lt;/pre&gt;&lt;p&gt;It’s marked to be used on a method and that it can be applied multiple times and that’s it./p&gt;&lt;br /&gt;
&lt;h3&gt;RowTestAttribute&lt;/h3&gt;&lt;p&gt;This is where the magic happens! The attribute does two things:creates a xml data source file and run the method with the parameters. Inheriting from &lt;em&gt;MethodInterceptionAspect &lt;/em&gt;enables hooking into two events – compilation of the class and when it runs:&lt;/p&gt;&lt;pre class="brush: csharp; ruler: true;"&gt;[Serializable]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class RowTestAttribute : MethodInterceptionAspect
{
    private MethodInfo _methodToInvoke;

    public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
    {
        base.CompileTimeInitialize(method, aspectInfo);

        _methodToInvoke = method.DeclaringType.GetMethods(BindingFlags.Instance | BindingFlags.Public).Single(info =&amp;gt; info.Name == method.Name &amp;amp;&amp;amp; info != method);

        var rowAttributes = _methodToInvoke.GetCustomAttributes&amp;lt;RowAttribute&amp;gt;();

        CreateDataSource(_methodToInvoke, rowAttributes);
    }

    public override void OnInvoke(MethodInterceptionArgs args)
    {
        var testContext = args.Instance.GetPropertyValue&amp;lt;TestContext&amp;gt;(&amp;quot;TestContext&amp;quot;);

        var parameters = _methodToInvoke.GetParameters();

        var arguments = testContext.GetParameterValues(parameters);

        try
        {
            _methodToInvoke.Invoke(args.Instance, arguments.ToArray());
        }
        catch (TargetInvocationException exc)
        {
            // fix stacktrace
            FieldInfo remoteStackTraceString = typeof(Exception).GetField(&amp;quot;_remoteStackTraceString&amp;quot;, BindingFlags.Instance | BindingFlags.NonPublic); // MS.Net

            remoteStackTraceString.SetValue(exc.InnerException, exc.InnerException.StackTrace + Environment.NewLine);

            throw exc.InnerException;
        }
    }        

    private string CreateDataSource(MethodBase testMethod, IEnumerable&amp;lt;RowAttribute&amp;gt; customeAttribute)
    {
        var projectFileName = PostSharpEnvironment.Current.CurrentProject.EvaluateExpression(&amp;quot;{$MSBuildProjectFullPath}&amp;quot;);
        var projectPath = Path.GetDirectoryName(projectFileName);
        var filename = Path.Combine(projectPath, _methodToInvoke.Name + &amp;quot;.xml&amp;quot;);

        using (var sr = new XmlTextWriter(filename, Encoding.ASCII))
        {
            sr.WriteStartDocument();
            sr.WriteStartElement(&amp;quot;Rows&amp;quot;);
            foreach (var rowAttribute in customeAttribute)
            {
                sr.WriteStartElement(&amp;quot;Row&amp;quot;);

                for (var i = 0; i &amp;lt; rowAttribute.Parameters.Length; i++)
                {
                    sr.WriteStartElement(&amp;quot;value&amp;quot; + i);
                    sr.WriteValue(rowAttribute.Parameters[i]);
                    sr.WriteEndElement();
                }

                sr.WriteEndElement();
            }

            sr.WriteEndElement();
            sr.WriteEndDocument();
        }

        return filename;
    }
}&lt;/pre&gt;&lt;p&gt;There are three main functions:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;CompileTimeInitialize&lt;/strong&gt; – that get called when the code compiles and is responsible to create the XML file – remember we need it before the test runs &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;OnInvoke &lt;/strong&gt;– called when the test runs. Reads the data from the data source and convert the parameters before running the second (parameterized) method &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CreateDataSource&lt;/strong&gt; – you’ve guessed it – this is where we create the xml file – simple and dirty… I use PostSharp’s &lt;em&gt;EvaluateExpression&lt;/em&gt; to find where the project’s file is – remember this bit runs on compile so no tricks using reflection could be used to find the target assembly. &lt;/li&gt;
&lt;/ol&gt;&lt;h3&gt;Utilities&lt;/h3&gt;&lt;p&gt;Simple methods I use in the &lt;em&gt;RowTestAttribute&lt;/em&gt; – just in case you’re wondering:&lt;/p&gt;&lt;pre class="brush: csharp; ruler: true;"&gt;public static class Extensions
{
    public static IEnumerable&amp;lt;T&amp;gt; GetCustomAttributes&amp;lt;T&amp;gt;(this MethodBase method) where T : Attribute
    {
        return (T[])Attribute.GetCustomAttributes(method, typeof(T));
    }

    public static T GetPropertyValue&amp;lt;T&amp;gt;(this object instance, string propertyName)
    {
        var propertyInfo = instance.GetType().GetProperty(propertyName);
        return (T)propertyInfo.GetValue(instance, null);
    }

    public static IEnumerable&amp;lt;object&amp;gt; GetParameterValues(this TestContext context, ParameterInfo[] parameters)
    {
        for (var i = 0; i &amp;lt; parameters.Length; i++)
        {
            var parameterType = parameters[i].ParameterType;
            var inputData = context.DataRow[&amp;quot;value&amp;quot; + i];

            yield return Convert.ChangeType(inputData, parameterType);
        }
    }
}&lt;/pre&gt;&lt;h3&gt;Running the test&lt;/h3&gt;&lt;p&gt;MSTest force me to run the empty parameter-less method. Running the test from the beginning of this post will result in the following:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/-Ey4zS4MkCXI/TmfKzu0E8hI/AAAAAAAAC8k/C3JH7rw_DGE/s1600-h/image%25255B13%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-n2b6e1cAovo/TmfK0scGDlI/AAAAAAAAC8o/quken06jIYQ/image_thumb%25255B9%25255D.png?imgmax=800" width="640" height="462" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;How cool is that – The “test” is actually 4 tests run separately and one of them failed – with a clear error message. And&amp;#160; there’s more clicking on the test we get to see the full error message:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh5.ggpht.com/-yOYbTjl_J0s/TmfK1hwzwmI/AAAAAAAAC8s/Aql2mddYEck/s1600-h/image%25255B12%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-72ZXTJKbMto/TmfK2phG9KI/AAAAAAAAC8w/Sc48yMmcLEY/image_thumb%25255B8%25255D.png?imgmax=800" width="640" height="460" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;In fact I was so impressed with how it works that I put it to us at work despite the fact that it’s not finished yet.&lt;/p&gt;&lt;h3&gt;Is it done?&lt;/h3&gt;&lt;p&gt;Not yet – I would really like to throw away the &lt;em&gt;DeploymentItemAttribute &lt;/em&gt;and if I can get away with it the &lt;em&gt;DataSourceAttribute. &lt;/em&gt;I do use it daily and it feels just wrong.&lt;/p&gt;&lt;p&gt;I’ve tried creating the attributes in runtime – using PostSharp but Visual Studio was not fooled – probably because DTE is used to collect these attribute and not reflection.&lt;/p&gt;&lt;p&gt;By publishing this post I was hoping to achieve two goals:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Help other lost souls such as myself that are forced to use MSTest but wish they had the ability to run &lt;em&gt;RowTests – &lt;/em&gt;BTW you’re welcome&lt;/li&gt;
&lt;li&gt;Get feedback, suggestions and ideas how this nifty idea can be improved&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;And please let me know if you put this code to use – that’s what the comments are for&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Happy coding…&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-7247369068133166260?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=VUYxbJqnzXw:vBndE1GR3FU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=VUYxbJqnzXw:vBndE1GR3FU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=VUYxbJqnzXw:vBndE1GR3FU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=VUYxbJqnzXw:vBndE1GR3FU:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=VUYxbJqnzXw:vBndE1GR3FU:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=VUYxbJqnzXw:vBndE1GR3FU:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=VUYxbJqnzXw:vBndE1GR3FU:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=VUYxbJqnzXw:vBndE1GR3FU:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/VUYxbJqnzXw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/VUYxbJqnzXw/enabling-parameterized-tests-in-mstest.html</link><author>noreply@blogger.com (Dror Helper)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh4.ggpht.com/-n2b6e1cAovo/TmfK0scGDlI/AAAAAAAAC8o/quken06jIYQ/s72-c/image_thumb%25255B9%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/09/enabling-parameterized-tests-in-mstest.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-3032238603138494818</guid><pubDate>Wed, 17 Aug 2011 14:58:00 +0000</pubDate><atom:updated>2011-08-17T17:58:22.377+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Thoughts</category><title>9 years ago…</title><description>&lt;p&gt;August 2002 I’ve started&amp;#160; my first “real” programming job, I was an intern at Intel working side by side with intelligent and talented engineers on a performance monitoring tool for Linux. A lot has happened since, I switched a few jobs, sometimes I worked for big enterprise and sometime for a small startup until I ended up on my current position in a company that is neither (or both). &lt;/p&gt;  &lt;p&gt;I wrote software that did video processing, ecommerce and helped people write better unit tests (I hope) mostly (but not only) in C++ and .NET languages where I felt most comfortable.&lt;/p&gt;  &lt;div&gt;&lt;a href="http://www.flickr.com/photos/namovaryar/406095231/" target="_blank"&gt;&lt;img title="Motivational Poster - Reflection by Raymond Brettschneider, on Flickr" border="0" alt="Motivational Poster - Reflection by Raymond Brettschneider, on Flickr" src="http://farm1.static.flickr.com/131/406095231_5d802e577e.jpg" /&gt;&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://creativecommons.org/licenses/by-nc-nd/2.0/" target="_blank"&gt;&lt;img title="Creative Commons Attribution-Noncommercial-No Derivative Works 2.0 Generic License" border="0" alt="Creative Commons Attribution-Noncommercial-No Derivative Works 2.0 Generic License" align="left" src="http://i.creativecommons.org/l/by-nc-nd/2.0/80x15.png" /&gt;&lt;/a&gt;&amp;#160; by &lt;a href="http://www.flickr.com/people/namovaryar/" target="_blank"&gt; Raymond Brettschneider&lt;/a&gt;&lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;In the last nine years I learnt quite a lot in the since I wrote my first &lt;em&gt;void main - &lt;/em&gt;on my first job I leant how to write code, on my second job I learnt how to write code fast but only on my previous job did I learn how to write code well…&lt;/p&gt;  &lt;p&gt;In every job and every project I had a the good fortune to find guru that could teach me something and with each lesson I improved not only professionally but also as an individual.&lt;/p&gt;  &lt;p&gt;All in all it’s been fun ride, it’s not over - I’m just stopped for a minuet too look back and take a breath.&lt;/p&gt;  &lt;p&gt;I can’t wait to see what would happen in the next nine years.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-3032238603138494818?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=pdurYMC09_c:3Z_UV6CTUtk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=pdurYMC09_c:3Z_UV6CTUtk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=pdurYMC09_c:3Z_UV6CTUtk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=pdurYMC09_c:3Z_UV6CTUtk:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=pdurYMC09_c:3Z_UV6CTUtk:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=pdurYMC09_c:3Z_UV6CTUtk:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=pdurYMC09_c:3Z_UV6CTUtk:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=pdurYMC09_c:3Z_UV6CTUtk:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/pdurYMC09_c" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/pdurYMC09_c/9-years-ago.html</link><author>noreply@blogger.com (Dror Helper)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm1.static.flickr.com/131/406095231_5d802e577e_t.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/08/9-years-ago.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-6300727115823719965</guid><pubDate>Mon, 01 Aug 2011 07:15:00 +0000</pubDate><atom:updated>2011-08-01T10:22:56.710+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Typemock</category><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">Unit tests</category><category domain="http://www.blogger.com/atom/ns#">Tips and Tricks</category><category domain="http://www.blogger.com/atom/ns#">C#</category><category domain="http://www.blogger.com/atom/ns#">NUnit</category><title>Supercharge Isolate.Verify</title><description>&lt;p&gt;At work we use &lt;a href="http://www.typemock.com/isolator-product-page" target="_blank"&gt;Typemock Isolator&lt;/a&gt; for all of our Isolation/Mocking needs. Lately I’ve noticed that my co-workers do not like to use verify. One of the reasons they prefer not to use it is that sometime Verify error messages leave much to be desired. There are a few simple tricks that helps &lt;a href="http://www.typemock.com/isolator-product-page" target="_blank"&gt;Isolator&lt;/a&gt; help you when using verify and I’m going to show them right here in this very blog post.&lt;/p&gt;&lt;h3&gt;What is this verify you talk about?&lt;/h3&gt;&lt;p&gt;Any Isolation framework worth mentioning can do the following three features:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Create fake object (a.k.a mock/stub/test dummy – you name it) &lt;/li&gt;
&lt;li&gt;Set expectations on fake objects &lt;/li&gt;
&lt;li&gt;Verify method was called in fake object &lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Verify is what differentiate mock from stub. Without getting into too many definitions a mock object is a fake object that can assert that methods were called inside of it and even check if it was called with specific arguments.&lt;/p&gt;&lt;h3&gt;So what’s the problem with verify?&lt;/h3&gt;&lt;p&gt;Verify is a powerful tool and should be used with care. Checking that method A called method B is not its purpose. You don’t want your tests failing just because you did a simple refactoring. Instead Verify should be used when the end result of the test is a method call and not a state, for example use it in a test that an email is sent to the client after a successful operation.&lt;/p&gt;&lt;p&gt;Oddly enough – that’s not the reason that developers tend not to like using it. The real reason is that unlike Assert that provides a clear and understandable message when fails some of the times Verify message is not clear enough. Good errors are crucial when test fails – it saves time by helping the developer understand the issue without needing to debug the code which equals faster development time.&lt;/p&gt;&lt;p&gt;And so we would like to improve the error message on the failing test to help understand why the test failed a few days/weeks/months after it was written.&lt;/p&gt;&lt;h3&gt;Improving Verify error messages&lt;/h3&gt;&lt;p&gt;Luckily for us the good people of &lt;a href="http://www.typemock.com" target="_blank"&gt;Typemock&lt;/a&gt; have already thought about this issue as long as enough information is provided.&lt;/p&gt;&lt;pre class="brush: csharp;"&gt;[Test]
public void VerifyStringParam()
{
    var cut = Isolate.Fake.Instance&amp;lt;ClassUnderTest&amp;gt;();

    cut.SomeMethod(&amp;quot;this is the wrong string&amp;quot;);

    Isolate.Verify.WasCalledWithExactArguments(() =&amp;gt; cut.SomeMethod(&amp;quot;this is the right string&amp;quot;));
}&lt;/pre&gt;&lt;p&gt;The code is quite simple even if you’re not familiar with Isolator – in fact it’s too simple, I cannot think of a good reason to write this code other than to show my point.&lt;/p&gt;&lt;p&gt;First we create a fake object then we call a method on it and finally we check that it was called with a different variable.&lt;/p&gt;&lt;p&gt;We got the following error:&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;a href="http://lh4.ggpht.com/-kwek30If8Do/TjZSh2_CxDI/AAAAAAAAC7k/B9sgoYF8tTM/s1600-h/image%25255B22%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh5.ggpht.com/-sbKTbpAEyiY/TjZSisWYrAI/AAAAAAAAC7o/EU28cJiTIGk/image_thumb%25255B12%25255D.png?imgmax=800" width="644" height="322" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The error is exactly what I need – it tells me what went wrong and shows the first offending character in the sting. But what happens if I use a more complex parameter:&lt;/p&gt;&lt;pre class="brush: csharp;"&gt;[Test]
public void VerifyComplexParam()
{
    var cut = Isolate.Fake.Instance&amp;lt;ClassUnderTest&amp;gt;();

    var myClass = new MyClass
    {
        Id = &amp;quot;wrongId&amp;quot;,
        Data = 11
    };

    cut.SomeMethod(myClass);

    var expected = new MyClass { Id = &amp;quot;Id&amp;quot;, Data = 5 };
    Isolate.Verify.WasCalledWithExactArguments(() =&amp;gt; cut.SomeMethod(expected));
}&lt;/pre&gt;&lt;p&gt;Here I use a more elaborate (yet useless) class as a parameter, and again I “accidently” call the method with the wrong parameter. Running the test would provide the following failure message:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh4.ggpht.com/-nTWomNnjG_0/TjZSjhgjdXI/AAAAAAAAC7s/-_LoaaMV7FY/s1600-h/image%25255B23%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh4.ggpht.com/-LjLQZyg3EAY/TjZSkbiYDII/AAAAAAAAC7w/VJVipIGnsVk/image_thumb%25255B13%25255D.png?imgmax=800" width="583" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;SO what happened? the test failed but Isolator in his great wisdom offers us to implement &lt;em&gt;Equals&lt;/em&gt; because 9 out of 10 times I don’t want to compare the parameters by reference just by their inside value. By implementing equality methods we can tell Isolator if the inside of the class is the same – after implementing &lt;em&gt;Equals&lt;/em&gt; I get the following error message:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/-CLUkOfYpgco/TjZSlMLbN0I/AAAAAAAAC70/cLlvXf-bOGk/s1600-h/image%25255B24%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-U5ouCN-SGkQ/TjZSl42E57I/AAAAAAAAC74/znDGo-BNlAk/image_thumb%25255B14%25255D.png?imgmax=800" width="644" height="451" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;How cool is that! Isolator has used equals and when it failed assumed that one (or more) of the properties of the class are to blame and so it shows all of the properties in &lt;em&gt;MyClass&lt;/em&gt; that are not equal.&lt;/p&gt;&lt;p&gt;But what happens if we pass a really complex class – one that contains another class?&lt;/p&gt;&lt;pre class="brush: csharp;"&gt;[Test]
public void VerifyMoreComplexParam()
{
    var cut = Isolate.Fake.Instance&amp;lt;ClassUnderTest&amp;gt;();

    var complexClass = new ComplexClass
    {
         InnerClass = new MyClass { Id = &amp;quot;id&amp;quot;, Data = 10 }
    };

    cut.SomeMethod(complexClass);

    var expected = new ComplexClass
    {
         InnerClass = new MyClass { Id = &amp;quot;Id&amp;quot;, Data = 5 }
    };

    Isolate.Verify.WasCalledWithExactArguments(() =&amp;gt; cut.SomeMethod(expected));
}&lt;/pre&gt;&lt;p&gt;We get this error message:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh4.ggpht.com/-NLalv3vpbVY/TjZSmvTDXAI/AAAAAAAAC78/DNMNODueb_g/s1600-h/image%25255B25%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-OMkfXCymmUc/TjZSnXKSAwI/AAAAAAAAC8A/sHlrC9O84pI/image_thumb%25255B15%25255D.png?imgmax=800" width="644" height="377" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Isolator has found that the problem was the parameter (duh) but he would not tell me what is wrong with it – I guess there is no option but to debug – wrong!&lt;/p&gt;&lt;p&gt;By overriding &lt;em&gt;ToString&lt;/em&gt; we can improve the error message into this:&lt;/p&gt;&lt;p&gt;&lt;a href="http://lh6.ggpht.com/-uLQKpCG_hEo/TjZSoW4WawI/AAAAAAAAC8E/oR82to7P-lQ/s1600-h/image%25255B26%25255D.png"&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-gdJmIS__NJc/TjZSpGCnE2I/AAAAAAAAC8I/QUrao8cg5YA/image_thumb%25255B16%25255D.png?imgmax=800" width="644" height="377" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Even if Isolator won’t guess what is different between the classes at least he shows the string representation helping me discover for myself why the test failed.&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;You might have noticed that when using these simple tricks you can discover instantly why the test failed – without using debugger or even glancing at the source code – in fact throughout this post I never once showed the code for the class under test.&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Happy coding…&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-6300727115823719965?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=b-1dQOXjesE:if1NA-2w1fU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=b-1dQOXjesE:if1NA-2w1fU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=b-1dQOXjesE:if1NA-2w1fU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=b-1dQOXjesE:if1NA-2w1fU:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=b-1dQOXjesE:if1NA-2w1fU:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=b-1dQOXjesE:if1NA-2w1fU:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=b-1dQOXjesE:if1NA-2w1fU:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=b-1dQOXjesE:if1NA-2w1fU:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/b-1dQOXjesE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/b-1dQOXjesE/supercharge-isolateverify.html</link><author>noreply@blogger.com (Dror Helper)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://lh5.ggpht.com/-sbKTbpAEyiY/TjZSisWYrAI/AAAAAAAAC7o/EU28cJiTIGk/s72-c/image_thumb%25255B12%25255D.png?imgmax=800" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/08/supercharge-isolateverify.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-5814836156817791045</guid><pubDate>Sat, 23 Jul 2011 09:31:00 +0000</pubDate><atom:updated>2011-07-23T12:31:01.510+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">Unit tests</category><category domain="http://www.blogger.com/atom/ns#">MSTest</category><category domain="http://www.blogger.com/atom/ns#">NUnit</category><category domain="http://www.blogger.com/atom/ns#">TDD</category><title>Three Day TDD .NET Course (Israel)</title><description>&lt;p&gt;A new practitioner of TDD and unit tests has much to learn: &lt;/p&gt;  &lt;p&gt;how to what are acceptance tests?&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt; how to write tests that won’t break on every trivial change?&lt;/li&gt;    &lt;li&gt;what mock objects and why should you care?&lt;/li&gt;    &lt;li&gt;How do I test my product code?&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;So if you’re looking for a place to learn all those look no further – &lt;a href="http://liorfriedman.com" target="_blank"&gt;Lior Friedman&lt;/a&gt; has opened a course on all things unit testing and TDD for .NET developers.&lt;/p&gt;  &lt;p&gt;This three day course will take place at the 14th of August where students will learn how to write unit tests not only for simple “hello world” examples but also for&amp;#160; complex real world systems – and everything in between.&lt;/p&gt;  &lt;p&gt;The course &lt;a href="http://www.liorfriedman.com/training/tdd/tdd-net" target="_blank"&gt;outline and can be found here&lt;/a&gt; and Registration is &lt;a href="http://www.liorfriedman.com/registrationform?layout=blog" target="_blank"&gt;open&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;If you want to learn more just head to &lt;a href="http://www.liorfriedman.com" target="_blank"&gt;Lior’s&lt;/a&gt; site and check it out.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-5814836156817791045?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=sal9rqZglUo:jev9tEi1OX8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=sal9rqZglUo:jev9tEi1OX8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=sal9rqZglUo:jev9tEi1OX8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=sal9rqZglUo:jev9tEi1OX8:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=sal9rqZglUo:jev9tEi1OX8:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=sal9rqZglUo:jev9tEi1OX8:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=sal9rqZglUo:jev9tEi1OX8:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=sal9rqZglUo:jev9tEi1OX8:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/sal9rqZglUo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/sal9rqZglUo/three-day-tdd-net-course-israel.html</link><author>noreply@blogger.com (Dror Helper)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/07/three-day-tdd-net-course-israel.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-6769919665376201021</guid><pubDate>Sun, 17 Jul 2011 11:24:00 +0000</pubDate><atom:updated>2011-07-17T14:32:11.764+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Unit tests</category><category domain="http://www.blogger.com/atom/ns#">C#</category><category domain="http://www.blogger.com/atom/ns#">NUnit</category><category domain="http://www.blogger.com/atom/ns#">TDD</category><title>How to return default(Type) in runtime – a TDD example in four unit tests</title><description>&lt;p&gt;I’ve found this question while going over my old &lt;a href="http://stackoverflow.com" target="_blank"&gt;StackOverflow&lt;/a&gt; answers:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;I'm using reflection to loop through a Type's properties and set certain types to their default. Now, I could do a switch on the type and set the default(Type) explicitly, but I'd rather do it in one line. Is there a programmatic equivalent of default?&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;I encourage you to read till the end before &lt;a href="http://stackoverflow.com/questions/325426/c-programmatic-equivalent-of-defaulttype/353073#353073" target="_blank"&gt;checking my answer&lt;/a&gt; – because I want to show you how this task can be solved using TDD (&lt;a href="http://en.wikipedia.org/wiki/Test-driven_development" target="_blank"&gt;Test Driven Design&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;&lt;img alt="File:Test-driven development.PNG" src="http://upload.wikimedia.org/wikipedia/en/9/9c/Test-driven_development.PNG" width="683" height="490" /&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;[From &lt;/em&gt;&lt;a href="http://en.wikipedia.org/wiki/Test-driven_development" target="_blank"&gt;&lt;em&gt;Wikipedia&lt;/em&gt;&lt;/a&gt;&lt;em&gt;]&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;&lt;h3&gt;Test #1 – handle null input&lt;/h3&gt;&lt;p&gt;Let’s write the first test – when null is passed return null:&lt;/p&gt;&lt;pre class="brush: csharp;"&gt;[Test]
public void GetDefault_PassNull_ReturnNull()
{
    var result = DefaultCreator.GetDefault(null);

    Assert.That(result, Is.Null);
}&lt;/pre&gt;&lt;p&gt;Now all we need is to make the test pass and so implementing this requirement is as simple as can be:&lt;/p&gt;&lt;pre class="brush: csharp; highlight: [5]"&gt;public class DefaultCreator
{
    public static object GetDefault(Type type);
    {
        return null;
    }
}&lt;/pre&gt;&lt;p&gt;Although this seems like cheating this is the way to create the design piece but piece, instead of creating it all upfront I hope that things would get clearer in the process just keep in mind that the worse case scenario is that we have a test that checks what happens if null is passed.&lt;/p&gt;&lt;h3&gt;Test #2 – reference types&lt;/h3&gt;&lt;p&gt;Next test - if T is an object default(T) will return &lt;em&gt;null:&lt;/em&gt;&lt;/p&gt;&lt;pre class="brush: csharp;"&gt;[Test]
public void GetDefault_PassObject_ReturnNull()
{
    var result = DefaultCreator.GetDefault(typeof(object));

    Assert.That(result, Is.Null);
}&lt;/pre&gt;&lt;p&gt;Running the test shows a cool feature of test driven design – the test passes! and so right now we have a class that satisfies two out of three of our requirements.&lt;/p&gt;&lt;h3&gt;Test #3 – primitives&lt;/h3&gt;&lt;p&gt;All we need to implement now is how to behave when a value type is passed – and so we write another test:&lt;/p&gt;&lt;pre class="brush: csharp;"&gt;[Test]
public void GetDefault_PassInteger_Return0() 
{
    var result = DefaultCreator.GetDefault(typeof(int));

    Assert.That(result, Is.EqualTo(0));
}&lt;/pre&gt;&lt;p&gt;And write the simplest solution that makes it pass:&lt;/p&gt;&lt;pre class="brush: csharp; highlight: [5]"&gt;public class DefaultCreator
{
    public static object GetDefault(Type type)
    {
        if (type == typeof(int)) 
        {
            return 0;
        }

        return null;
    }
}&lt;/pre&gt;&lt;p&gt;So far so good but we’re not done yet – after writing a few more tests for double, float and long refactoring brought this solution:&lt;/p&gt;&lt;pre class="brush: csharp; highlight: [5]"&gt;public class DefaultCreator
{
    public static object GetDefault(Type type)
    {
        if (type.IsPrimitive) 
        {
            return 0;
        }

        return null;
    }
}&lt;/pre&gt;&lt;h3&gt;Test #4 – Structs&lt;/h3&gt;&lt;p&gt;Still with me good – what about a complex value type :&lt;/p&gt;&lt;pre class="brush: csharp;"&gt;[Test]
public void GetDefault_PassStruct_ReturnEmptyStruct() 
{
    var result = DefaultCreator.GetDefault(typeof(MyStruct));

    Assert.That(result, Is.TypeOf&amp;lt;MyStruct&amp;gt;());
}&lt;/pre&gt;&lt;p&gt;Now that we have a failing test – we can add functionality to fix it:&lt;/p&gt;&lt;pre class="brush: csharp; highlight: [5];"&gt;public class DefaultCreator
{
    public static object GetDefault(Type type)
    {
        if (type.IsValueType) 
        {
            return Activator.CreateInstance(type);
        }

        return null;
    }
}&lt;/pre&gt;&lt;p&gt;Run all of the tests and that’s it – we have a class that mimics &lt;em&gt;default(T)&lt;/em&gt; at run-time one step at a time.&lt;/p&gt;&lt;h3&gt;The end&lt;/h3&gt;&lt;p&gt;Of course I could have created this class without unit tests but I wanted to show a simple (but not too simple) example that shows how to use unit tests as a design tool.&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;Happy coding…&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-6769919665376201021?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=lDWvNsIMFjU:A_BiC1hBuxU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=lDWvNsIMFjU:A_BiC1hBuxU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=lDWvNsIMFjU:A_BiC1hBuxU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=lDWvNsIMFjU:A_BiC1hBuxU:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=lDWvNsIMFjU:A_BiC1hBuxU:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=lDWvNsIMFjU:A_BiC1hBuxU:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=lDWvNsIMFjU:A_BiC1hBuxU:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=lDWvNsIMFjU:A_BiC1hBuxU:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/lDWvNsIMFjU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/lDWvNsIMFjU/how-to-return-defaulttype-in-runtime.html</link><author>noreply@blogger.com (Dror Helper)</author><thr:total>1</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/07/how-to-return-defaulttype-in-runtime.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-4245489381641284623</guid><pubDate>Tue, 28 Jun 2011 18:22:00 +0000</pubDate><atom:updated>2011-06-28T21:22:11.953+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">Multi-threading</category><category domain="http://www.blogger.com/atom/ns#">C#</category><title>RTFM–the tale of ReaderWriterLockSlim</title><description>&lt;p&gt;The .NET BCL (Base Class Library) is readable, easy to understand and not less important documented. This is a story on where a simple reading of documentation could have saved us from a minor bug…&lt;/p&gt;  &lt;p&gt;If you’ve been using .NET you might be familiar with the &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlock.aspx" target="_blank"&gt;ReaderWriterLock&lt;/a&gt;&lt;em&gt;&lt;/em&gt; essentially a lock that enable multiple readers or one writer synchronization. The only problem is that the good old ReaderWriterLock had a few drawbacks – and so the good people of Microsoft have create a new and improved &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx" target="_blank"&gt;ReaderWriterLockSlim&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;A developer at my team had a simple task – make sure that there are not race conditions when reading and writing a big chunk of the project’s shared data and for the task he choose the trusty ReaderWriterLockSlim. He had two methods to access the data one for reading and one for writing – so far so good.&lt;/p&gt;  &lt;p&gt;Fast forward a year and the team has a strange issue – it seems that only one thread can access the data – even if it’s only reading it. After a few debates my co-worker found the root of the problem – whenever a read was required instead of using &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.enterreadlock.aspx" target="_blank"&gt;EnterReadLock&lt;/a&gt; – which is used to, well acquire read permissions the original developer had used &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.enterupgradeablereadlock.aspx" target="_blank"&gt;EnterUpgradeableReadLock&lt;/a&gt;. Perhaps because it’s enable using a write request from within the read lock – I have no idea since that developer has since left the team.&lt;/p&gt;  &lt;p&gt;And according to &lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx" target="_blank"&gt;MSDN&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Regardless of recursion policy, only one thread can be in write mode at any time. When a thread is in write mode, no other thread can enter the lock in any mode. Only one thread can be in upgradeable mode at any time. Any number of threads can be in read mode, and there can be one thread in upgradeable mode while other threads are in read mode.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;strong&gt;Duh!&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The problem was not that the original developer didn’t know that using an upgradable lock essentially creates a state where all the locks a mutually exclusive – just like using simple &lt;a href="http://msdn.microsoft.com/en-us/library/c5kehkcz.aspx" target="_blank"&gt;lock&lt;/a&gt; only without the performance benefits. The problem is that all of the team saw the code at one point or the other and not one of use thought of reading the page on MSDN that has the paragraph quoted above!&lt;/p&gt;  &lt;p&gt;We had a simple policy of if it works – don’t break it and would have probably continue to use ReaderWriterLockSlim the wrong way unless a different issue caused us to take notice.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Happy coding…&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-4245489381641284623?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=dUQ2iPGjxew:OOKKX6rTHJ0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=dUQ2iPGjxew:OOKKX6rTHJ0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=dUQ2iPGjxew:OOKKX6rTHJ0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=dUQ2iPGjxew:OOKKX6rTHJ0:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=dUQ2iPGjxew:OOKKX6rTHJ0:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=dUQ2iPGjxew:OOKKX6rTHJ0:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=dUQ2iPGjxew:OOKKX6rTHJ0:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=dUQ2iPGjxew:OOKKX6rTHJ0:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/dUQ2iPGjxew" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/dUQ2iPGjxew/rtfmthe-tale-of-readerwriterlockslim.html</link><author>noreply@blogger.com (Dror Helper)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/06/rtfmthe-tale-of-readerwriterlockslim.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-5586038867576509775</guid><pubDate>Tue, 07 Jun 2011 08:56:00 +0000</pubDate><atom:updated>2011-06-07T12:00:37.275+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">.NET</category><category domain="http://www.blogger.com/atom/ns#">C#</category><title>Using null-coalescing to find item in multiple collections</title><description>&lt;p&gt;A co-worker showed me this:&lt;/p&gt;&lt;pre class="brush: csharp; ruler: true;"&gt;var result = collection1.GetObjectByAtSpecialLocation(location) ??
        collection1.GetObjectByAtLocation(parent, location) ??
        collection2.GetObjectByAtSpecialLocation(location) ??
        collection2.GetObjectByAtLocation(parent, location);&lt;/pre&gt;&lt;p&gt;I’m still trying to decide whether it’s a good practice and if it’s readable or not…&lt;/p&gt;&lt;p&gt;In case you’re not familiar with &lt;em&gt;?? operator&lt;/em&gt; a.k.a &lt;a href="http://msdn.microsoft.com/en-us/library/ms173224.aspx" target="_blank"&gt;null-coalescing operator&lt;/a&gt; it’s basically returns a default value if the left side is null so the following line means return empty string if &lt;em&gt;name&lt;/em&gt; is null:&lt;/p&gt;&lt;pre class="brush: csharp; ruler: true;"&gt;string result = name ?? string.Empty;&lt;/pre&gt;&lt;p&gt;And so the code at the beginning of the post can also be written as:&lt;/p&gt;&lt;pre class="brush: csharp; ruler: true;"&gt;var result = collection1.GetObjectByAtSpecialLocation(location);
if(result == null) 
{
    result = collection1.GetObjectByAtLocation(parent, location);
} 

if(result == null) 
{
    result = collection2.GetObjectByAtSpecialLocation(location);
} 

if(result == null) 
{
    result = collection2.GetObjectByAtLocation(parent, location);
}&lt;/pre&gt;&lt;p&gt;Although most developers would agree that it’s easy enough to understand it’s far from being a good piece of code.&lt;/p&gt;&lt;p&gt;I also think that the reason that there was a need to check if an item exist over two different collections in two different ways indicates a design flow – but since we’re not living in a perfect world right now it’s impossible to merge those two collections and regardless of effort there was a good reason that they are different in the first place so I’m have to find an item in four different ways.&lt;/p&gt;&lt;p&gt;At first when I saw the code I cried abuse – it seemed to me that there bound to be a better way to do so without nesting four calls but after a while this solution seemed almost elegant.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;What do you think?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-5586038867576509775?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=_CQC9lphV2U:8_XNDcKB2OE:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=_CQC9lphV2U:8_XNDcKB2OE:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=_CQC9lphV2U:8_XNDcKB2OE:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=_CQC9lphV2U:8_XNDcKB2OE:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=_CQC9lphV2U:8_XNDcKB2OE:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=_CQC9lphV2U:8_XNDcKB2OE:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=_CQC9lphV2U:8_XNDcKB2OE:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=_CQC9lphV2U:8_XNDcKB2OE:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/_CQC9lphV2U" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/_CQC9lphV2U/using-null-coalescing-to-find-item-in.html</link><author>noreply@blogger.com (Dror Helper)</author><thr:total>2</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/06/using-null-coalescing-to-find-item-in.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-466407628242725032</guid><pubDate>Fri, 20 May 2011 07:57:00 +0000</pubDate><atom:updated>2012-02-13T14:08:17.767+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">CI</category><category domain="http://www.blogger.com/atom/ns#">Agile</category><title>The 7 levels of continuous integration</title><description>I’ve noticed that when other developers talk about “continuous integration” they do not always mean the same thing. &lt;br /&gt;
The following is an outline of the seven stages of continuous integration based solely on my own experience:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;No Server, no automation - no problems&lt;/li&gt;
&lt;li&gt;Have nightly build that run each day – at least we know that the project compiles&lt;/li&gt;
&lt;li&gt;Started writing “unit” tests – now running as part of the nightly build&lt;/li&gt;
&lt;li&gt;Created a build that runs on each commits – who broke the build?!&lt;/li&gt;
&lt;li&gt;Added static code analysis and style checking to the build&lt;/li&gt;
&lt;li&gt;Server Build, deploy &amp;amp; run the tests on several environments also used to deploy on testing (and production) environments&lt;/li&gt;
&lt;li&gt;Everything is automated – Even Gui tests runs automatically on the latest code, you even got as far as testing the installer. Code is analyzed and results are sent by email. Nothing is done manually unless it is done only once…&lt;/li&gt;
&lt;/ol&gt;
These are &lt;u&gt;my&lt;/u&gt;&amp;nbsp;stages as I experienced them in several jobs – what are yours?&lt;br /&gt;
&lt;br /&gt;
Happy coding…&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-466407628242725032?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=vH3aVo0FxHQ:bOsvdNLdr6E:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=vH3aVo0FxHQ:bOsvdNLdr6E:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=vH3aVo0FxHQ:bOsvdNLdr6E:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=vH3aVo0FxHQ:bOsvdNLdr6E:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=vH3aVo0FxHQ:bOsvdNLdr6E:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=vH3aVo0FxHQ:bOsvdNLdr6E:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=vH3aVo0FxHQ:bOsvdNLdr6E:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=vH3aVo0FxHQ:bOsvdNLdr6E:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/vH3aVo0FxHQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/vH3aVo0FxHQ/7-levels-of-continuous-integration.html</link><author>noreply@blogger.com (Dror Helper)</author><thr:total>4</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/05/7-levels-of-continuous-integration.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-6077446245805898357</guid><pubDate>Tue, 17 May 2011 10:34:00 +0000</pubDate><atom:updated>2011-05-17T14:00:31.405+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Agile</category><category domain="http://www.blogger.com/atom/ns#">Conference</category><title>QA and Development in Agile 2011</title><description>&lt;p&gt;This Thursday (May19th) I’ll take part in a Panel at the “&lt;a href="http://www.meda-conferences.com/index.php?option=com_mtree&amp;amp;task=viewlink&amp;amp;link_id=85&amp;amp;Itemid=14" target="_blank"&gt;QA and development Agile&lt;/a&gt;” conference.&lt;/p&gt;&lt;p&gt;I’ve been asked to talk about unit testing, TDD, SCRUM and anything else agile – topics that you should be familiar with if you’ve been reading this blog.&lt;/p&gt;&lt;p&gt;There would be developer and QA tracks with very interesting sessions two of which by good friends of mine: &lt;a href="http://www.gilzilberfeld.com/" target="_blank"&gt;Gil Zilberfeld&lt;/a&gt; and &lt;a href="http://imistaken.blogspot.com/" target="_blank"&gt;Lior Friedman&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&amp;#160;&lt;/p&gt;&lt;p&gt;I’ll be there all day long so if you’re there, come and say hi.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-6077446245805898357?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=p6wXTDHsf-M:5JafM0NYGJA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=p6wXTDHsf-M:5JafM0NYGJA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=p6wXTDHsf-M:5JafM0NYGJA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=p6wXTDHsf-M:5JafM0NYGJA:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=p6wXTDHsf-M:5JafM0NYGJA:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=p6wXTDHsf-M:5JafM0NYGJA:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=p6wXTDHsf-M:5JafM0NYGJA:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=p6wXTDHsf-M:5JafM0NYGJA:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/p6wXTDHsf-M" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/p6wXTDHsf-M/qa-and-development-in-agile-2011.html</link><author>noreply@blogger.com (Dror Helper)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/05/qa-and-development-in-agile-2011.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-896350910545389425</guid><pubDate>Sat, 07 May 2011 18:45:00 +0000</pubDate><atom:updated>2011-05-07T21:45:28.171+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Productivity</category><category domain="http://www.blogger.com/atom/ns#">Unit tests</category><category domain="http://www.blogger.com/atom/ns#">Thoughts</category><category domain="http://www.blogger.com/atom/ns#">TDD</category><title>Don’t fix invisible bugs</title><description>&lt;p&gt;Last week I conducted yet another code review. While looking at the code I’ve noticed a lot of lines similar to &lt;em&gt;If(x != null)&lt;/em&gt; and &lt;em&gt;if(y &amp;lt; 0) &lt;/em&gt;all over the code. These lines were not “business related” but were put in the code to make sure that proper inputs were given to the methods. Usually this is a good practice but further review showed that some of the code was checking for conditions that could not possibly happen. it meant that a lot of effort was given to creating code that checks for things that would never happen.&lt;/p&gt;  &lt;p&gt;I’ve asked the developer why he written that code and he answered that it was put there to make sure that he handles a certain scenario properly. I’ve asked him when such conditions would happen and after thought he answered – never!&lt;/p&gt;  &lt;p&gt;In that case - I said – please remove this code. At first he insisted that the code should stay there because: You can never know and because it was already written. I didn’t even dignify the 2nd remark with an answer but instead told him to write a unit test that shows that the code was important and could save us from disaster. After a few tries he was convinced that there is no way to cause his methods to fail and that this code is not needed.&lt;/p&gt;  &lt;p&gt;This is not a new thing, when I see a fellow developer over thinking some method or class I suggest that first he write a test. I try to make sure that all of teammates practice TDD (Test Driven Development) along other benefits writing the tests before hand guarantee that every lines written is needed. But even if you do not writes your tests first and you find yourself asking whether you need to write “that code” try writing a test before to show that there a problem there that need solving…&lt;/p&gt;  &lt;p&gt;It seems that code coverage goes both ways – it’s important to make sure that your code is well tested but if there is a piece of code that is not tested it could be because it would never run – and as such can be removed.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-896350910545389425?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=a7XtDnu05vg:ERAvdiO3hFM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=a7XtDnu05vg:ERAvdiO3hFM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=a7XtDnu05vg:ERAvdiO3hFM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=a7XtDnu05vg:ERAvdiO3hFM:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=a7XtDnu05vg:ERAvdiO3hFM:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=a7XtDnu05vg:ERAvdiO3hFM:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=a7XtDnu05vg:ERAvdiO3hFM:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=a7XtDnu05vg:ERAvdiO3hFM:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/a7XtDnu05vg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/a7XtDnu05vg/dont-fix-invisible-bugs.html</link><author>noreply@blogger.com (Dror Helper)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/05/dont-fix-invisible-bugs.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-5349895509163832258</guid><pubDate>Thu, 21 Apr 2011 08:10:00 +0000</pubDate><atom:updated>2011-04-21T11:10:46.816+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Thoughts</category><title>3 signs that you’ve been coding too much</title><description>&lt;p&gt;Could there be such thing as too much coding? From time to time I get reminded that there is more to the world than Visual Studio and highlighted text. Below are real stories that happened to me (sometimes more than once), causing me to ask myself – should I take a break?&lt;/p&gt;  &lt;h3&gt;Run in debug mode emailing&lt;/h3&gt;  &lt;p&gt;You’ve just tried sending an email by pressing F5    &lt;br /&gt;When a co-worker told me that he’s just used the “Run&amp;quot; from debugger” button to send an Email it made me laugh. only to do the same thing after a few months…&lt;/p&gt;  &lt;p&gt;I guess my brain was wired to press F5 to “execute” – stupid brain.&lt;/p&gt;  &lt;h3&gt;Compiling word documents&lt;/h3&gt;  &lt;p&gt;In my pre-Resharper days I was used to compiling my code every few lines as a basic “sanity check” it was for my code what quick save is for games. it became such a second nature that a few times after I’ve finished writing a paragraph in word I’ve tried to compile it by pressing ctrl + shift + B.&lt;/p&gt;  &lt;h3&gt;Proper coding standards in text files&lt;/h3&gt;  &lt;p&gt;This one is new. I get to write comments to document my code. a few days ago after writing a line of documentation I’ve noticed that I’ve used Pascal case TheEntireTimeAndTheWierdThingIsThatIWasAbleToReadItAtLeastOnceBeforeNoticing.&lt;/p&gt;  &lt;h3&gt;Conclusion&lt;/h3&gt;  &lt;p&gt;Sadly these is not a fictionally post – it happened to me and might happen to you. And I know that I’m not the only one – so if you have stories of strange things that happened to you or your “friend” – please leave a comment.&lt;/p&gt;  &lt;div&gt;&lt;a href="http://www.flickr.com/photos/pedromourapinheiro/2366871743/" target="_blank"&gt;&lt;img title="doh by Pedro Moura Pinheiro, on Flickr" border="0" alt="doh by Pedro Moura Pinheiro, on Flickr" src="http://farm4.static.flickr.com/3104/2366871743_f0f902551e_m.jpg" /&gt;&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://creativecommons.org/licenses/by-nc-sa/2.0/" target="_blank"&gt;&lt;img title="Creative Commons Attribution-Noncommercial-Share Alike 2.0 Generic License" border="0" alt="Creative Commons Attribution-Noncommercial-Share Alike 2.0 Generic License" align="left" src="http://i.creativecommons.org/l/by-nc-sa/2.0/80x15.png" /&gt;&lt;/a&gt;&amp;#160; by &lt;a href="http://www.flickr.com/people/pedromourapinheiro/" target="_blank"&gt;Pedro Moura Pinheiro&lt;/a&gt;&lt;/div&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Happy Coding…&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-5349895509163832258?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=PA0OdbUjk4E:Oe1_gZHkdR8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=PA0OdbUjk4E:Oe1_gZHkdR8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=PA0OdbUjk4E:Oe1_gZHkdR8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=PA0OdbUjk4E:Oe1_gZHkdR8:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=PA0OdbUjk4E:Oe1_gZHkdR8:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=PA0OdbUjk4E:Oe1_gZHkdR8:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=PA0OdbUjk4E:Oe1_gZHkdR8:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=PA0OdbUjk4E:Oe1_gZHkdR8:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/PA0OdbUjk4E" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/PA0OdbUjk4E/3-signs-that-youve-been-coding-too-much.html</link><author>noreply@blogger.com (Dror Helper)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm4.static.flickr.com/3104/2366871743_f0f902551e_t.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/04/3-signs-that-youve-been-coding-too-much.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-5203497918146814731</guid><pubDate>Mon, 04 Apr 2011 14:18:00 +0000</pubDate><atom:updated>2011-04-04T17:18:40.343+03:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Unit tests</category><category domain="http://www.blogger.com/atom/ns#">Thoughts</category><title>Testing right by testing the right thing</title><description>&lt;p&gt;Before answering questions about unit testing I usually tend to ask some questions to get the broader picture – especially if the question sound strange. &lt;/p&gt;  &lt;p&gt;Such question was asked by a teammate – he wanted to know if he can replace the behavior of a fake object while still calling the method replaced. This sounded a bit strange to me – either you want to fake an object or you don’t so I asked him if he happens to test the functionality of the same object he’s faking – he answered that no but he needs the method to run in order for the test to pass.&lt;/p&gt;  &lt;p&gt;At first he insisted that he wants to test if a problem report in the system was closed twice as so he needs to count the times that the close method was called while still calling it. Next I asked him how does the user notice the issue, does our user care that he closes the report twice? obviously the user does not care. After further inquiry I manage to find that if a close operation is performed on an already close report an exception is thrown and the user does not get notification for the end of the running process. After we cam to that conclusion he managed to write a simple &lt;u&gt;unit test&lt;/u&gt; that checks whether the user is notified in no time.&lt;/p&gt;  &lt;p&gt;In retrospect I could have told him how to solve the issue he had using our Isolation framework of choice – the result would have a been a poorly written, fragile test.&lt;/p&gt; &lt;a href="http://www.flickr.com/photos/dhdesign/1096440379/" target="_blank"&gt;&lt;img style="display: inline" title="Fragile Box by DHDesign, on Flickr" border="0" alt="Fragile Box by DHDesign, on Flickr" src="http://farm2.static.flickr.com/1203/1096440379_85299a1ed2_m.jpg" /&gt;&lt;/a&gt;  &lt;br /&gt;&lt;a href="http://creativecommons.org/licenses/by-nc/2.0/" target="_blank"&gt;&lt;img title="Creative Commons Attribution-Noncommercial 2.0 Generic License" border="0" alt="Creative Commons Attribution-Noncommercial 2.0 Generic License" align="left" src="http://i.creativecommons.org/l/by-nc/2.0/80x15.png" /&gt;&lt;/a&gt;&amp;#160; by &lt;a href="http://www.flickr.com/people/dhdesign/" target="_blank"&gt; DHDesign&lt;/a&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Happy coding…&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-5203497918146814731?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=jhFSvNLtcgI:cR4FnMKaoJ8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=jhFSvNLtcgI:cR4FnMKaoJ8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=jhFSvNLtcgI:cR4FnMKaoJ8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=jhFSvNLtcgI:cR4FnMKaoJ8:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=jhFSvNLtcgI:cR4FnMKaoJ8:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=jhFSvNLtcgI:cR4FnMKaoJ8:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=jhFSvNLtcgI:cR4FnMKaoJ8:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=jhFSvNLtcgI:cR4FnMKaoJ8:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/jhFSvNLtcgI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/jhFSvNLtcgI/testing-right-by-testing-right-thing.html</link><author>noreply@blogger.com (Dror Helper)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm2.static.flickr.com/1203/1096440379_85299a1ed2_t.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/04/testing-right-by-testing-right-thing.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-2506471538417615883</guid><pubDate>Thu, 24 Mar 2011 18:30:00 +0000</pubDate><atom:updated>2011-03-25T10:55:16.336+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">DSL</category><category domain="http://www.blogger.com/atom/ns#">Software Craftmanship</category><title>DSL presentation at the local Software Craftsmanship group</title><description>A couple of days ago I gave a talk at the local &lt;a href="http://www.linkedin.com/groups?mostPopular=&amp;amp;gid=2578449&amp;amp;trk=myg_ugrp_ovr" target="_blank"&gt;Software Craftsmanship group&lt;/a&gt; on the subject of Domain Specific Languages (DSL) and fluent interfaces. After the session I prepared an exercise for the audience:&lt;br /&gt;
&lt;strong&gt;Create a fluent interface for an online shop that calculates discounts based on customer and purchase information. &lt;/strong&gt;&lt;br /&gt;
I gave a list of use cases and waited to see what would happen:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;VIP customer get 15% discount on all purchases &lt;/li&gt;
&lt;li&gt;Buying product A would give you 10% discount on product B &lt;/li&gt;
&lt;li&gt;Preferred and VIP customers can buy 5 + 1 of a specific product &lt;/li&gt;
&lt;li&gt;All customers can get 20% off purchase using specific coupon &lt;/li&gt;
&lt;li&gt;If amount of purchase &amp;gt; 100$ customer is entitled for 10% discount. &lt;/li&gt;
&lt;li&gt;If customer have purchased &amp;gt; 100$ the last three months upgrade him to VIP &lt;/li&gt;
&lt;li&gt;On the customer’s birthday he’s entitled to 50% discount &lt;/li&gt;
&lt;li&gt;All customers living in New York can get up to 25% off all purchases &lt;/li&gt;
&lt;/ul&gt;I was expecting API along these lines:&lt;br /&gt;
&lt;pre class="brush: csharp;"&gt;RuleEngine.CustomerOfType&amp;lt;VIP&amp;gt;().GetDiscountOf(15);&lt;/pre&gt;The group was divided to teams of 2-3 developers choose a programming language and started working on my exercise. The first thing I’ve noticed is diversity in programming languages – C#, Java, C++ (on Linux!), Python and Ruby were used.&lt;br /&gt;
After a while it has become clear that the room was divided into two main groups of thought. Some teams started to design the object model required to solve the problem while other teams started implementing the rules and created the fluent interface from the required rule. This made me think about upfront design vs. iterative development. No one managed to complete the entire exercise but the teams that choose to design up front managed to cover less rules than the teams that created the rules one by one.&lt;br /&gt;
It was fun watching teams designing an API and then finding ways to create the API they wanted. I saw some interesting implementation ideas that were very different from what I had in mind in a good way.&lt;br /&gt;
All in all it was a good meet-up I can’t wait for the next time.&lt;br /&gt;
&lt;div id="__ss_7354454" style="width: 425px;"&gt;&lt;strong style="display: block; margin: 12px 0px 4px;"&gt;&lt;a href="http://www.slideshare.net/dhelper/domain-specific-languages-7354454" title="Domain specific languages"&gt;Domain specific languages&lt;/a&gt;&lt;/strong&gt; &lt;object height="355" id="__sse7354454" width="425"&gt; &lt;param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=domainspecificlanguages-110323014857-phpapp01&amp;amp;stripped_title=domain-specific-languages-7354454&amp;amp;userName=dhelper" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;param name="allowScriptAccess" value="always" /&gt;&lt;embed name="__sse7354454" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=domainspecificlanguages-110323014857-phpapp01&amp;amp;stripped_title=domain-specific-languages-7354454&amp;amp;userName=dhelper" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"&gt;&lt;/embed&gt; &lt;/object&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="padding-bottom: 12px; padding-left: 0px; padding-right: 0px; padding-top: 5px;"&gt;&lt;u&gt;Update&lt;/u&gt;&lt;br /&gt;
The session (in Hebrew) can be viewed here - thanks to &amp;nbsp;&lt;a href="http://www.irefactor.net/"&gt;Uri&lt;/a&gt;&amp;nbsp;&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;iframe src="http://player.vimeo.com/video/21408457" width="400" height="300" frameborder="0"&gt;&lt;/iframe&gt;&lt;p&gt;&lt;a href="http://vimeo.com/21408457"&gt;SCIL.DSL&lt;/a&gt; from &lt;a href="http://vimeo.com/urilavi"&gt;Uri Lavi&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-2506471538417615883?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=jftu89RA4WY:AJSOEhOJmHc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=jftu89RA4WY:AJSOEhOJmHc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=jftu89RA4WY:AJSOEhOJmHc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=jftu89RA4WY:AJSOEhOJmHc:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=jftu89RA4WY:AJSOEhOJmHc:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=jftu89RA4WY:AJSOEhOJmHc:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=jftu89RA4WY:AJSOEhOJmHc:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=jftu89RA4WY:AJSOEhOJmHc:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/jftu89RA4WY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/jftu89RA4WY/dsl-presentation-at-local-software.html</link><author>noreply@blogger.com (Dror Helper)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/03/dsl-presentation-at-local-software.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-3028612823486849219</guid><pubDate>Thu, 17 Mar 2011 12:56:00 +0000</pubDate><atom:updated>2011-03-17T14:56:18.834+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Thoughts</category><title>Advice for the newbie developer</title><description>&lt;p&gt;Every developer was a newbie once. It doesn’t matter if you’re fresh out of college or been developing software for 10 in this line of work you get to be the newbie from time to time – whenever you learn a new technology or programming language and to some extent whenever you start working in a new place.&lt;/p&gt;  &lt;p&gt;Lately a new member has join our team. Her is a capable developer with years of experience under his belt, he is also completely new to the .NET world. Luckily he has the right attitude and he’s willing to learn everything from scratch - fast. &lt;/p&gt;  &lt;p&gt;the following is my advice to the software developer who wants to learn created from observations of the last few days:&lt;/p&gt;  &lt;h3&gt;Admit that you’re a newbie&lt;/h3&gt;  &lt;p&gt;This on isn’t trivial – in order to become a seasoned developer you have admit that you’re not there yet. This becomes harder as you become a more experienced developer. although you can use old knowledge in order to learn new stuff quicker more often than not you need to start from the bottom. a seasoned C++ developer would probably learn C# quicker than someone who never wrote a single line of code but it does not mean he automatically knows everything.&lt;/p&gt;  &lt;h3&gt;Be willing to leave your comfort zone&lt;/h3&gt;  &lt;p&gt;This is the prerequisite to learning new things. You might be used of doing things using tools and practices that does not apply to the new technology. Instead of forcing your beliefs and methods where they don’t belong you need to learn new&amp;#160; ways of doing things. The plus side is that you might learn something that would change the way you think.&lt;/p&gt;  &lt;h3&gt;Find a mentor&lt;/h3&gt;  &lt;p&gt;Although this point is not mandatory, it helps when there’s someone to learn from. Find your mentor and ask him questions. It could be your team leader, another team member or your friendly neighborhood architect. It doesn’t matter as long as he’s willing to teach you. He would help you avoid the same problem he already solved and teach you new tricks specific to your project sometime without even noticing.&lt;/p&gt;  &lt;h3&gt;Keep an open mind&lt;/h3&gt;  &lt;p&gt;Change is hard, Learning new stuff is hard. Try not to be the obstacle to your own learning. It’s easy to explain why your old way of doing things is better than others and what’s wrong with everything around you (and that &lt;a href="http://en.wikipedia.org/wiki/Wear_Sunscreen" target="_blank"&gt;prices were reasonable, politicians were noble and children respected their elders&lt;/a&gt;). The point is that you need to learn – so why not try something new, the worst that would happen is that you learn not to do it anymore.&lt;/p&gt;  &lt;h3&gt;Don’t take anything for granted&lt;/h3&gt;  &lt;p&gt;Ask questions, not just to learn but to understand why things are done. Just because you’re new it doesn’t mean that you cannot teach as well. People get used to doing things a certain way that might be changed due to a fresh perspective. &lt;/p&gt;  &lt;h3&gt;&lt;img style="display: block; float: none; margin-left: auto; margin-right: auto" src="http://2.bp.blogspot.com/_-1O9jBf4DEo/TTnog2M76gI/AAAAAAAAARk/ZM7ZxAD50Ks/s1600/science+-+you%2527re+doing+it+wrong.jpg" width="321" height="257" /&gt;&lt;/h3&gt;  &lt;h3&gt;Conclusion&lt;/h3&gt;  &lt;p&gt;That’s my thoughts on the subject – I hope it helps the next time you have to learn something new…&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-3028612823486849219?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=daoBDuHE7x8:TP1mhvQDIa4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=daoBDuHE7x8:TP1mhvQDIa4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=daoBDuHE7x8:TP1mhvQDIa4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=daoBDuHE7x8:TP1mhvQDIa4:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=daoBDuHE7x8:TP1mhvQDIa4:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=daoBDuHE7x8:TP1mhvQDIa4:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=daoBDuHE7x8:TP1mhvQDIa4:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=daoBDuHE7x8:TP1mhvQDIa4:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/daoBDuHE7x8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/daoBDuHE7x8/advice-for-newbie-developer.html</link><author>noreply@blogger.com (Dror Helper)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/_-1O9jBf4DEo/TTnog2M76gI/AAAAAAAAARk/ZM7ZxAD50Ks/s72-c/science+-+you%2527re+doing+it+wrong.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/03/advice-for-newbie-developer.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-8412831559140848595.post-3650746375776429794</guid><pubDate>Wed, 09 Mar 2011 10:22:00 +0000</pubDate><atom:updated>2011-03-09T13:01:50.878+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Thoughts</category><title>How I Learned to Stop Worrying and Love the Coding Convensions</title><description>&lt;p&gt;Can you spot the difference between the following two code snippets?&lt;/p&gt;&lt;p&gt;&lt;u&gt;Exhibit #1&lt;/u&gt;:&lt;/p&gt;&lt;pre class="brush: csharp;"&gt;public class MyClass
{
    public int MyFunc(int x, int y)
    {
        return x + y;
    }
}&lt;/pre&gt;&lt;p&gt;&lt;u&gt;Exhibit #2&lt;/u&gt;:&lt;/p&gt;&lt;pre class="brush: csharp;"&gt;public class MyClass{
    public int MyFunc(int x, int y){
        return x + y;
    }
}&lt;/pre&gt;&lt;p&gt;If you have some programming experience you might recognize the two styles. One of which common in your projects and the other looks strange and might even cause you a slight discomfort or bad feeling at the pit of your stomach. Some software developers have been arguing about which is better for as long as I can remember and to tell the truth I was one of them until recently.&lt;/p&gt;&lt;p&gt;I work mostly in C# and the majority of projects/demos/tutorials out there use the first convention. I used to argue that it’s better because it makes the code more readable and besides that’s the Visual Studio default and if it’s good enough for Microsoft it’s good enough for me. Then I got to my current employer where the official coding standard defines option number 2 as well as other conventions and it was hard. Each time I glanced at my code I had the urge to re-format, it made me feel “dirty”. After a while I got used to the new curly brackets location but it still felt wrong to me. One of my responsibilities is to make sure that all of the teams projects follows the official company’s coding specifications some of which I don’t fully agree with.&lt;/p&gt;&lt;p&gt;I’m a fan of this &lt;a href="http://thisdeveloperslife.com/" target="_blank"&gt;developer’s life podcast&lt;/a&gt; and yesterday I heard the latest show &lt;a href="http://thisdeveloperslife.com/post/1-1-4-obsession" target="_blank"&gt;Obsession&lt;/a&gt; where Scott and Rob talk to several developers about their obsessions and than it hit me – the feeling I have whenever I see code that formatted “wrong” is my little OCD (obsessive compulsive disorder), it’s one of the obsessions I picked up on the way, I need to code to be “right”, similar behavior can be found when developers argue what is better – camel-case or Pascal-case, spaces or tabs, VB.NET or C# and so on. Many of these arguments are valid but sometimes we just miss the point, just because we feel good/bad with something doesn’t mean that it’s right it just mean we’re more comfortable with it and that’s ok. &lt;img style="display: inline; float: right" align="right" src="http://t0.gstatic.com/images?q=tbn:ANd9GcTDpUAkQ3-qg3yrUY-sLz7PLM3-Vr0972AkOmFkbOAsCwxIlfeu" width="233" height="158" /&gt;&lt;/p&gt;&lt;p&gt;As for coding standards there is a valid reason&amp;#160; they’re in place – we want all of the company’s source code to follow the same rules. An important goal – even at the price of making you feel good about how the code looks.&lt;/p&gt;&lt;p&gt;One final note – this can only go so far, if the rules make the code less readable and the developers less effective – you should make an effort to change them.&lt;/p&gt;&lt;p&gt;Happy coding…&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8412831559140848595-3650746375776429794?l=blog.drorhelper.com' alt='' /&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=xwkBSrNAsyc:FPHlpWYybjs:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=xwkBSrNAsyc:FPHlpWYybjs:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=xwkBSrNAsyc:FPHlpWYybjs:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=xwkBSrNAsyc:FPHlpWYybjs:zYSYRoQSaQY"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=zYSYRoQSaQY" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=xwkBSrNAsyc:FPHlpWYybjs:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=I9og5sOYxJI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=xwkBSrNAsyc:FPHlpWYybjs:VWBAqf-qjwI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?d=VWBAqf-qjwI" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/HelperCode?a=xwkBSrNAsyc:FPHlpWYybjs:ihZm8jKPjHg"&gt;&lt;img src="http://feeds.feedburner.com/~ff/HelperCode?i=xwkBSrNAsyc:FPHlpWYybjs:ihZm8jKPjHg" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/HelperCode/~4/xwkBSrNAsyc" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/HelperCode/~3/xwkBSrNAsyc/how-i-learned-to-stop-worrying-and-love.html</link><author>noreply@blogger.com (Dror Helper)</author><thr:total>0</thr:total><feedburner:origLink>http://blog.drorhelper.com/2011/03/how-i-learned-to-stop-worrying-and-love.html</feedburner:origLink></item></channel></rss>

