Oct 12

Regardless of what we discover…

The Retrospective Prime Directive:

Regardless of what we discover, we understand and truly believe that everyone did the best job they could, given what they knew at the time, their skills and abilities, the resources available, and the situation at hand.

What a great starting point for generating a safe environment during a sprint retrospective. A safe environment is important for a successful retrospective. However, starting with the prime directive will not generate a successful retrospective. Let me explain.

If I start thinking about the last sprint with the prime directive in mind, it is close to impossible for me to see how I could have done better. Because I did the best job I could – that’s what the prime directive said. If I’ve done the best job I could, what could be improved? Because my knowledge & skills are what they are, it sure is the situation at hand and the resources available which could be improved: The story wasn’t workable, the automated acceptance tests were sorely lacking, the build server failed all the time, the code was using this incomprehensible template stuff, the compiler was too slow, I had too many meetings, there are always conflicts when I try to commit my code, the APIs encountered are too complex, the product owner wasn’t available for questions 24/7, the unit tests ran for ages and slowed me down, the Scrum Master didn’t moderate each and every meeting & discussion – etc. and so forth.

If you’re using the prime directive as a starting point, you’re framing your mind the wrong way.

What happened to individual responsibility, to laziness, to procrastination, to lacking technical skills, to a lack of practice, to inefficient use of my time, to a lack of knowledge, to stalling, to stepping up to the plate and saying “I have to do a better job and I need to do something about it”?

Why don’t we start with the Retrospective Prime Questions (you bet I made up this phrase 2min ago)?

  • What could I have done to make this sprint more successfully?
  • How could I have behaved differently?
  • What should I have done to help my teammate accomplish his task?
  • What could I have contributed to improve the process?
  • What do I have to learn in order prevent this from happening again?
  • What can I do to improve our environment?

Maybe we would come up with action items like this:

  • Mary will fix this §$%& build server. Joe will help her out, he’s a Jenkins wizard. They’ll get right to it on Tuesday morning.
  • Mark will help improving our unit tests performance – he has some great ideas on how to make that happen.
  • Erwin needs to use Skype to contact the product owner with questions instead of stalling. Our Scrum Master will help him by reminding us in the Daily Scrum that the product owner is on the road.
  • Joe needs to understand this %&$§ template stuff. He will sit down over the weekend for a few hours, read up on it and do some experiments. Jack said he will work with him over a beer next Wednesday night and help Joe getting his templates straight. Mary said she’ll join Joe & Jack, too as she’s unsure if she really got variadic templates. Our Scrum Master will make sure that there’s plenty of free beer available to make this a pleasant experience.
  • We will check the top stories on the product backlog regularly and see if they’re workable. I will start doing that tomorrow morning before the daily meeting. 10 minutes & a good coffee should be enough to do that.
  • Paul will update his code from the repository multiple times a day to avoid deadly conflicts. We’ll set up a kitchen timer for him as reminder.
  • Marvin needs to ask the Scrum Master to help out if his discussions spiral out of control. Erwin, who’s sitting next to Marvin will help with notifying the Scrum Master in time.
  • John knows a little bit about this Cucumber thing, he’ll sit down with the product owner next week to show him how to use it. This will bring us closer to automated acceptance tests.
  • Hans will ask our Scrum Master about recommendations on how to improve his verbal communication skills.


I’m neither a professional Scrum Master nor a Product Owner nor a Scrum expert. I’m just an ordinary software developer trying to deliver valuable, clean software. Most of the time, I’m failing. And it’s not because my environment is to blame or because there are impediments beyond my control. It is because I have to do a better job. And I want you to help me do that.

Another take on this topic can be found at What’s wrong with the Retrospective Prime Directive?.

My Scrum Master just sent me this link: NAIKAN. Looks like a worthwhile (Warning: German Language) exercise to encourage self-reflection.

Very nice German language post on this very topic: Der Flügelschlag eines Schmetterlings.

Great take on re-phrasing the Retrospective Prime Directive: Another Alternative To The Retrospective Prime Directive. Here’s a nice German translation by Nicole Rauch.

Another take on this very topic by Thomas Mayer – The Prime Defective.

Oct 12

Angst, Mut, Verantwortung, Disziplin

Joseph Pelrine hat auf der Agile Bodensee einen schönen Satz gesagt (ich paraphrasiere aus dem Gedächtnis):

