Tuesday, June 6, 2017

What role are your tests serving.

We had a discussion at work after watching the excellent Kelvin Henney talk about good unit tests. And it helped me clarify the many roles tests play and why people get a habit of complaining about their tests getting in the way. So here is the four categories a test is trying to balance:


  • Requirements
  • Regression
  • Documentation
  • Refactoring guide


Most test today are written as requirements. And this is a huge improvement over the past when we'd write tests later and try and get code coverage. Those 'later' tests are useless. The requirement tests happen for high level acceptance tests and in low level TDD too. Your test defines a behaviour you want. Once your test passes you don't go back to change it at all beyond some obvious cleanups like code duplication. These tests allow rapid development and reliable progress. But they can hinder refactoring, provide poor feedback on failures for regression and may be too implementation focused to be readable.

And easy correction is to make tests act as good documentation. Unit tests should explain component behaviour to other programmers. Think of it as the examples section in your book that any programmer is going to flip to and read first. Higher level tests can use BDD, tables or other techniques to create highly readable descriptions that can be shared with your product owner or customer. One thing you'll notice if you try and make unit tests act as good documentation is you'll want to avoid the london-style or mockist style test where every secondary object is mocked out. All those mocks heavily hinder the tests being a document as it shifts away from being an example of how the code runs on the product.

You may think all those requirements focused tests are all you need to cover the regression case. But for good regression tests you want highly informative error messages. I find those get introduced later when you start seeing such failures. That might be when a bug is introduced or a new feature makes old tests inaccurate. That's a good time to go back through those assert statements and make sure they give enough information to know how to correct it. As once corrected those asserts will benefit you ever after. There are also some frameworks that can help like the highly informative asserts from py.test.

Unit tests are your best guide for refactoring. So you want a complete suite of tests that run very fast. That way you can change a line of code and know within a few seconds if that change is okay. Higher level tests are helpful too in that you could replace an entire component (perhaps something custom with something off-the-shelf) and see everything still works. Can you replace your database with confidence? That's the kind of feedback high level tests can give to help refactoring.

So a single test can satisfy all four of these needs. But it doesn't need to so it's better to figure out where the focus is for the test you are writing at the time. Some tests might only be there for documentation. It's okay for tests to evolve to help refactoring only when you need that refactoring. But don't assume that once a test is passing that it automatically ticks all these boxes. It's just a check at that point.

Thursday, May 25, 2017

When Agile is not common sense

It's been about 8 years since I got my Agile training from James Grenning and started an Agile Pilot with my team. Right from the start I was super keen and got people practising TDD and Pair Programming even though I didn't really know if that effort would pay off. I just knew we had lots of problems with the old way so I wanted to embrace the new.

So I'd run my own little sessions with the broader team in Sydney sharing Agile concepts and ideas. Giving us a chance to discuss things and keep learning long after James had left. But often I would present new ideas and a few people in the group would respond "oh of course, that's just common sense". Initially I thought it was great as they were embracing these ideas as valuable even though it was not what we were doing before. But after a while I started to get frustrated because they we're not really listening. If some small part of a concept fit nicely with their "common sense" then they took that on and ignored the rest.

For example I'd point out that Agile asks us to plan regularly but to never put too much value into any plan. You need to be prepared to throw out your plan from yesterday because you learned something new today. "Oh of course, that's just common sense." But what I'd observe is they didn't re-plan regularly, they would just stick to the old plan unless something was clearly going wrong, and only then would re-plan in an attempt to react. They didn't adopt the new idea as they didn't understand that it's about being proactive. They didn't understand the value in making continuous minor adjustments or even just discussing how their understanding has shifted over time.



So I did a presentation to them about when Agile is not common sense. Put out the ideas that clearly challenged their old thinking and through that made my case that they allow other ideas to challenge them too. My list has grown over the years and it's still something I refer to when I feel people are being to complacent.

TDD
We all understand the value in having tests. But writing a test before there is any code? Writing a test before we have a clear picture of what we're building? TDD should challenge the way you learned to program.

Pair Programming
Two heads are smarter than one. But we all assume it'll be the same speed as just 1 person so under value the benefits. But in studies we find that, with practice, the speed increases by quite a lot. Most of programming is not typing it's thinking about the problem. The same is true for creating tests in that typing is a very small part of the time spent. With practice we see pairs operate at about 1.8x the speed of an individual while also having 50% fewer bugs.

Mob Programming
See pair programming

No Estimates
Estimates can be a dysfunction. Is someone asking for a completion date or trying to figure out a cost, plan a release or looking for a deadline to enforce. Move the conversation away from estimates as much as possible.

If something is difficult or error prone then do it more often
Teams will often avoid doing a minor release due to headaches in the release process. A good coach will then insist that releases be daily until release issues are resolved. It applies to many areas where we avoid facing issues rather than fixing them.

Maximise the work not done
We want to work on a prioritised list so that we can avoid doing things that have little value. Sure the customer says they want A, B & C but if C will help them immediately then do that and give them the software before working on A & B. You might find out that with C fixed that B drops from being the second most important feature to no longer being required.

Safe to fail
Encourage teams to challenge themselves and occasionally fail. If the team never fails then how do you know they are actually trying to improve? If treat everything as so important you cannot risk failure then you do not allow improvement. So you are not allowing teams to operate at their best when you demand only the best.

Having a detailed and complete test suite allows quicker changes to your code
Many with only a little experience at writing tests would disagree. The tests break in confusing ways. Changes to the software trigger many required changes in the tests. But really that's just changing code with poor tests that are too tightly coupled and fail in bad ways.

That's my list for now. As an aside it's worth remembering that common sense is cultural and really just wraps up a lot of assumptions we share. I do this contrast more to challenge people's thinking than really seeing a lot of value in something being common sense or not. When we start thinking of something as common sense we assume others know it and that's an unhelpful assumption.

