<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6816839243727608984</id><updated>2011-11-28T01:37:13.656+01:00</updated><category term='simplicity'/><category term='specification'/><category term='Mocking'/><category term='Example'/><category term='agile'/><category term='funny'/><category term='cheating'/><category term='bugs'/><category term='Extreme programming'/><category term='Iteration'/><category term='design'/><category term='implementation'/><category term='Procedures'/><category term='Pair Programming'/><category term='Unit Testing'/><category term='GUI'/><title type='text'>eXtreme Programming Jihad</title><subtitle type='html'>A narcissistic blog about my experiences of software development.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>23</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-7681264005971423136</id><published>2011-01-13T17:49:00.000+01:00</published><updated>2011-01-13T17:49:23.547+01:00</updated><title type='text'>TDP - Test driven plumbing</title><content type='html'>The other day I got a new washing machine installed in my house. After the first wash I noticed a small puddle of water on the floor below where the washing machine was connected to ingoing water and outgoing wastewater. I had a bug in my plumbing.&lt;br /&gt;&lt;br /&gt;Being test driven and all I figured I first had to device a test that would indicate I had fixed the leak. I tied a piece of cloth around the joint to the ingoing water and one around the joint to for the wastewater. I ran the machine ones more and observed both cloths getting wet. I removed the cloths and tightened the joints. Tied a dry piece of cloth around each joint and ran the machine a third time. This time the cloths were dry.&lt;br /&gt;&lt;br /&gt;I could have left the cloths there. Then I would even have had a regression test indicates which joint was leaking in case of a new leak, but I removed them, relying on the test to check on the floor for puddles.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-7681264005971423136?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/7681264005971423136/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2011/01/tdp-test-driven-plumbing.html#comment-form' title='1 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/7681264005971423136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/7681264005971423136'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2011/01/tdp-test-driven-plumbing.html' title='TDP - Test driven plumbing'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-7286145779909238404</id><published>2010-11-09T16:39:00.000+01:00</published><updated>2010-11-09T16:39:25.182+01:00</updated><title type='text'>JUnit Max Evaluation</title><content type='html'>I have been using JUnit Max for a few weeks now. And feel like I am ready to do an evaluation of it. &lt;br /&gt;&lt;br /&gt;The benefits of JUnit Max are numerous.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Tests are run faster than when you usually do when using the internal Eclipse JUnit runner, since it starts automatically upon saving a file.&lt;/li&gt;&lt;li&gt;More tests are run during regular development as it eventually will run all my tests for the project I am working on. When running tests manually I tend to run only a subset of tests since running tests is interrupting my coding, and I want the interruptions to be as short as possible. This makes me find unexpected side effects sooner.&lt;/li&gt;&lt;li&gt;JUnit gui of Eclipse have quite a few problems, specially with showing the actual fail message. JUnit max shows the message both in the problems view, and as a "compile error" with a tooltip. Which makes the actual error easier to read.&lt;/li&gt;&lt;li&gt;To get full use of JUnit Max you will, even more, experience the benefit of quick unit tests. Since you will be addicted to getting your test results quickly. You would not want to wait minutes for your IDE compiler, and you will eventually not want to wait for the test errors to show either.&lt;/li&gt;&lt;li&gt;There is no fuzz in getting it to run. If you can run your tests within Eclipse, JUnit Max can run them too.&lt;/li&gt;&lt;/ul&gt;I see only two problems, and they are rather minor.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;JUnit Max adds a little bit of extra load on your development machine, if you are on the limit of what your workstation can perform this might be a problem. Upgrade your equipment!&lt;/li&gt;&lt;li&gt;JUnit Max costs money. In a professional environment, this should be no problem, since the costs of this software is minor compared to the cost of paying the developer to wait for tests to run.&lt;/li&gt;&lt;/ul&gt;&amp;nbsp;To conclude. JUnit Max will make you work more effectively, and is worth the 100$/year it costs. Go get it!&lt;br /&gt;&lt;br /&gt;http://junitmax.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-7286145779909238404?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/7286145779909238404/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2010/11/junit-max-evaluation.html#comment-form' title='0 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/7286145779909238404'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/7286145779909238404'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2010/11/junit-max-evaluation.html' title='JUnit Max Evaluation'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-5500989441790586058</id><published>2010-10-25T17:18:00.000+02:00</published><updated>2010-10-25T17:18:45.441+02:00</updated><title type='text'>JUnit Max</title><content type='html'>I have started to look at Kent Beck's latest creation, JUnit Max (http://www.junitmax.com). And it is looking really promising.&lt;br /&gt;&lt;br /&gt;JUnit Max is an Eclipse plugin that run your junit test cases in the background, just as eclipse compile your code in the background. And like the compiler, JUnit Max adds those small red icons to the margin of your editor window, and also reports the test failures as problems. On my crap laptop, the load on the system is not noticeable. The results however are not as fast as the compiler responses. But still way faster than to run the usual JUnit tool in Eclipse.&lt;br /&gt;&lt;br /&gt;I do not know yet if is worth the $100 per year fee, but I intend to find out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-5500989441790586058?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/5500989441790586058/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2010/10/junit-max.html#comment-form' title='0 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/5500989441790586058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/5500989441790586058'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2010/10/junit-max.html' title='JUnit Max'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-3548295189198876745</id><published>2010-10-20T10:48:00.001+02:00</published><updated>2010-10-20T10:48:54.264+02:00</updated><title type='text'>Continous Deployment</title><content type='html'>He might look like a punk rocker who has worn his DocMartens a few yours too many, but he is making some interesting claims. &lt;br /&gt;&lt;br /&gt;&lt;a href="http://saucelabs.com/blog/index.php/2009/09/continuous-deployment%E2%80%94the-video/"&gt;http://saucelabs.com/blog/index.php/2009/09/continuous-deployment%E2%80%94the-video/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Watch it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-3548295189198876745?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/3548295189198876745/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2010/10/continous-deployment.html#comment-form' title='0 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/3548295189198876745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/3548295189198876745'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2010/10/continous-deployment.html' title='Continous Deployment'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-411370106560207194</id><published>2010-10-20T07:05:00.000+02:00</published><updated>2010-10-20T07:05:34.609+02:00</updated><title type='text'>The joy of TDD</title><content type='html'>During the last few weeks of work I have been working on a small web service app. The work has been done a bit on the side since I had more urgent tasks to attend to, but had some time to spare once in a while. While coding the service, which is not too complex and consists of some thousand lines of code, I worked by the motto of not adding or changing a line of code unless it helped me passing a unit test. I also set out a strategy for myself to test every detail in detail, and test that system composition was done properly, but I had no tests that exercised the whole service. Yesterday I installed the service for the first time on a web server and performed the first manual test call. It worked flawlessly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-411370106560207194?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/411370106560207194/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2010/10/joy-of-tdd.html#comment-form' title='0 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/411370106560207194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/411370106560207194'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2010/10/joy-of-tdd.html' title='The joy of TDD'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-8081106726133222303</id><published>2010-10-19T08:16:00.000+02:00</published><updated>2010-10-19T08:16:09.453+02:00</updated><title type='text'>Back in the saddle</title><content type='html'>After + a year of parental leave I am back programming. Listening to&lt;br /&gt;&lt;a href="http://traffic.libsyn.com/seradio/seradio-episode167-kentBack.mp3"&gt;Software Engineering Radio interview with Kent Beck&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-8081106726133222303?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/8081106726133222303/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2010/10/back-in-saddle.html#comment-form' title='0 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/8081106726133222303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/8081106726133222303'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2010/10/back-in-saddle.html' title='Back in the saddle'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-7150128325240331817</id><published>2009-09-30T13:44:00.000+02:00</published><updated>2009-09-30T13:44:49.825+02:00</updated><title type='text'>The Duct tape programmer debate</title><content type='html'>On Joel Spolsky's blogg, Joel On Software a few days ago there was a post called &lt;a href="http://www.joelonsoftware.com/items/2009/09/23.html"&gt;The Duct Tape Programmer&lt;/a&gt;. He had read a book with an interview with a former Netscape programmer called Jamie Zawinski, who he found to be an amazing programmer working in a manner that Spolsky appreciated. Spolsky gave Zawinski the title Duct Tape Programmer for his way of solving problems in stead of engineering them. He ranted about 'architecture astronauts' who make things too complicated etc. In the debate after the article the actual "Duct Tape Programmer", Jamie Zawinski, stated that Spolsky had gotten most of it wrong (&lt;a href="http://jwz.livejournal.com/1096593.html"&gt;that "duct tape" silliness&lt;/a&gt;), but anyhow the post contains some important things.&lt;br /&gt;&lt;br /&gt;Here are my thoughts, when I trying to interpret what Joel Spolsky writes in a positive way.&lt;br /&gt;&lt;br /&gt;The base property of a duct tape programmer is the ability do things in a simple manner. &lt;a href="http://www.extremeprogramming.org/rules/simple.html"&gt;eXtreme programming has this as one of it's first rules of software design&lt;/a&gt;. But after that fact, the aspects of duct tape programmers that Joel Spolsky so highly admire, are hard to appreciate. Not doing unit tests will not make you deliver a working product sooner. Being a good craftsman is beneficial in programming as in any business, but when someone is going key board cow boy on a project, the mess made will still be substantial, no matter the programmers skill. Succeeding at a programming project is about cooperation, not about duct tape.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-7150128325240331817?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/7150128325240331817/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2009/09/duct-tape-programmer-debate.html#comment-form' title='1 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/7150128325240331817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/7150128325240331817'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2009/09/duct-tape-programmer-debate.html' title='The Duct tape programmer debate'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-866467865559966780</id><published>2009-09-17T18:37:00.000+02:00</published><updated>2009-09-17T18:37:04.103+02:00</updated><title type='text'>Unit testing real value functions revisited</title><content type='html'>My former class mate Patrick gave me the following link&lt;br /&gt;&lt;a href="http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm"&gt;http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Apparently there are people who think quite a lot on these matters, and there are alternatives to absolute delta comparison.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-866467865559966780?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/866467865559966780/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2009/09/unit-testing-real-value-functions_17.html#comment-form' title='2 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/866467865559966780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/866467865559966780'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2009/09/unit-testing-real-value-functions_17.html' title='Unit testing real value functions revisited'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-3655312018207556028</id><published>2009-09-12T17:50:00.001+02:00</published><updated>2009-09-12T17:51:21.088+02:00</updated><title type='text'>Unit testing real value functions</title><content type='html'>In Java, and most other programming languages, have a real number data type. These are, of course, not real numbers, but discrete ones. This provides problems when unit testing, since we often experience small truncation errors when doing repeated calculations. The assertion&lt;br /&gt;&lt;pre&gt;assertEquals(1.0f/3.0f, fancyRealValueAlgorithm(1,3));&lt;br /&gt;&lt;/pre&gt;will often fail due to these truncation errors, even though the fancyRealValueAlgorithm really returns a value that is 1/3.&lt;br /&gt;&lt;br /&gt;I usually resolve this by the simple alteration&lt;br /&gt;&lt;pre&gt;assertTrue(Math.abs(1.0f/3.0f - fancyRealValueAlgorithm(1,3)) &lt; 0.001f);&lt;br /&gt;&lt;/pre&gt;But this has a few problems. It accepts the correct things, but when the assertion fails, the output from the unit test framework is rather poor. I also need to set the limit (0.001f in the example) for each assertion. I have experimented a bit with a helper function which looks like&lt;pre&gt;public void assertRealValueEquals(String message, float expected, float actual, float relativeError) {&lt;br /&gt;   assertTrue(message + " expected &lt;" + expected + "&gt; but was &lt;" + actual + "&gt;", Math.abs(expected - actual) &lt; expected * relativeError);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;But I think there should be better ways. Just have not thought of anyone of them yet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-3655312018207556028?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/3655312018207556028/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2009/09/unit-testing-real-value-functions.html#comment-form' title='2 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/3655312018207556028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/3655312018207556028'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2009/09/unit-testing-real-value-functions.html' title='Unit testing real value functions'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-8276355568840251605</id><published>2009-08-30T14:22:00.001+02:00</published><updated>2009-08-30T14:22:21.722+02:00</updated><title type='text'></title><content type='html'>Amen Hallelujah!&lt;br /&gt;&lt;br /&gt;&lt;embed allowfullscreen="true" allowscriptaccess="always" id="VideoPlayback" src="http://video.google.com/googleplayer.swf?docid=-5105910452864283694&amp;amp;hl=sv&amp;amp;fs=true" style="height: 326px; width: 400px;" type="application/x-shockwave-flash"&gt; &lt;/embed&gt;&lt;br /&gt;&lt;br /&gt;It is really long, but it contains bunches of excellent ideas.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-8276355568840251605?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/8276355568840251605/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2009/08/amen-hallelujah-it-is-really-long-but.html#comment-form' title='0 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/8276355568840251605'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/8276355568840251605'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2009/08/amen-hallelujah-it-is-really-long-but.html' title=''/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-4415618173991884681</id><published>2009-08-29T23:00:00.000+02:00</published><updated>2009-08-29T23:00:53.485+02:00</updated><title type='text'>One test case at the time</title><content type='html'>When writing and implementing tests in TDD there are several different strategies on how and when to do what. I'll try to describe the two extremes.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You write all your unit tests for the behaviour/problem at hand, and implement a solution that solves them all.&lt;/li&gt;&lt;li&gt;You implement one unit test. Implement a solution to that particular test. Implement one more unit test, followed by a solution, and keep going until you are satisfied.&lt;/li&gt;&lt;/ol&gt;&amp;nbsp;When I started working with TDD, strategy no 1 seemed like the way to go. But working that way tends to make me overwork my solutions. And since I am of the opinion that a complex solution is a bad one, at least if there are simpler solutions at hand, I have moved away from that strategy. The last months I have been working with a hybrid of the two, namely:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Write test case stubs of all the aspects of the behaviour you are working with. Example:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;@Test public void testApsectA {fail("NYI");}&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Implement the first test to fail when running JUnit (or whatever is the unit testing framework of the day)&lt;/li&gt;&lt;li&gt;Rerun JUnit, and implement next failing until done.&lt;/li&gt;&lt;/ul&gt;My idea with this strategy is that I in each test I implement only increase the complexity of the implementation as much needed for just that case.&lt;br /&gt;&lt;br /&gt;I am starting to think that I am fooling myself though. There is a risk that while implementing one case, I am designing a solution to fit the coming cases as well. Thus being back on the first strategy. Reading&lt;br /&gt;&lt;a href="http://gojko.net/2009/02/27/thought-provoking-tdd-exercise-at-the-software-craftsmanship-conference/"&gt;http://gojko.net/2009/02/27/thought-provoking-tdd-exercise-at-the-software-craftsmanship-conference/&lt;/a&gt;&lt;br /&gt;which a collogue of mine sent me got me thinking about these things. And I have decided to try the idea with writing just one failing test at a time. I anticipate one problem, that I will forget requirements I used to put in test stubs before. I dunno how I will solve that one yet. I will try to keep them in my head for now, let's see where they end up.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-4415618173991884681?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/4415618173991884681/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2009/08/one-test-case-at-time.html#comment-form' title='0 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/4415618173991884681'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/4415618173991884681'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2009/08/one-test-case-at-time.html' title='One test case at the time'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-7570774419216678579</id><published>2009-08-27T17:43:00.000+02:00</published><updated>2009-08-27T17:43:30.906+02:00</updated><title type='text'>WTF mate?</title><content type='html'>Hmmm, just a few hours after writing my last post, I find this: &lt;br /&gt;&lt;br /&gt;&lt;a href="http://programmingsoftwareprogressive.start4all.com/2009/08/27/extreme-programming-jihad-the-pettson-problem-and-xp/"&gt;http://programmingsoftwareprogressive.start4all.com/2009/08/27/extreme-programming-jihad-the-pettson-problem-and-xp/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;People are strange.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-7570774419216678579?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/7570774419216678579/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2009/08/wtf-mate.html#comment-form' title='3 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/7570774419216678579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/7570774419216678579'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2009/08/wtf-mate.html' title='WTF mate?'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-323220131591699818</id><published>2009-08-27T10:11:00.002+02:00</published><updated>2009-08-27T10:49:55.380+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Procedures'/><category scheme='http://www.blogger.com/atom/ns#' term='Mocking'/><title type='text'>The Pettson Problem and XP</title><content type='html'>In Sweden we have a term which roughly translates into "The Pettson Problem". It originates from a kids story where the main character, Pettson, needs to make pancakes to celebrate his cats birthday. In order to make pancakes he need flour, which he needs to buy from the store. To get to the store he needs to go by bike, but the bike has a flat tire. He has the tools to fix the tire in the tool shed, but the door is locked and the key is on the bottom of the well(!?). He has a fishing pole in the attic, which he could use to get the key out of the well, but he needs a ladder to get to the attic...&lt;br /&gt;&lt;br /&gt;These kinds of problems arise all the time in software development. In my current project for instance, I am starting to look at the user input of recipes. In order to complete yesterdays use case completely, I at least need a web servlet of some sort and a business logics layer. To make it meaningful I would also need some sort of persistence, with some sort of database at the back.&lt;br /&gt;&lt;br /&gt;XP offers a few hints in its rules on how to manage this, and the keys being &lt;a href="http://www.extremeprogramming.org/rules/unittests.html"&gt;unit testing&lt;/a&gt; and &lt;a href="http://www.extremeprogramming.org/rules/simple.html"&gt;simplicity&lt;/a&gt;. But even these can be implemented in different ways:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Premade components&lt;/span&gt;. One common way is to design the general layers, like servlet, business logic and persistance as separate modules not related to the use cases, using generic test cases which one thinks/knows are the behaviours one wants from them.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Depth first implementation&lt;/span&gt;. An alternative aproach is to start with a use case, and when you discover you need any of these generic components, or need to alter them in some manner. You create it or modify as you go along.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Width first implementation.&lt;/span&gt; As you discover that need new functionality you create an interface for it, along with a mock that can be used for the use case currently at hand. You also create, or at least specify, a set of unit tests that tests a proper implementation of the new functionality.&lt;/li&gt;&lt;/ol&gt;Premade components are a common strategy, which feels safe and reliable. It will however rather often fail the simplicity rule, since one tends to over design generic components to solve problems that do not exist.&lt;br /&gt;&lt;br /&gt;Depth first implementation is also rather common in real world practices. It will have a better chance of meeting the simplicity rule. It will however often lead the programmer away from the original problem quite quick, and will lead to lots of non working code until it is all finished. One more problem that might arise is that the unit tests will depend on more than just the unit it is testing. This can of course be solved by mocking the lower layer functionality, but most programmers I know, including myself, have a tendency to throw in the lower layer tests in the same tests as the upper layer tests.&lt;br /&gt;&lt;br /&gt;With the width first approach I will get lots and lots of unsatisfied unit tests. But I will get proper motivation for all the code I write, and I will get unit tests in it proper form, where it tests units rather than whole systems. This is why I will try to maintain a width first implementation strategy in my hobby project.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-323220131591699818?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/323220131591699818/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2009/08/pettson-problem-and-xp.html#comment-form' title='0 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/323220131591699818'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/323220131591699818'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2009/08/pettson-problem-and-xp.html' title='The Pettson Problem and XP'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-7304177985872638696</id><published>2009-08-26T20:55:00.003+02:00</published><updated>2009-08-27T10:12:33.448+02:00</updated><title type='text'>Start with what is important</title><content type='html'>&lt;span id="SPELLING_ERROR_0"&gt;Since&lt;/span&gt; I &lt;span id="SPELLING_ERROR_1"&gt;am&lt;/span&gt; &lt;span id="SPELLING_ERROR_2"&gt;making&lt;/span&gt; a &lt;span id="SPELLING_ERROR_3"&gt;site&lt;/span&gt; &lt;span id="SPELLING_ERROR_4"&gt;based&lt;/span&gt; &lt;span id="SPELLING_ERROR_5"&gt;on&lt;/span&gt; &lt;span id="SPELLING_ERROR_6"&gt;user&lt;/span&gt; &lt;span id="SPELLING_ERROR_7"&gt;generated&lt;/span&gt; &lt;span id="SPELLING_ERROR_8"&gt;content&lt;/span&gt;, &lt;span id="SPELLING_ERROR_9"&gt;the&lt;/span&gt; parts &lt;span id="SPELLING_ERROR_10"&gt;where&lt;/span&gt; &lt;span id="SPELLING_ERROR_11"&gt;the&lt;/span&gt; &lt;span id="SPELLING_ERROR_12"&gt;user&lt;/span&gt; &lt;span id="SPELLING_ERROR_13"&gt;enters&lt;/span&gt; &lt;span id="SPELLING_ERROR_14"&gt;content&lt;/span&gt; &lt;span id="SPELLING_ERROR_15"&gt;to&lt;/span&gt; &lt;span id="SPELLING_ERROR_16"&gt;the&lt;/span&gt; &lt;span id="SPELLING_ERROR_17"&gt;site&lt;/span&gt; is &lt;span id="SPELLING_ERROR_18"&gt;of&lt;/span&gt; &lt;span id="SPELLING_ERROR_19"&gt;great&lt;/span&gt; &lt;span id="SPELLING_ERROR_20"&gt;importance.&lt;/span&gt; Without thinking of any of the other parts of the site I created a simple use case.&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;The user enters a recipe containing an ingredient list and a description as text. The user press a post button and gets a preview of how the site has interpreted the recepie. The user goes back to the input view, and edits a few things. The user clicks post and gets the new preview. The user then chooses to save the recipe.&lt;/blockquote&gt;&lt;br /&gt;First thing on my mind now is to start setting up the test cases for this. But that will have to wait until tomorrow.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-7304177985872638696?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/7304177985872638696/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2009/08/start-with-what-is-important.html#comment-form' title='0 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/7304177985872638696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/7304177985872638696'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2009/08/start-with-what-is-important.html' title='Start with what is important'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-323411717187104780</id><published>2009-08-26T20:20:00.003+02:00</published><updated>2009-08-26T20:51:18.721+02:00</updated><title type='text'>eXtreme Programming of one</title><content type='html'>eXtreme programming is created to work with groups of people making software, and solving the issues that arrise when there are more than one chef making the soup. But several of the ideas of XP, and other agile paradigms are applicable even to projects even with only one participant.&lt;br /&gt;&lt;br /&gt;I am starting a hobby programming project. During that project I will try to investigate some of the points I have been trying to make, along with other thoughts about software quality I have been thinking over the last years.&lt;br /&gt;&lt;br /&gt;The project will be a user generated content site for sharing and organizing recepies. The paradigms I am planning to examine are&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Various aspects of unit testing&lt;/li&gt;&lt;li&gt;The "one piece flow"&lt;/li&gt;&lt;li&gt;Working with verticals rather than layers&lt;/li&gt;&lt;/ul&gt;Since agile is the word of the day, these starting points are of course up for reconcidering. But let's start here, and see where it goes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-323411717187104780?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/323411717187104780/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2009/08/extreme-programming-of-one.html#comment-form' title='0 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/323411717187104780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/323411717187104780'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2009/08/extreme-programming-of-one.html' title='eXtreme Programming of one'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-1716419157361724365</id><published>2009-05-05T08:20:00.002+02:00</published><updated>2009-05-05T10:13:08.152+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><title type='text'>Agile to do the work of evil</title><content type='html'>contains a bit of plump, shady jokes towards the end, but a really funny clip:&lt;br /&gt;&lt;object height="364" width="445"&gt;&lt;param name="movie" value="http://www.youtube.com/v/l1wKO3rID9g&amp;amp;hl=en&amp;amp;fs=1&amp;amp;border=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/l1wKO3rID9g&amp;amp;hl=en&amp;amp;fs=1&amp;amp;border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="364" width="445"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-1716419157361724365?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/1716419157361724365/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2009/05/agile-to-do-work-of-evil_04.html#comment-form' title='3 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/1716419157361724365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/1716419157361724365'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2009/05/agile-to-do-work-of-evil_04.html' title='Agile to do the work of evil'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-5134452379862109060</id><published>2009-05-04T18:33:00.001+02:00</published><updated>2009-05-05T10:13:26.971+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bugs'/><title type='text'>A fraction of the cost of flaws</title><content type='html'>When exposing a product to a end user, one can be sure it will generate support requests. Most likely these requests needs to be acted upon, if you want to keep your users, and they will most likely be caused by a flaw in your product. Be it a communication problem, which prevents the user from understanding how your product is used, or a technical issue that prevents the user from using the product as intended, or something else. Regardless it will hopefully end up in your support organization. There it will consume time.&lt;br /&gt;&lt;br /&gt;To look a bit into this issue I created a simple tool which I fed with 4 parameters.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;An estimate of the number of users who will use the product in the future&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The number of hours per week spent by support to help users suffering from the issue&lt;/li&gt;&lt;li&gt;A guess to whether the occurrence of the issue is proportional to a constant, linear to the number of users, quadratic to the number of users or exponential to the number of users.&lt;/li&gt;&lt;li&gt;A rough estimate of the time it would take to change the product to make the issue go away.&lt;/li&gt;&lt;/ol&gt;The tool plotted 2 graphs displaying the cost in work time per week and total accumulated support work. It also showed where on the accumulated time line the time supporting the issue exceeds the time it had taken to resolve it before shipping.&lt;br /&gt;&lt;br /&gt;I created a, purely theoretical, example where I had a rather newly release product, which has a predicted user base growth of 400% in the coming year. The product has some flaws, among one of them one that rendered 3 hours of support work each week, and the work load is expected to increase proportional to the number of users. As a guess of developer time to fix the issue, I estimated 35 hours. Below you can see the result. The blue line is the accumulated work load on the support organization. The red line is the work load each week on the support organization to handle the issue. On the blue line you can see a dot where the work load on the support organization exceeds the estimated work load on the development team.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_T71XS4Xk5OU/Sf_Rkln5rpI/AAAAAAAAAAM/sLcCwIOHtmw/s1600-h/test-1.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_T71XS4Xk5OU/Sf_Rkln5rpI/AAAAAAAAAAM/sLcCwIOHtmw/s320/test-1.png" alt="" id="BLOGGER_PHOTO_ID_5332210910334922386" border="0" /&gt;&lt;/a&gt;While experimenting with this tool, I quickly found out that the cost of maintaining an issue quickly grows beyond the cost of repairing the issue. One might argue that the user base growth might be unrealistic, the cost of development being higher than support per hour etc. But the key features of the graphs will remain the same.&lt;br /&gt;&lt;br /&gt;Remember: this is only one of the costs of an issue in a product. Fixing an issue should always be top priority.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-5134452379862109060?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/5134452379862109060/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2009/05/fraction-of-cost-of-flaws.html#comment-form' title='1 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/5134452379862109060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/5134452379862109060'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2009/05/fraction-of-cost-of-flaws.html' title='A fraction of the cost of flaws'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_T71XS4Xk5OU/Sf_Rkln5rpI/AAAAAAAAAAM/sLcCwIOHtmw/s72-c/test-1.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-2880092807204476961</id><published>2009-04-24T07:51:00.000+02:00</published><updated>2009-04-24T09:49:18.047+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='Iteration'/><category scheme='http://www.blogger.com/atom/ns#' term='implementation'/><category scheme='http://www.blogger.com/atom/ns#' term='specification'/><title type='text'>The importance of being iterative</title><content type='html'>Most of us programmers like to work according to a specification. A specification that tells us what kind of problem we are solving, and what the expected results are. We usually start by making a design of the solution, then start implementing it. The implementation will contain bugs. Most programmers agree that we create bugs, and we have various ways of dealing with that fact. The design will also contain flaws, resulting in poor performance of the implementation. We tend to call these bugs as well, and try to handle them in the same way as implementation bugs. When we consider us done with the implementation of the specification we consider the feature done. Any change to the specification will be seen as a violation of contract and the large feature creep warning beacon lits.&lt;br /&gt;&lt;br /&gt;The problem is that specifications are inherently flawed. It is extremely hard to make a good specification on first attempt.&lt;br /&gt;&lt;br /&gt;There are several ideas that tries to deal with this problem. Extreme programming, along with may other methodologies, use iterations:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The way to improve your implementation according to design is to iterate it. This is almost always done in the process of programming. You write your tests, you write some code, you run your tests, they fail you correct the code. You improve your tests when you see flaws, you correct the code.&lt;/li&gt;&lt;li&gt;The way to improve your design according to the specification is to iterate it. When something that you need is not supported by the design, you change the design to support your newfound need. You will then have to go back to iterate the implementation.&lt;/li&gt;&lt;li&gt;The way to improve the specification is to iterate it. When you find that the specification does not deal with the problem at hand, you need to change it. Implementing the wrong thing is worse than not implementing it at all. Often you cannot see the flaws in the specifications until you have a working implementation of it to look at. When a specification has changed, you will have to iterate your design again.&lt;/li&gt;&lt;/ul&gt;Of course you can find flaws in the design before your implementation is done, and flaws in the specification before the design is done. In that case you must make the change and start over accordingly.&lt;br /&gt;&lt;br /&gt;Failing at this will make you produce poorly working software that does not do what it needs to do for its user. It will also lower your future development velocity.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-2880092807204476961?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/2880092807204476961/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2009/04/importance-of-being-iterative.html#comment-form' title='1 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/2880092807204476961'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/2880092807204476961'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2009/04/importance-of-being-iterative.html' title='The importance of being iterative'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-703458493790867407</id><published>2009-04-04T20:13:00.000+02:00</published><updated>2009-04-17T12:56:00.810+02:00</updated><title type='text'>Bugs in iterative development</title><content type='html'>The following article created quite a fuzz at work the other day:&lt;br /&gt;&lt;a href="http://testobsessed.com/2009/03/13/handling-bugs-in-an-agile-context/"&gt;[1] http://testobsessed.com/2009/03/13/handling-bugs-in-an-agile-context/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The QA team, with supporters, were upset by her saying that she though bug tracking systems were not needed, and thus should not be used. I stated that I agreed, at least in part, with her, and that made them even more upset.&lt;br /&gt;&lt;br /&gt;I did get, at least partial, support from a my colleague Oskar (author of &lt;a href="http://gamesartdesign.blogspot.com/"&gt;http://gamesartdesign.blogspot.com&lt;/a&gt;). We sat down and discussed it a bit and at least I drew the following conclusions:&lt;br /&gt;&lt;br /&gt;The major problem is how we handle the development process at most companies. Oskar described it as the product owner ordered a full train set of features each sprint, where the team had to finish off all of them, with a prio order if the work load was too high. The feedback loop did only end up back at the QA or the product owner near or at the end of the sprint, where feedback was received on all the features. Resulting in loads of issues and feedback. Since all the feedback could not be acted upon at once, because there was too much feedback to be processed in parallel by the team, we have to keep track of that somewhere. In our case it was a mix of notes (mental or on piece of paper), new backlog items and bugzilla. Much of the stuff that has gone into the bug tacking in the last year of development, is still there, and will most likely be there until the project is terminated.&lt;br /&gt;&lt;br /&gt;The solution we saw was to not build the whole train set, actually no train at all. Only one car. And to take feedback on only that car. If that feedback needs to be addressed, it should be addressed before work on the next car is even started. The rationales behind this are:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The first few guesses of how a feature should work are wrong/not good&lt;/li&gt;&lt;li&gt;The way to do better guesses is to analyze the old guesses and improve them&lt;/li&gt;&lt;li&gt;The aim is always to produce value. The value of a poorly working feature is low, or even negative. &lt;/li&gt;&lt;li&gt;Feedback that is not acted upon will create a debt, the lack of iterations will increase the amount of feedback that is not acted upon.&lt;/li&gt;&lt;/ol&gt;Here comes the tricky part:&lt;br /&gt;A feature should not be considered done until we stop iterate on it. A feature that is not done has no bugs, since it is not even working.&lt;br /&gt;&lt;br /&gt;Of curse there will be flaws and issues that are undiscovered when the team, QA and product owner marks a feature as done. These are bugs, and needs to be properly handled. The key in [1] is that these will not be many. Building a big apparatus to handle just a few issues is not worthwhile.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-703458493790867407?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/703458493790867407/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2009/04/how-to-handle-bugs.html#comment-form' title='1 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/703458493790867407'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/703458493790867407'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2009/04/how-to-handle-bugs.html' title='Bugs in iterative development'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-8073967409555919040</id><published>2009-04-01T20:35:00.000+02:00</published><updated>2009-04-03T20:29:12.246+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='cheating'/><category scheme='http://www.blogger.com/atom/ns#' term='Pair Programming'/><title type='text'>No task is too simple to not be taken seriously</title><content type='html'>I have a colleague that has a standing quote he often picks up and uses:&lt;br /&gt;- That cannot be more than a line of code.&lt;br /&gt;He is not a computer programmer, but that attitude is often picked up by programmers as well. To some programmers, the idea that something that is just a line of code, implies that it does not require the attention that other programming does. Meaning you should not care to "details" like unit tests, design, pair programming or any other procedure you might use in more complicated situations.&lt;br /&gt;&lt;br /&gt;This notion is sometimes (or even often) supported by project managers and other bureaucrats, which can make it even harder to resist. Doing quick fixes gives the illusion of progress, which is beneficial to all those who can take credit from it.&lt;br /&gt;&lt;br /&gt;The downside is that you do not get all the benefits from the procedures you left out. Your code is no longer supported by the unit tests you have, which in the good case makes refactoring hard, in the worse case it creates regression flaws, and potentially adds to clutter and rotting code. You do not get the knowledge share and code review of you co programmer, since you skipped the pair programming. These things will come back and bite you, so watch out!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-8073967409555919040?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/8073967409555919040/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2009/04/no-task-is-too-simple-to-not-be-taken.html#comment-form' title='1 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/8073967409555919040'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/8073967409555919040'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2009/04/no-task-is-too-simple-to-not-be-taken.html' title='No task is too simple to not be taken seriously'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-957237946545169155</id><published>2009-03-27T19:49:00.001+01:00</published><updated>2009-04-03T20:29:49.470+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><title type='text'>When not to use unit tests</title><content type='html'>During my daily struggle to implement a proper working procedure at work, in this particular case, unit testing, I got the question&lt;br /&gt;- When should one not use unit tests?&lt;br /&gt;My gut feeling reply was never, we had a short argument about the usefulness of unit tests in various situations, and ended up in bizare margin cases, like if one should unit test ones unit tests, use unit tests when prototyping/practicing new techniques (of course you should, more than once I have seen prototype code end up in production), and my antagonist was at least sure that he would not have to worry about unit tests too much, since he was largly a GUI programmer. To remedy this I had to look up the following resources on GUI unit testing:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.javaworld.com/javaworld/jw-07-2007/jw-07-fest.html"&gt;Test-driven GUI development with FEST - JavaWorld&lt;/a&gt;&lt;br /&gt;Short tutorial to testing java GUIs using the FEST framework&lt;br /&gt;&lt;br /&gt;&lt;a href="http://marstonstudio.com/2007/07/28/asunit-testing-with-flash-cs3-and-actionscript-3/"&gt;asunit testing with flash cs3 and actionscript 3&lt;/a&gt;&lt;br /&gt;An introduction to testing flash and action script 3 using AsUnit&lt;br /&gt;&lt;br /&gt;&lt;a href="http://nunitforms.sourceforge.net/docs.html"&gt;NUnitForms : An NUnit extension for testing Windows Forms applications.&lt;/a&gt;&lt;br /&gt;Gui testing for .NET. They got the concept of unit testing a bit backwards, but the methods should be usable for proper programming aswell.&lt;br /&gt;&lt;br /&gt;I am not often faced with GUI programming in my line of work, but I hope that I can get back on this topic when I have more hands on experience.&lt;br /&gt;&lt;br /&gt;So the question still seems open, when should I not use unit tests, I have yet to find a situation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-957237946545169155?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/957237946545169155/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2009/03/when-not-to-use-unit-tests.html#comment-form' title='0 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/957237946545169155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/957237946545169155'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2009/03/when-not-to-use-unit-tests.html' title='When not to use unit tests'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-5433194692151424802</id><published>2009-03-25T07:47:00.000+01:00</published><updated>2009-04-24T09:50:17.680+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Extreme programming'/><category scheme='http://www.blogger.com/atom/ns#' term='simplicity'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>YAGNI</title><content type='html'>Computer programmers are often immensely proud of their code, and we often brag about our fancy solutions. This is a perfect boost of ego, as well as a perfect waste of time and money.&lt;br /&gt;&lt;br /&gt;The first rule of Extreme Programming design is &lt;a href="http://www.extremeprogramming.org/rules/simple.html"&gt;Simplicity&lt;/a&gt;. And this is a rule one cannot under estimate.&lt;br /&gt;&lt;br /&gt;Here is where your user stories and following user tests come into play. Every design made should be supported by a user story with accompanied unit tests. Implementation and design not explicitly supported by a user story will add to complexity, complexity will introduce more errors, increase maintenance costs, will make the code harder to read and understand and harder to refactor/rework when a better solution is found, or the requirements have changed. The benefit of making a more complex solution is that it, hopefully, adds more useful features. But since the features were not requested in the first place they will most likely not be used.&lt;br /&gt;&lt;br /&gt;I use the following process to get on the right path:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Write the user stories together with customer&lt;/li&gt;&lt;li&gt;Break the user stories down into "technical testable chunks"&lt;/li&gt;&lt;li&gt;Write unit tests to cover the broken down user stories&lt;/li&gt;&lt;li&gt;Implement just enough to get a green light on the unit tests&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Sure one might spin away in technical design or feature inventing orgies on item no 2 and 4, but it will only come back and bite you later on.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-5433194692151424802?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/5433194692151424802/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2009/03/yagni.html#comment-form' title='2 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/5433194692151424802'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/5433194692151424802'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2009/03/yagni.html' title='YAGNI'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6816839243727608984.post-2317529679993913483</id><published>2009-03-11T13:41:00.000+01:00</published><updated>2009-03-13T10:16:08.437+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Unit Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Example'/><title type='text'>Unit Test Driven Development by example part 1</title><content type='html'>Most programmers have heard of the concept unit tests, many of them have even tried it out. The idea to write unit tests before the actual implementation has also been presented to most programmers, and most programmers have shrugged and thought "I cannot test my code until I know how it is working". Well, most programmers are infidels.&lt;br /&gt;&lt;br /&gt;I would claim that writing the unit tests before the implementation is the key idea behind unit tests. It will change the way you look upon the whole process of developing code, at least it did to me. It provides a natural route from feature request from the business people through out the whole life of the code. It helps you decide how complex you need to make your design.&lt;br /&gt;&lt;br /&gt;I will here present an rather phony example, which I hope will show you the excellence of unit testing.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Unit Testing Example: The Rating Calculator&lt;/span&gt;&lt;br /&gt;We are working on a chess game server. We have been given the assignment to calculate and store ratings at game end. The rating should be ELO with static, but configurable K and scale values.&lt;br /&gt;&lt;br /&gt;First we start off by writing &lt;span style="font-style: italic;"&gt;short&lt;/span&gt; use cases:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;      S = 400&lt;br /&gt;K = 10&lt;br /&gt;Player A has rating 1200 win&lt;br /&gt;Player B has rating 1000 loose&lt;br /&gt;E_A = 1/(1+10^((1000-1200)/400)) = 0.75975&lt;br /&gt;E_B = 1/(1+10^((1200-1000)/400)) = 0.24025&lt;br /&gt;Player A gets rating 1200+10*(1-0.75975) = 1202&lt;br /&gt;Player B gets rating 1000+10*(0-0.24025) = 998&lt;/li&gt;&lt;li&gt;S = 400&lt;br /&gt;K = 10&lt;br /&gt;Player A has rating 1200 loose&lt;br /&gt;Player B has rating 1000 win&lt;br /&gt;E_A = 1/(1+10^((1000-1200)/400)) = 0.75975&lt;br /&gt;E_B = 1/(1+10^((1200-1000)/400)) = 0.24025&lt;br /&gt;Player A gets rating 1200+10*(0-0.75975) = 1192&lt;br /&gt;Player B gets rating 1000+10*(1-0.24025) = 1008&lt;/li&gt;&lt;li&gt;... more examples with different values for K, scale, ingoing rating, winners/losers/draws and thus different resulting ratings.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;When a rating calculator is called to process an unfinished game, an exception is thrown&lt;/li&gt;&lt;/ul&gt;The aim is to make each of these use cases to match one test method in the test case. Writing the use case as a comment to the test method also helps, both to remember where you put the use case, and as a sort of documentation of the test case.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class EloRatingEndGameProcessorTest {&lt;br /&gt;/**&lt;br /&gt;* S = 400&lt;br /&gt;* K = 10&lt;br /&gt;* Player A has rating 1200 loose&lt;br /&gt;* Player B has rating 1000 win&lt;br /&gt;*&lt;br /&gt;*  E_A = 1/(1+10^((1000-1200)/400)) = 0.75975&lt;br /&gt;*  E_B = 1/(1+10^((1200-1000)/400)) = 0.24025&lt;br /&gt;*&lt;br /&gt;* Player A gets rating 1200+10*(0-0.75975) = 1192&lt;br /&gt;* Player B gets rating 1000+10*(1-0.24025) = 1008&lt;br /&gt;*/&lt;br /&gt;@Test&lt;br /&gt;public void testHigherRaterLooseRatingChange() throws Exception {&lt;br /&gt; Player playerA = new Player();&lt;br /&gt; Player playerB = new Player();&lt;br /&gt; Float playerAScore = 1.0f;&lt;br /&gt; Float playerBScore = 0.0f;&lt;br /&gt; Game game = new Game(playerA, playerB, playerAScore, playerBScore);&lt;br /&gt; PlayerDao playerDao = new MockPlayerDao();&lt;br /&gt; playerDao.updateRating(playerA, 1200);&lt;br /&gt; playerDao.updateRating(playerB, 1000);&lt;br /&gt;&lt;br /&gt; GameEndProcessor processor = new EloRatingGameEndProcessor(playerDao, 400.0f,10.0f);&lt;br /&gt;&lt;br /&gt; processor.process(game);&lt;br /&gt;&lt;br /&gt; assertEquals(1192, playerDao.getRating(playerA));&lt;br /&gt; assertEquals(1008, playerDao.getRating(playerB));&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;.&lt;br /&gt;&lt;br /&gt;/**&lt;br /&gt; * Game has no result when rating processor is called, exception expected&lt;br /&gt; */&lt;br /&gt;@Test&lt;br /&gt;public void testProcessingUnfinishedGame() {&lt;br /&gt; Game game = new Game();&lt;br /&gt;&lt;br /&gt; PlayerDao playerDao = new MockPlayerDao();&lt;br /&gt; GameEndProcessor processor = new EloRatingGameEndProcessor(playerDao, 400.0f,10.0f);&lt;br /&gt;&lt;br /&gt; try {&lt;br /&gt;  processor.process(game);&lt;br /&gt;  fail("When processing a game with no result, we expect a GameNotFinishedException");&lt;br /&gt; } catch (GameNotFinishedException e) {&lt;br /&gt;  // ok, this is expected&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Where&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Player is the domain model player representation. *&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Game is the domain model game representation. *&lt;br /&gt;&lt;/li&gt;&lt;li&gt;PlayerDao is an interface for manipulating players towards some persistent storage. The actual implementation of a PlayerDao is not under test here.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;MockPlayerDao is a part of the actual test and is defined by&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;pre&gt;&lt;br /&gt;public class MockPlayerDao implements PlayerDao {&lt;br /&gt;private Map&lt;player,&gt; ratings = new HashMap&lt;player,&gt;();&lt;br /&gt;@Override&lt;br /&gt;public int getRating(Player player) {&lt;br /&gt;    return ratings.get(player);&lt;br /&gt;}&lt;br /&gt;@Override&lt;br /&gt;public void updateRating(Player player, int newRating) {&lt;br /&gt;    ratings.put(player, newRating);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/player,&gt;&lt;/player,&gt;&lt;/pre&gt;&lt;ul&gt;&lt;li&gt;GameEndProcessor is an interface for objects called at end of game.&lt;/li&gt;&lt;li&gt;GameNotFinishedException is an exception which we expect when a rating calculator is called on a game that has not ended yet.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;EloRatingGameEndProcessor is the class under test, which is not written yet.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;* This class is not under test, and we assert that this class is covered by other test&lt;br /&gt;&lt;br /&gt;We continue with writing similar test cases for each use case. Expanding the interfaces as we need, but we do not implement anything in the actual source code yet!&lt;br /&gt;&lt;br /&gt;When all use cases are covered by test cases, we run our tests and observe the results. It will fail miserably. But not to worry. Now look at the first few test failures and implement the easiest solution possible to those failures. I end up with the following implementation of EloRatingGameEndProcessor:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class EloRatingGameEndProcessor implements GameEndProcessor {&lt;br /&gt;&lt;br /&gt;private PlayerDao playerDao;&lt;br /&gt;private float S;&lt;br /&gt;private float K;&lt;br /&gt;public PlayerDao getPlayerDao() {&lt;br /&gt;  return playerDao;&lt;br /&gt;}&lt;br /&gt;public void setPlayerDao(PlayerDao playerDao) {&lt;br /&gt;  this.playerDao = playerDao;&lt;br /&gt;}&lt;br /&gt;public float getS() {&lt;br /&gt;  return S;&lt;br /&gt;}&lt;br /&gt;public void setS(float s) {&lt;br /&gt;  S = s;&lt;br /&gt;}&lt;br /&gt;public float getK() {&lt;br /&gt;  return K;&lt;br /&gt;}&lt;br /&gt;public void setK(float k) {&lt;br /&gt;  K = k;&lt;br /&gt;}&lt;br /&gt;public EloRatingGameEndProcessor(PlayerDao playerDao, float s, float k) {&lt;br /&gt;  super();&lt;br /&gt;  this.playerDao = playerDao;&lt;br /&gt;  S = s;&lt;br /&gt;  K = k;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public void process(Game game) throws GameNotFinishedException {&lt;br /&gt;  float ratingA = playerDao.getRating(game.getPlayerA());&lt;br /&gt;  float ratingB = playerDao.getRating(game.getPlayerB());&lt;br /&gt;  float EA = (float) (1.0f/(1.0f+Math.pow(10, (ratingB-ratingA)/S)));&lt;br /&gt;  float EB = (float) (1.0f/(1.0f+Math.pow(10, (ratingA-ratingB)/S)));&lt;br /&gt;&lt;br /&gt;  int newRatingA = Math.round(ratingA + K * (game.getPlayerAScore() - EA));&lt;br /&gt;  int newRatingB = Math.round(ratingB + K * (game.getPlayerBScore() - EB));&lt;br /&gt;&lt;br /&gt;  playerDao.updateRating(game.getPlayerA(), newRatingA);&lt;br /&gt;  playerDao.updateRating(game.getPlayerB(), newRatingB);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;We rerun the tests. If we got it all right, get a lot more uplifting results. But we still have the last test case left, so we need to do a bit more implementation.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;@Override&lt;br /&gt;public void process(Game game) throws GameNotFinishedException {&lt;br /&gt; if (game.getPlayerAScore() == null&lt;br /&gt;   || game.getPlayerBScore() == null) {&lt;br /&gt;  throw new GameNotFinishedException();&lt;br /&gt; }&lt;br /&gt;...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Rerun the tests, and we observe the results. All test should now pass, and we have a rating calculator of which we can be fairly sure to state that it will update the rating according to standard ELO manners, provided the calculator is called at end game and we have a PlayerDao that stores the ratings properly. In order to know that the processor is called at end game, and the real PlayerDao implementation works, we need to write more tests...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6816839243727608984-2317529679993913483?l=xp-jihad.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://xp-jihad.blogspot.com/feeds/2317529679993913483/comments/default' title='Kommentarer till inlägget'/><link rel='replies' type='text/html' href='http://xp-jihad.blogspot.com/2009/03/unit-test-driven-development-by-example.html#comment-form' title='0 kommentarer'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/2317529679993913483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6816839243727608984/posts/default/2317529679993913483'/><link rel='alternate' type='text/html' href='http://xp-jihad.blogspot.com/2009/03/unit-test-driven-development-by-example.html' title='Unit Test Driven Development by example part 1'/><author><name>Niklas Gawell</name><uri>http://www.blogger.com/profile/01022019979992504458</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