“Über Scrum zu reden oder Scrum zu lehren / coachen ist viel leichter als Scrum tatsächlich tagtäglich zu implementieren”.

Das Arbeiten im Scrum-Umfeld verlangt dem Entwickler einiges ab. Es bringt Ängste zutage, erfordert Mut, Verantwortung und Disziplin:


  • Angst nicht “ganz fertig” zu werden
  • Angst sich vor den anderen Teammitgliedern zu blamieren
  • Angst verantwortlich gemacht zu werden
  • Angst daß eigene Defizite sichtbar werden
  • Angst daß der Task mehr beeinhaltet als man absehen konnte
  • Angst die notwendige Technik nicht zu beherrschen
  • Angst nicht rechtzeitig nach Hause zu kommen


  • Mut auch komplexe und unbekannte Aufgabenstellungen anzugehen
  • Mut andere rechtzeitig um Hilfe zu bitten
  • Mut eigene Defizite einzugestehen
  • Mut Verantwortung zu übernehmen
  • Mut auch mal später nach Hause zu kommen
  • Mut Aufgaben auch nachträglich zu vereinfachen
  • Mut nicht dem Sprintziel dienliche Aufgaben beiseite zu schieben


  • Verantwortung, sich fehlende Fähigkeiten anzueignen
  • Verantwortung für die Gruppe zu übernehmen
  • Verantwortung für eigene Fehler zu übernehmen
  • Verantwortung für das Produkt zu übernehmen
  • Verantwortung pünktlich zu erscheinen
  • Verantwortung Informationen klar, präzise und zeitgerecht zu vermitteln
  • Verantwortung sich über anstehende Aufgaben zu informieren


  • Disziplin den Test zuerst zu schreiben
  • Disziplin auch wenn es zeitlich eng wird sauberen Code zu schreiben
  • Disziplin immer wieder über das eigene Fortkommen transparent zu informieren
  • Disziplin auch die unangenehmen oder unpopulären Tätigkeiten zu erledigen
  • Disziplin komplexe Aufgabenstellungen in überschaubare Arbeitspakete zu zerteilen
  • Disziplin immer wieder rechtzeitig Hilfe einzuholen
  • Disziplin bei jeder Tätigkeit immer wieder das Sprintziel im Auge zu haben

Sep 12

Short recap of the Wrecking Ball tour’s 2012 German leg (yup, I’m very late)