Thursday, May 11, 2017

Applying the Toyota Kata

Last year I got to attend a workshop on the Toyota Kata by Hakan Forss and I could immediately see how it could be useful but I didn't have an obvious place to apply it until recently.

So what is the Toyota Kata? I see it as an alternative to retrospectives. It lets you define a collection of goals and run experiments to see if you can get progress towards that goal. Unlike retrospectives you can define goals that may seem distant (release to customers on every passing commit), may be simply something you want to maintain (have zero bugs in production) or be impossible (have zero wait time in moving a story from backlog to done). Once you've built this collection of measurable goals you decide what you're going to try and your expected outcome (we will to TDD and have 50% less bugs in production). You can define what the period is before you check in again and decide on the next step. But as with anything Agile; shorter is better. You can work it into a normal two week scrum cycle or if improvements are important enough then spend a small time on it every day. Next time you get together you can assess how the experiment(s) did and what you want to try and do next.

I really like how it's focused on doing small experiments rather than committing yourself to something to fix the problem immediately. Especially for those big issues it frees you up to try anything because you'll know soon if it helped and can try something else. With normal retrospectives it can be hard to get people to conduct experiments.

So my team recently went from doing 2 week sprints to a Kan-ban style flow of work. I had some concerns that it could lead to a range of problems and wanted it to be a positive change, So we figured out some measurable goals where we wanted improvement and things we to maintain. The improvement ended up being focused around cycle time as I felt sprints encouraged us to get things done because a sprint was ending even though it's an artificial deadline. If a task lasted more than a sprint we were able to quickly see it as an issue. Other measures were around velocity (measured in weeks instead of sprints) and team comfort (do they like the change or would they rather go back).

So far things have been great. Our cycle time is getting better and everyone is comfortable with the process. It's not a clear winner where people love the new process over the old. And our goals for cycle time seem lofty compared to what we ended up measuring. But it's given us a structure to keep experimenting and keep chipping away at these things. I absolutely would recommend it to anyone facing issues they feel cannot be resolved in a normal retrospective cycle. It can compliment or replace retrospectives as you see fit.

Wednesday, May 10, 2017

So I've been advised to create a Coaching Manual

I'm trying to build up my skills as an Agile Coach. In a way I've been doing this already now for about 8 years. But it's getting a bit more structure and organisation.

The way I see it learning is part of software development. It always has been. Some people get comfortable with their knowledge and workload and stop learning but that has never been me. When I get too comfortable I start looking for something else to do.

But my learnings are just a jumble in my brain. Sometimes it impresses me as I can pull out a name, a quote or apply a process to something specific. And sometimes it lets me down so I have to revisit and revise like I'm doing right now. I'm listening to Esther Derby talk about her Six Rules of Change and writing this at the same time. Not something I recommend but I just want a refresher as I've studied it before. I'll probably grab the slides later and use it as part of a mini-presentation. Sorry you just ran into my jumble.

What I'm trying to say is it's time to organise that jumble into something written. And the best place I can think of to write it is here. So I'll try and every week regurgitate something out of my head and into words. Usually it'll be referencing someone else smarter than me rather than anything terribly unique. But that's okay as it'll form a nice reference I can go back to for myself.

Thursday, January 5, 2017

Things I’ve learned from running lean coffee and why you should organise one too

I’ve been running a 30 minute lean coffee session in my workplace every two weeks for 18 months now. Our first meeting for this year is tomorrow. I started the sessions when a bunch of people from work went to the Agile Australia conference and we wanted people to keep sharing ideas and other learnings. Now I invite any software developer in the building so my invite list has grown to 99 people but I typically only get about 10.

How lean coffee works: A few people from work got to take part in one at Agile Australia but I missed it myself. So I just got online and read everything at http://leancoffee.org/ I grabbed a bunch of index cards and texters and was ready to go.

I feel it’s super important to my company as it’s the only time people from all the software development teams can meet each other and discuss things. It’s helping break down walls between teams and helping ensure learnings can spread to other teams quicker.

  • Location matters. I started off in the building’s cafe but it would get too noisy when the coffee grinder is going. So we moved to another table in the entryway. I like that we’re highly visible but also in a casual environment. I find meeting rooms too formal. I also like that there are lots of tables so I can split the group up on demand.
  • I setup up one table for the discussion and if that table gets full I ask someone with experience to help run that table and move to a new one. I try and split like this once we hit 8 people. Timing of topics is done on a phone so anyone can do it and once someone has come a couple of times they know the routine and can run a table that has already been setup.
  • I am always prepared to throw in a topic to get things started. I especially like light hearted subjects. Last time my card was “How would Santa write software?”. This is extra useful when I’m going to leave a table to setup the next one.
  • Be a good host and facilitate the discussion. If you see someone get cut off ask what they were going to say at a later moment.
  • Take notes. You never know when you’re going to learn something. But also you might get useful feedback for the lean coffee at unexpected moments. Who else should I invite? What’s a good topic for next time? Do we need to change the location? The time?
  • I run mine for 30 minutes as it’s pretty hard to get people to leave their desk when I’m not supplying lunch. But at 30 minutes we are lucky if we can get through 4 topics. You could do it an hour but I think the energy and attention would quickly drop after that. Also I host mine in the morning as I find it easier to get people to make time just before their standup meetings.
  • I only get a few people attending. And that’s okay but I try and push to get people from different teams coming. It’s all about sharing information and if it’s only a couple of teams then there is a huge part of the company we’re not hearing from.
  • Encourage people to bring coffee and tea. I like the casual feel it helps add.
  • I use index cards instead of post its. I find it works better on a flat table and means I’m less likely to have a texter bleed through and mark the table.