Friday, December 19, 2014

Between the lines

As coders we are constantly making decisions. This is what we do, this is what it`s all about. It is our job. Our decisions have a lot of impact. They affect all aspects of the software, the users that are going to use it, and even the company that hires the employees that are going to use it. And of course they affect our own and our company's reputation, what problems we face when we engage upcoming tasks, the success of the project, our co-workers mood and even our own mood in the future. Bad decisions can easily make us suffer.

What we do is not a routine, ever. We might have patterns, practices and problems that have already been solved. Yet still, every new decision that we make has a unique context. In fact the context changes everytime we learn and gain new experience. This is why we are engineers. This is why our work is very creative.

Sometimes we make good decisions, and sometimes we make bad ones. This is true for all types of coders from juniors to masters. Sometimes we make bad decisions because we just don't know any better, due to a lack of programming-, technology- or domainknowledge. And sometimes we make bad decisions because we are being put under pressure.

Bad decisions are expensive and dangerous. They produce technical debt, and it is not uncommon that they lead us to even more bad decisions. Slowly but surely this burden becomes heavier. It cost us time, energy and money. In extreme cases it gets so expensive that it would be favorable to completely start over.

Willingly or not, because of the decisions we make, we coders are in great power. We are leaders, and we can easily steer towards failure. We are not just the ones to write lines. We are not just code monkeys. We are the ones who design the heart of the Software and bear great responsibility.

When everyone gets mad because of a problem, maybe a date or even a deadline, we coders are the ones to stay strong. We are the ones to keep calm, and disillusion the others. We know the code, so we know the truth. If we don't stand up, whoelse should?

It is hard to act professionally and responsible at any time, but it's mostly a good choice. Thankfully, code is very forgivingly in its nature. Technology nowadays allows us to easily change it, thus allowing us to revert our decisions. We should value changeability in the code. We should even take action to improve changeability in the code. Maybe that'd be a good choice!?

I would like to end this post with a quote by @WoodyZuill:
Be the programmer you want to see in the world.

Friday, July 11, 2014

Improve your Feedbackloop with Continuous Testing

Have you ever though about what the most valueable thing in software development was for you? And im not talking about things that value for you personally, but for the success of the development itself. Well i have thought about it, and for me it was Feedback - in any form. It is so important, because it enables steering. Development practices are made for the purpose of better feedback. TDD, Continuous Integration, Iterations, to name only a view. Many of the agile methods and XP are basically about better feedback.

It begins with customer interaction. I need as much feedback as possible, as frequent as possible. If i don't get feedback, i'm likely to get on the wrong track, resulting in a product that is not going to be used, because it's not what the customer needed. The more feedback i get, the better the outcome will be. If i get feedback rarely, i am unable to steer. I'm forced to make assumptions which are likely just obstacles. The quicker i get feedback, the faster i can deliver value to my customer. Feedback allows me to steer.

Feedback is as important for programming. I want it early and often. If i write hundreds of lines of code without running them, they will most likely result in a very long and painful debugging session, and a lot of changes. I don't want that, so i take baby steps. They make me go safer, faster and happier. There are two phases that define my programming feedback loop.
  1. The phase where i write code. Lets call it alpha, like so 'α'.
  2. The phase where i evaluate my code, and eventually fix errors. Lets call it beta, like so 'β'.
You could also see those phases as modes. It is important to understand here, that these phases have nothing todo with the alpha/beta definition of a software cycle. I just invented them to describe my programming feedbackloop.In the following graphics you'll notice that the lines get shorter and shorter by example which is intentional and should point out how i got faster using new strategies.
When i first started coding, i did not write any tests. I wrote lots of code before i tried it out manually. Obviously it didn't work when i first ran it. I ended up in rather long α-phases, where i just wrote code, and also long β-phases, where i evaluated (got my feedback), and fixed it. Like this:



I was very slow back then.

I soon started with an interpreted language, which was very cool because i could run the scripts immediately. No need to compile or anything. Just write and run. It shortened my feedback loop, and i became faster overall:



Sooner or later i eventually started tdd. And regardless of the language that i was using, interpreted or not, it again shortened my feedback loop and made me go faster. The loop was shortened to a single 'unit', which is obviously smaller than anything manually executable. It allowed me to evaluate small behaviours, long before the program was even runnable. It is important to understand, that the α-phase in the following graphic contains both writing tests and implementation. The β-phase is much shorter, since unittests run very fast.


I thought this was just great, and it could not get any better. Wrong i was!! Later, i tried something that made me go like this:



"What the ...?" You might ask. No, i did not break space-time. The thing i tried was Continuous Testing. Which basically means, that i do tdd, but i don't run my tests by pressing a button and then wait. I just have them run all the time in the background automatically... Everytime i change my code, my tests immediately run automatically, and show me "OK" or "NOT OK" on a small icon on my screen. Since the tests only take about a second to run, this feedback is instant. And since my IDE saves my files onchange automatically, i do not have to press ctrl+s or anything. I just code... and as i code my files get saved.... and as the files get saved my tests get run... fluently, immediately. This is HUGE. I am now progressing without disruption. I completely broke out of the phases, or if you want to call them 'modes'. I love it.

I have used infinitest for this. It is a Continuous Testing plugin for Intellij/Eclipse. If you are doing javascript, i can also recommend grunt for Continuous Testing.

Tuesday, June 3, 2014

About the „Is TDD Dead?“ discussion

It did not take long after Agile died that TDD joined its party. If you havent noticed, David Heinemeier Hansson put up quite a rant against TDD on his blog leading to a lot of discussion - also on Twitter. Finally they ended up doing a live online discussion regularely featuring Kent Beck, Martin Fowler and David not (yet) involving the TDD advocate Robert C. Martin aka uncle bob. If you haven't watched it live, here is the initial 30min discussion of the series on Youtube. I really recommend the whole series.

I think this topic and the ongoing discussion is very valueable to our craft because it is the kind of questioning and critical thinking that evolve what we do and how good we are at it. Even if we have a strong faith in something, we should not be afraid to question it, ever.

I get davids points, however i do not entirely agree with all of his concerns. I want to share my thoughts in this blogpost.

„Test induced design damage“
A good design is a design that makes the software easy to change. I think this is something we all agree about. While TDD generally puts a lot of good pressure on your design, it can still make the code hard to change if you apply a high level of isolation, lots of mocking, and a high test-granularity. In this case refactorings and other changes will force us to touch a lot of test-code also. So i've come to the conclusion that its best to apply an individual level of test-isolation/granularity that suit the current requirements. Complex and/or long-lived software might take much value of a strict TDD approach, while simple and/or short-lived software might take more value of a more pragmatic approach. I've happened to experience lots of applications that were so big yet simple that "collaborating-units-tests" with reduced mocking and integration tests were just perfect. The value of this approach was that it was very easy to change/refactor production code without touching test-code. Still, the tests provided 100% functional coverage. So i think that design damage is not induced by tests or tdd, but by bad decisionmaking. Testing is engineering. Look for advantages, make tradeoffs. Trying to minimize mocking can definitely pay off. The advantages of a high test-isolation-level/granularity are
  • a very accurate fault-feedback,
  • and that every part of the code is executed just as much as it had to, leading to a faster test-suite

To Test first, or not to Test first
The point is, you do not want to verify if the code is working manually. You'd have to do it way too often, and it would just take too long. You want to be able to fiddle with the code, and do small changes frequently, without having to try everything out manually. You want to do it automated, and the feedback should be instant. So i see no point in 1. writing code, 2. trying it out, and then 3. writing a test. Why not write the test in the first place? Also, we tend to be very flaccid on writing a test for something that we have found to be working, because we tend to become euphoric about our success very quickly which makes us tired of digging in details. Other than that, the actual writing of the test first forces us to think about the problem to an extent that makes us recognize details, that we hadn't yet thought of. These details are better to be known before we start writing production code.

TDD is so widespread nowadays
I was laughing when i noticed that there are actually people who believe that everyone does tdd nowadays. Sadly, TDD, or lets say developer testing is in fact unused and/or undiscovered in many places. I've happened to see it missed in programming education and also software companies. Sometimes, it was even unwelcome by certain customers. If you were using any kind of developer testing in these places, you were a pioneer. There is still plenty of work to do on this topic.

The bottom line is, automated developer testing is good. We need it. We were silly if we didn't. The question is just: "How?". And this is where engineering comes in.