(Should get this months old draft out there before the 2013 leg of the tour is upon us 😉

Not sure if I qualify as a Bruce Springsteen “fan”. With fandom, I do associate hysterical screaming (and I’m far from it). “Mild stalking” is another characterization I associate with fandom. Most certainly, I’m not interested in the private life of neither Bruce Springsteen nor members of the E Street Band.

However, I do care deeply about the music. Everybody has a certain kind of music which deeply resonates with him or her. And Bruce Springsteen’s music deeply resonates with me.

Frankfurt was special as I took my wife and my two older daughters with me. We got seats on the right hand side quite far from the stage. The concert, however, became absolutely magical as Bruce & the E Street band clearly loosened up in the last quarter of the concert. Summertime Blues in the main set came unexpected, and the departure from the standard encores played on the tour so far with Cadillac Ranch, Sherry Darling & Glory Days made my day.

For Cologne, a slightly more intimate stadium than Frankfurt, I managed to get front of stage tickets. Unfortunately, I missed the pit roll calls by about 15minutes (shouldn’t have stopped for a bathroom break during the 2.5h drive to Cologne ;-), but found a nice, relatively short queue in the shades. Met a few nice folks who provided me with priceless advice on how to convince my wife to do a few more Springsteen concerts (Hint: Trade shopping/sightseeing in Milan/Florence for spending the evening at Springsteen concerts). I got lucky and ended up maybe 12th “row” on the left side of the stage, with a great view of the fantastic performance and hard work Nils Lofgren is putting into the show.

For the Berlin trip (kindly sponsored by my aforementioned wife), I showed up early at the Berlin Olympic Stadium, got my number (171) and spent the day either queueing, showing up for the roll call or queueing & reading (Recommend classic car magazines). A worthwhile effort, as I got a great spot in the pit (about 5th row) on the right side of the stage right in front of Steven van Zandt. The big news was, of course, the opening song “When I leave Berlin” which was extensively rehearsed during the soundcheck and an absolutely beautiful rendition of “Save my Love”.

I didn’t expect the Wrecking Ball material to be a perfect fit for a stadium setting. Of course, I was wrong. It worked out great, lot’s of feedback from the audience.

Was it worthwhile? You bet. Rumors suggest that there might be a second european leg next year (Munich? Hamburg?) I’m very much looking forward to it, maybe “Racing in the Street” this time? I hope to put the free advice I got in Cologne to good use and try to get a few more 2013 concerts in Italy or Spain on my schedule.

Pro tip: Get a Mophie Juice Pack Plus for your iPhone if you intend to tweet the setlist. It’s $§&! ugly (the Mophie, not the setlist), but it will double your battery capacity during the show. And trust me, you’ll need it as you’re desperately trying to get your tweets through the congested ether at the venue.

Sep 12

Staring is not an efficient coding technique

The following quote from Buzz Andersen’s blog (which I highly recommend) caught my eye:

…full-time pairing can make the certain amount of “staring into space” time every programmer needs to get things right excruciatingly awkward.

I don’t want to dive into the pair programming discussion this time, I’ll leave this for another post. I would like to talk about staring. Staring on the code. Staring on a comment. Staring on a UML design sketch. Or, as Buzz puts it, staring into space. (*)

As far as I can tell (and I have done my fair share of staring over the years), staring is a software engineering technique where, for an extend period of time, the software developer refrains from any movement of his extremities, stops moving his eyeballs and focusses on a particular piece of code, while his CPU cores, umm, brain runs at 100% load trying to solve the problem at hand.

If we’re lucky, said developer appears to wake up from time to time, types a few characters, maybe adds a comment and resumes staring. If we’re less lucky, said developer will remain unresponsive for extended amounts of time and will make no measurable progress towards his goal.

I don’t dispute that “Staring” may be a technique to get things right, but I would like to go on the record that it’s an efficient technique to get things right. Day after day, I observe that developers “stare into space” or, even more inefficient, “stare on the code” in order to solve problems. However, I’ve never seen a problem getting solved by staring, I’ve only seen problems getting solved by adding or changing code.

Why is staring an inefficient technique, you may ask?

Staring is inefficient because it doesn’t employ a feedback loop. You are reasoning about the code with yourself. Nothing wrong with it, but there’s no one involved giving you feedback on your thoughts or challenging your assumptions – after all, it’s just you staring at the code.

If you catch yourself staring at code too often, make sure to get into the habit of doing something with the code instead:

  • Even if you don’t have automated tests (and you know you should, don’t you), you can do tiny, lowest-risk refactorings which help you deepen your understanding of the code just a tiny little bit. Rename a variable, a function, extract a few lines of code to a new method, write a comment (gasp), change the formatting to suit your style (quadruple gasp). You can always revert this changes after you understood what’s going on (you do use version control, don’t you?)
  • How about running the code in a debugger to get the additional feedback of variable / objects / state changes at runtime?
  • How about writing unit tests? Write a test, write a little bit of code, write some more code, see a test failing, change the code, write a test to test your assumptions about specific parts of the code. Do a change to the codebase to learn something? Do the tests still run? Great. They don’t? Looks like your assumptions were wrong. Trace back, take another route.

If you absolutely must “stare” at the code, I suggest to take a step back and “sleep on it” or to take a short walk. But those are techniques which should be reserved to occasions when you really got stuck and you’re trying to solve really hard problems. Guess what, most of the time the problems aren’t that hard. They may be challenging but they are quite solvable by taking tiny, reproducible (sometimes revertible) steps towards a solution.

Code is like clay. Make sure to mold it. Carefully. You’ll learn way more by molding the code, not by staring at it.

(*) Don’t want to get into discussing “staring on web-sites not at all related to the task at hand” either.

Sep 12

I sense a disturbance in the Atlassian force…

Great products are the foundation of a great company. Atlassian has great, rock-solid products (If I wouldn’t be a rather stern German, I would say these are absolutely fantastic products). They improve those products thoughtfully and continuously. We have been customers since 2006. Actually. we have been customers for so long that I find e-mails from a co-CEO answering dumb questions of mine during our JIRA evaluation.

JIRA 2/3

First, we purchased the JIRA Enterprise Edition and renewed our maintenance/update every year. Rock-solid product. Worked great. Atlassian kept improving it. Pretty steep pricing for us, but it had unlimited users which was important as we had a product with about 150+ customers reporting their feedback through JIRA.

JIRA 4 license change

Then, Atlassian introduced JIRA 4, and nixed the unlimited users Exterprise Edition. Changing to the user tier we needed would have doubled our yearly maintenance costs including the risk of running out of users again in the future. We didn’t do it but decided to stick with JIRA 3 for this particular project. We put all the other projects on a newly purchased JIRA 4 50 user license (about 15 active engineers (devs & support) and about 20 marketing/sales guys/gals which would mostly be read-only/comment-only – with a yearly maintenance/update fee which was absolutely worth it because Atlassian kept improving the product.


After introducing Scrum a few years ago, we looked at Atlassian’s Greenhopper offering. As expected, a great product. However, we would have had to purchase a 50 user Greenhopper license to match our 50 user JIRA license – although we only have about 10 devs on our Scrum team. The rest of the users couldn’t care less about Greenhopper. Plus Greenhopper is quite steeply priced (about 50% of the base JIRA license) for both the product and the yearly maintenance. So the Greenhopper purchase never happened for us.


Because JIRA was working so well for us (from a product point of view), we looked into Confluence. Another great product. We looked at the pricing and found there was no 50 user tier, just a 100 user tier. So we would basically have to pay for 50 users we didn’t intend to use in the foreseeable future. However, the product is – as mentioned before – a really great one, so we decided to go for it – of course including a yearly maintenance/update fee which was absolutely worth it because Atlassian kept improving the product.

Dropping MacOS

Probably about 1.5 years ago, out of the blue, MacOS (our platform for both JIRA & Confluence) was no longer supported as a production environment for both JIRA & Confluence – Mind you, I’m not disputing the decision, I was baffled because there was absolutely no mention of this rather important news (“We cease support for a major operating system platform”) on any of Atlassians developer blogs / website etc. So we’re running our JIRA / Confluence production systems on some unsupported operation system – but hey, it still works. Still rock solid. Still great products.

Team Calendar

Atlassian came out with a new plug-in for Confluence called Team Calendar, which – you know what’s coming – is actually quite a great product and would be a nice fit for us. However, we would have had to purchase a 100 user Team Calendar license to match our 100 user Confluence license – although we only have about 10 devs which would use Team Calendar (rest of the company is on Exchange/Outlook – let’s not go there). Plus Team Calendar is very steeply priced compared to the base Confluence license for both the product and the yearly maintenance. So the Team Calendar purchase never happened for us.

Confluence license change

Last night, I received a lengthy, nicely layed-out HTML e-mail titled “Upcoming Changes to Your Confluence Download License” in my inbox. The e-mail was talking eloquently about the latest Confluence 4.3 release and how great it was – agreed. Another solid release. It also mentioned prominently that I would be able to purchase yearly maintenance at the existing price for two years – although the licensing would change – and that there would be additional “Enterprise” licensing tiers. It talked about existing users being able to renew at existing prices or upgrade during a grace period, but no mention how the new licensing & pricing would affect existing customers. Connecting the dots, I decided to click through to the FAQ page get more details on this “license change”. On item 5 (of 13), I found that Atlassian intends to increase the cost of our yearly Confluence maintenance/update fee by a whopping 80%. Words fail me.

The message I receive

  • Atlassian tends to make unexpected, substantial licensing changes
  • The pricing of plug-ins seems somewhat off compared to the base product
  • The pricing of plug-ins is tied to the user tier of the base product
  • An 80% price increase for yearly maintenance / updates

From where I stand, all these moves are maximizing Atlassian’s profits at the expense of their users. I’m not sure how I can align this message with the set of values Atlassian is based on.

I conclude that there’s a substantial risk involved with being an Atlassian customer. It’s not the risk that you end up with a set of bad products. The products are great. Rather, it’s a business & financial risk and a lack of mid- and long term licensing cost predictability (both financial and feature set predictability). And no, a two year grandfathering period doesn’t change the message I receive.

P.S.: Dear @atlassian employees reading through this rant (I know you will): If there are any factual errors in my rant, please do not hesitate to contact me at hm dot kern at gmail dot com, via Twitter @hmkern99 and I will update this post right away.

[Update 1] I updated the section “Confluence license change” to more accurately reflect the content of the mail. Thanks for the feedback, Matt!

May 12

Softwerkskammer Karlsruhe, 9th Meeting

This time, we decided to do the widely known Roman Calculator Kata. Coding via a beamer worked surprisingly well, especially after Nicole took over who’s a way faster & smarter typist than yours truly.

A couple of observations:

  • Although we started doing TDD (with the proper focus on “Driven”), the group quickly moved away from “doing the simplest thing that could possibly work” and started putting out new algorithmic variants of the solution at an amazing rate using the existing tests as a safety net
  • Taking small steps is a challenge if you’re in a room with smart people who tend to solve the problem right away by applying their superior brains
  • Taking baby steps is even harder in such a setting
  • It would be an interesting exercise to clean up the code produced as much as possible (and making it as C or C++ like as possible while doing so)
  • It would be an interesting exercise to start over with a clean slate and try a different order of the tests and see how this effects the algorithm chosen
  • Another variant would be to start with or at least add tests which check for edge cases or error conditions
  • Note to self: More cold soft drinks are needed / programmer food would be nice, too

A great, educational way to spend the evening. Thanks to all the participants – I look forward to the next meeting.

Apr 12

The main benefits of TDD

For me, there are two main, long-term benefits of TDD (Test-Driven Development):

First, by using TDD (thus writing the tests first) you make sure that your code remains in a testable state all the time (even if you don’t write all the tests to cover all the edge cases) – As anybody working with legacy code can attest, adding unit tests to an existing code base is usually excruciatingly hard and takes a lot of time. It can be done – witness Working with Legacy Code, sure, but it’s a very long and thorny journey. You don’t want to go down this road with the new code you’re writing every day.

Second, by using TDD you always have a decent, highly decoupled design – not a perfect or insanely great design, but quite a usable design to go forward. More often than not, it will be a better design than you’re used to.

“Test-Driven Development” is actually “Test-Driven Design”.

Apr 12

Where does “thinking” and “design” fit into the TDD picture?

I very much enjoyed @unclebobmartin‘s generous talk at the Java User Group Karlsruhe last night. In addition to covering rockets, linear accelerators and small nuclear bombs as a means to overcome the gravitational field of the earth, he gave a great introductory talk on TDD and professionalism. Always a pleasure to be reminded on why we are doing TDD in the first place.

One of the questions which came up during Q&A – I’m paraphrasing here – was:

“I tried TDD and was told not to design or think, just to write the tests and the code. The result was a mess”.

Bob Martin’s answer was along these lines:

If you’re a TDD newbie, you need to leave your old rationale of thinking things through upfront behind. So the recommendation is “Don’t think about the design or what’s next”, but to methodically follow the mantra “Write some failing test” – “Write some code just so the test is satisfied” – “Write some failing test” – “Write some code just so the test is satisfied” – …. As your start to grok the rhythm of TDD, you gradually let your design skills in.

I would like to humbly elaborate on this answer. The practice of TDD consists of three simple steps:

  • Step 1 – “Red” – Write some failing test
  • Step 2 – “Green” – Write some code just so the test is satisfied (implement the simplest thing that could possibly work (not sure who coined the term, probably Ward Cunningham))
  • Step 3 – “Refactor” – Remove all duplication from both your production and your test code

Resist your urge to design upfront, to think through algorithmic solutions and alternatives. Just write a failing test. Then, write some code to make the test pass. Don’t write more code. Just the amount of code to make the test pass.

Now, turn to step 3. If you skip it, you will create a mess.

Step 3 is where your design skills are more than welcome. Apply your design skills to ruthlessly eliminate the duplication you created (and you did create some duplication because you did “the simplest thing that could possibly work” in step 2, didn’t you?) – Just keep in mind that you are not supposed to create a design which anticipates future requirement changes, you are supposed to ruthlessly eliminate duplication to create “the simplest design that could possibly work” for your current code base.

So there are a lot of design skills involved in TDD. It’s just that most of the design skills are applied “after the fact”. They are applied after you made the failing test pass.

There’s another place for design skills in TDD. Look at the first step – “Red”. You are supposed to write a failing test. You will probably need to instantiate an object (which, keep in mind, doesn’t exist yet). Or call a function or method (which don’t exist yet, either) on an existing object. You can apply your API design skills right there: What’s the best way to name the class or function? Which parameters do you need? How do you minimize the number of parameters? How do you make it easy for the test (and future users of the class / function) to accomplish the task at hand?

You aren’t convinced yet? You still need more places to apply your superior brain powers? Good news, there’s even more “thinking” involved. In step 1, you are supposed to write a failing test. This requires a lot of thinking:

  • What do I test next?
  • What’s the next logical step in the evolution of my method / class?
  • What are the edge cases I need to test for?
  • Which test will small enough in scope that I can cope with the implementation right away?
  • Which test will bring me closer to the solution of the task i’m working on?


If you follow TDD and apply your thinking and design skills as described above, you will end up with a testable, highly decoupled design. It’s not a great design yet, but chances are it’ll be a much better and more usable design than the ones you’ve encountered so far.


You may wonder why I didn’t mention the long and hard thoughts you need to think in step 2 while writing the code to make the test pass. Two questions for you: You did write some failing test, just enough testing code so the test fails, correct? Then you did the simplest thing that could possibly work to make the test pass, correct? Nothing more? Good. Go figure.

Feb 12

Softwerkskammer Karlsruhe, 6th Meeting

Finally, I managed to attend a meeting of the Softwerkskammer Karlsruhe, a group of software professionals dedicated to improving their craft. Todays topic was Flow Design and Event Based Components, a presentation graciously provided by Tilmann Kuhn. He gave a short overview of Flow Design and then dove into a sample implementation using Event Based Components in Java (a language I used to be more familiar with in the 90s). Java’s (and the associated frameworks’) verboseness aside, flow design and its implementation very much reminded me of Prograph CPX, a graphical data flow language of the early 90s. In order to close the daunting gap between the flow design’s graphical representation and its textual implementation an integrated IDE is (IMHO) essential.

Then, Hayati Ayguen presented his take of a flow implementation in C++ for signal processing. Terse. Brief. Very focussed on a specific use case – Signal processing. Just enough infrastructure to make it work efficiently. A wonderful contrast to the Java implementation – which does have its merits, don’t get me wrong.

A great and thought provoking evening. Thanks to the organizers. I look forward to participate in upcoming meetings.

[Update 3/2/12 – Fixed up an incomplete sentence – Looks like it was way to late Wednesday night (or I got distracted by the late night soccer game analysis on TV ;-)]

Oct 11

Thoughtworks Event, Frankfurt

Last night, Thoughtworks was hosting an public event @ Japan Center, Frankfurt – right next to the EZB and Deutsche Bank headquarters (I sure hope that those buildings were filled with busy & smart people working on setting things straight with the Euro).

  • 18:45 – Welcome by Nick Ashley, MD of ThoughtWorks Deutschland
  • 19:00 – Wolf Schlegel: “Dos and don’ts of Continuous Integration and Delivery”
  • 19.20 – Erik Dörnenburg: “Lean for enterprise architecture
  • 19:45 – Martin Fowler: “Software Design in the 21st Century”
  • 20:30 – Networking – drinks and food

Unfortunately, I missed about half of Wolf Schlegel’s talk on Continous Delivery, but judging on the second half, I would have preferred more in-depth discussion of technologies and best practices. The talk seemed like a space-station’s eye view of the topic.

Erik Dörnenburg was next talking about Lean Enterprise Architecture. I very much liked his analogy of comparing the role of a Software Architect to that of a Gardener instead of a traditional Architect. Spot on. Quite a few interesting thoughts on how to causing change in an organisation / team, too.

Martin Fowler gave two short talks, on on “Domain Specific Languages” and one on “Nondeterministic Tests“.

I was quite keen on the Domain Specific Language part, as we’re currently moving away from a “home-grown” Domain Specific Language for NC-code templating & output to a Python-based solution as we found that our own language lacked the expressiveness we are looking for. My key take-away was that there are two ways to create a DSL, external & internal and that we’re migrating from an external DSL to an internal DSL. Looks like the DSL book is supposed to be on my reading list real soon now.

Martin’s thoughts on “Nondeterministic Tests” were especially interesting as I was attending a talk on “Unit Testing & Concurrency” right last week in Karlsruhe. Very interesting to see the different takes on the topic – Abstracting away the concurrency altogether for unit testing purposes whereas Martin was leaning towards integration & acceptance testing and giving very sound advice on how to deal with concurrency issues within the tests (polling, callbacks, test doubles).

As you might have imagined, I mostly skipped the Networking part due to my sociophobia.

Overall, a very worthwhile evening and I very much look forward to future Thoughtworks events.