Jon Kruger -
  • About Me
  • Blog
  • Values
  • Presentations
About Me
Blog
Values
Presentations
  • About Me
  • Blog
  • Values
  • Presentations
Jon Kruger
Agile

Know what you’re building

If you set out to build something, you need to know what it is that you need to build. That’s just common sense, right?

Unfortunately a lot of companies struggle with this. It usually starts with requirements that don’t have the level of detail that they need in order to cover all of the edge cases. That leads to developers getting frustrated, guessing at the requirements, and low morale, among other things. In my opinion, this is not that difficult of a problem to solve. Here are some steps that might help:

Define the scenarios

As a developer, don’t start working on a feature until you can specify all of the testing scenarios in the Given/When/Then format.

Given I am a logged in user
When I go to the new order screen
And I try and purchase an iPhone
Then I should see a message saying that I’m eligible to buy a phone at the promotional price
And I should see a date when the phone is expected to ship

There are multiple reasons to do this. First, someone is going to have to test the feature at some point. You might as well define all of the test cases before you write the code. Otherwise you will have to guess what it is that you’re supposed to build since the QA team is going to define what “done” means. Figure out what “done” means ahead of time, and then you should have all the information you need to build the functionality with no bugs. Not only that, the QA team will be able to complete testing on your item in very little time (they’ve already written the test cases, and they won’t find a lot of bugs).

Second, do it for your own benefit. If you have Given/When/Then scenarios written out, you can easily turn that into unit tests. You can easily break the work down into smaller tasks. It also forces you to think about edge cases, design, and testing at the beginning. Now you have a good idea of what steps you need to take to build the functionality, it will be easier to write tests for everything, and you’ll know when you’re done (and how close you are to being done). You won’t get to the end and say, “I hope I thought of everything.” Sure, you might still miss something, but you’ll be a lot more confident that you didn’t.

It’s amazing how much longer it takes to develop something when you don’t have things broken down like this. It’s like you have to keep track of more things in your head, so you don’t think as fast. It’s much easier to take Given/When/Then scenarios and make them work one at a time.

Take time to design

A common misconception about Agile methodologies is that Agile does not place any importance on planning. Most Agile methodologies don’t approve of documentation for documentation’s sake. People therefore associate “design document” with “ZOMG WATERFALL RUN FOR YOUR LIVES!!!”. On my last project, my team lead had me write a design document for a feature I was going to work on and then we were going to discuss it together. The purpose of the document was not to check off a box or fill up a binder with stale technical details, the purpose was to help me think about the design. I was amazed, as I wrote everything out, I thought of all kinds of things that I hadn’t thought of before. It was an extremely valuable experience.

Agile says that we aren’t going to do big design up front, but that by no means implies that we should start working on a feature without having it defined! You may not have all of the details about what you’re going to build next week, but you definitely have to define what it is that you’re building right now. Agile does not encourage spotty requirements, in fact, it’s just the opposite. We want to have the requirements defined so that we can all agree on what the business needs and then write code with automated tests and no defects. Planning and design are not optional.

Hold your ground

If you have bad requirements, I think the buck needs to stop with the developers. The fact is that you can’t build something if you don’t know what it is that you need to build. If you know 90% of what you need to build, you can build 90% of it, but you can’t complete the feature. When this happens, you start getting a lot of bugs because no one (yourself included) thought of everything that needed to be considered.

So next time you have requirements that aren’t complete, don’t just start developing. Work with the BAs, QAs, business people, or whoever else needs to be involved to get everything defined. Once you start working on it and they see work getting done, people will assume that everything is OK when it’s not really OK. If you focus on getting all of the questions answered first, people might be more focused on getting everything defined because they’ll know that you’re blocked.

Sometimes you might have enough of the requirements that you can start developing. This is fine if you only have minor questions unanswered (“What should this error message say?”). You just don’t want to get in a situation where you’re getting stuck, you’re having to guess, or you’re having requirements changed on you because people are still thinking about the design.

Use your card wall

If you have swim lanes on your card wall, create columns for “In Analysis” and “Ready for Development” (or some similar wording). Don’t put anything in “Ready for Development” until the requirements are complete. Do the same thing in your work item tracker. We want people to be aware that there are still things to be done to define the requirements. If BAs see that, they will want to do what they need to do to get the feature out of that status and into “Ready for Development”. It also gives developers a visible way to say, “No, I need more definition before I can start developing.”

Use some tact

Please, please don’t go blasting your BAs, users, product owners, and everyone else who is not a developer. These people are trying their best (usually), but as a developer you have a different perspective on things. Your perspective is important, but so is theirs. Quit treating your users like “stupid users” and try to understand where they’re coming from, and help them understand where you’re coming from.

I’ve written plenty of requirements and it doesn’t feel good when a developer mocks the requirements that I just spent the last two days defining. Sure, I missed stuff. But no one appreciates getting put down when they’re working hard. Work with them to fix the problem, but use plenty of tact.

Be a coach

Writing code might be your primary job function, but you can also be unofficial coaches and help the rest of your team define good requirements in a way that will enable you to succeed. It’s in everyone’s best interest (yours included) if you try to collaborate more with people on your team. We like things in Given/When/Then format because we can easily write code against deterministic scenarios like this. It’s good for us if we have the test cases defined up front because it helps us know what to build. So if we can teach BAs how to write requirements this way and we can teach QAs to work with us to help define test cases before we write code, then everyone will win.

October 24, 2011by Jon Kruger
Agile

Implied metrics

In my last post, I talked about the kinds of metrics that I don’t like. But sometimes even good metrics can go wrong.

When I worked for a previous employer, we used “load sheets” on our Agile card wall. These were pieces of paper divided into 10 blocks (10 days in a 2 week iteration) and then we would cut out cards for the features that were sized to take up as many blocks as the estimate (so a 3 day estimate card would take up 3 blocks). We would use different colored dot stickers to indicate when we had discussed the requirements, discussed the design, completed the development, and when QA was complete. Each developer on the team would have one of these sheets on the wall, so you could see who was working on what and where we were pretty easily.

Load Sheets

I didn’t come up with the system, but I’m guessing that they designed it for at least two reasons (probably more than that):

  • Anyone can come and see what we’re working on and what the status is of a particular feature
  • We would meet with the project sponsor every other week and they would pick out features for the next two weeks, and the differently-sized cards gave a good visual representation of the cost associated with each feature

This system did an excellent job of both of those things. The problem is that the development team interpreted it in a completely different way.

When the developers looked at the sheets, these are some of the things that they thought:

  • The most important thing is for me to get my features to QA in the estimated time
  • Completing my tasks in the estimated time is important (more important than things like writing tests or helping other developers, because there are no metrics for those)
  • Completing my tasks this iteration is more important than helping others complete their tasks (even if helping someone else would be better for the team). This indirectly discouraged pairing on tasks.

As a result, the following things actually happened (I’m not making this stuff up):

  • One developer segregated himself from the team and focused on completing as many features as he possibly could. He did a good job of staying focused and he did get a lot done, but there was little collaboration or design discussion and virtually no unit tests. He used his productivity metric to ask for a raise (because he was completing twice as much work).
  • Developers would work on features, and as soon as the estimated time passed and they weren’t done, they got openly flustered and complained about the estimates being wrong (which was correct), and focused on getting it done instead of getting it done right (which led to technical debt).
  • Developers would get the work most of the way done and then say it was done, saying, “It’s far enough along that QA can take a look at it and let me know what’s wrong.” (That way they could move on to the next task.)

Whoa, what happened?!? I’m sure this wasn’t what the people who came up with this system intended. But that’s the problem — while the system provided a lot of positive benefits, it also indirectly encouraged individualistic behavior and cutting corners and discouraged collaboration because of implied metrics. I was leading the team, and I wasn’t going into TFS and spitting out reports to compare developers, and I wasn’t tracking who was completing tasks within the estimated time, because it didn’t matter at all. It didn’t matter what I was or wasn’t doing — the data was being tracked, so developers assumed that something was (or could) be done with it. (I’m not using this example to criticize the people who came up with the system, because no system is perfect, and there were many very successful projects completed using this approach.)

What could we have done differently? We could figure out what message we want our card wall to convey to the developers and structure it that way. For example:

  • I care much more about how much the team accomplishes in an iteration than how much each individual developer gets done, so don’t organize the cards by team member (if you want to write developers’ names on cards, that’s fine, just don’t organize them in a way that it’s easy to compare developers).
  • I care much more about a feature being done and ready to be deployed than I care about when a developer hands it over to QA, so instead of measuring how long it takes developers to complete their first pass at development, I’ll measure how long it takes from the time we start working on a feature to the time that it’s ready to be deployed. We need to break down the traditional silos of development and have BAs, QAs, and developers work together to achieve one goal.
  • I value communication and collaboration, so when I’m talking to the team, I’ll emphasize working together, being willing to help each other out, pairing, and things like that. I don’t want developers to think that they should be smart enough to figure something out when they’re stuck, I want them to ask for help and I want people to solve each other’s problems.
September 14, 2011by Jon Kruger
Agile

Metrics, and why I usually dislike them

Every team, company, and IT department wants to collect metrics these days. Sometimes metrics can be used for good purposes (e.g. are we on schedule), and some can be used for bad (e.g. let’s come up with some way that we can attempt to quantify how good our teams are so that we can compare them).

Let’s just get this out of the way — I really dislike metrics when they are used incorrectly. I think metrics are a good way of measuring your own progress internally. For example, I want to know if I’m on schedule to meet a target date. If the team is estimating work, I want to know how the actual time spent on the features compares to the estimates so that we can get better at estimating. I want to know how much time team members are spending on different activities (e.g. requirements gathering, development, production support) so that I can make future plans and staff the team accordingly. I might want to measure cycle time (the amount of time from when we start working on a feature to the time when the feature is deployed or ready for deployment). In all of these cases, two things are true: I’m not publicizing the metrics outside our team, and all of the metrics are measuring the performance of the team, not the performance of individuals.

I may use the metrics in order to know what message to send to a project sponsor. For example, if I can determine from our metrics that we’re ahead or behind, I would let the project sponsor know how ahead or behind we are. I might use cycle time to come up with a date when we think we can have a feature completed.

What I don’t want to do as a team lead is share any of the raw data with the people above me (unless I can trust them). Why? Because I don’t want to give them an opportunity to misinterpret the metrics and manage my team for me. If I’m leading a team, it’s my job to lead the team and it’s the team’s job to deliver. Too often, the higher-ups will use metrics in the wrong way.

This is what happens when your manager comes to you and says that you have to cram in some extra scope and cut out testing. They saw a metric (time for a developer to complete a feature) and made a decision based on it. They essentially are saying that “development time” is the most important metric, when in reality, what’s more important is the time to do all of the work (requirements, development, and testing). They are stepping in and managing the team and choosing a metric that you gave them (a development estimate).

This is why you have to choose your metrics wisely. What if you gave estimates to your project sponsor in terms of how many person-hours it takes? Let’s say that feature X will take 4 hours of BA work, 2 days of development, and 1 day of testing. In the end, that means that 3.5 days of people’s time will be needed. You probably know how much available BA and QA capacity you will have just like you know how much development capacity you will have. So why not portray it as one big bucket of capacity? Maybe you still break down the time and give that estimate by role. You run the risk of the sponsor trying to lop off the testing, at which point you have to earn your salary and explain to them why you need that much testing time (we wouldn’t say that we needed it if we didn’t need it, right?). If they don’t make QA people available to you, then use developers or BAs to do the QA. Either way, you need 3.5 hours of people’s time to do it.

Notice what I did differently — I gave a whole-team estimate. I didn’t just say how long it takes to do the development. That opened the door for your project sponsor (who probably doesn’t know how to manage your team) to staff the BA and QA team for you.

To me, the kinds of metrics I want to expose outside my team are things like features delivered, money saved/earned for the company, and things that show business value. Ultimately, this should be what matters to the business. These aren’t always easily quantifiable (which makes it difficult), but this should be what project sponsors and executives should ultimately care about. In fact, I would keep a list of achievements that you know have business value and report that up. Your project sponsor/manager would love that because they’ll turn around and report those same things to their boss. Now you’re speaking in the language that they should be caring about (cost savings, business value), and you’re free to manage the team the way that you know how.

September 6, 2011by Jon Kruger
Agile

Corporate frameworks and corporate standards

Most IT departments manage multiple projects and applications. As you go from project to project, you inevitably will find better ways to do things. Then at some point, someone might decide to get the smartest people together and come up with the one corporate framework to rule them all. All future projects will use the new framework, which makes sense because we’ve taken all of our good ideas and combined them so that other developers don’t have to go down the wrong path. I’ve had this idea before, it’s a great idea, right? We’ll have less risk of failure and we won’t constantly reinvent the wheel.

Companies think that by doing this, they will reduce the risk of failed projects. But they are buying into two things that are fundamentally incorrect — that they won’t be able to ever come up with a better way of doing things and that all projects are the same.

Ultimately what is lost when corporate standards are mandated is innovation. Developers are smart people, and many of them are trying to find new and better ways of doing things. If you don’t encourage them to find a better way, either they’ll quit trying, feel defeated because they can’t change things for the better, or get upset that the process is hindering them from getting things done better or faster.

Also, all projects are different. I’ve been on many “agile” projects, and every one did things differently. This is good because working on a two-person team at a startup is much different than working in an enterprise IT shop. I heard of one company who was trying to do an “agile transformation” so that they could find a methodology that they could standardize across the enterprise. It’s great to see people adopt agile practices (which are generally good), but trying to “standardize” so that everyone has to do things to same is directly opposed to the agile idea of continuous improvement. (Often times, the standardization of methodologies is mainly done so that common metrics can be established by which to judge teams, which encourages teams to game the system to make their metrics look better instead of solely trying to provide business value in the best way possible.)

The Alternative

What if instead of mandating that everyone used the same corporate framework, we encouraged teams to come up with the best way of doing things and then share them with other teams so that they can adopt each others’ best ideas if they so desire?

What if instead of mandating a framework, we created a repository of random pieces of code that people could pick from to do common tasks (e.g. an authentication library that authenticate to some corporate server)?

What if we stopped being obsessed with metrics and measuring teams and just went out and got the best developers that we could find, and then gave them everything they needed to do an awesome job?

August 19, 2011by Jon Kruger
Agile

Getting the most out of your Agile card wall

One thing that you’ll find on pretty much every Agile project is some kind of card wall where features are tracked.

board

When I started working on Agile projects several years ago, I didn’t quite understand the purpose of the card wall. I thought, wouldn’t you rather just track everything in some online tool?

While tracking things in an online tool is still a good idea, the Agile card wall gives you a level of transparency that it’s difficult to get from an online tool. With a good card wall, you can easily see what everyone is working on, what still needs to be worked on, how long the remaining work might take, and what’s blocking your progress. There is so much to keep track of on a software project, and it really helps when you have a visual aid that can help keep everything in front of you so that you don’t have to juggle everything in your mind (or some online tool).

The trick is to tweak your card wall to give you the most transparency as possible. Here are some things that I’ve found help me get the most of my card wall.

Everything is a task

Everyone puts development tasks on their card wall. However, not everything that your team does could be categorized as a deliverable feature. In fact, there are lots of other things that you might have to do:

  • Write up documentation on a wiki
  • Onboard a new team member
  • Set up a CI build
  • Get ready for a demo

These are all tasks that are completed by development team members that take a measurable amount of time. So why not create a card and put them on the board? Maybe you use a different color card to indicate that it’s an internal task. This gives you two benefits — you know what people are working on and you can use the estimate to gauge how much work is left to be done.

Make card walls for your entire team

If our development card wall can help us track what developers are working on and how much work is left, why not create card walls for the entire team? You could have a card wall for BA requirements gathering, QA creating test plans, project management tasks, or some mini-project that you want to track separately. You get the same benefits that you get with a development card wall — you know what people are working on, you can easily see the status of the effort, you can prioritize the backlog, and it can help you get an idea of how much work is remaining.

Make problems obvious

Your card wall should alert you to any problems and blockers as soon as possible. As a team lead, your job is to try and remove any blockers and constraints that could keep your team from being able to do their job. Some ways that you can do this:

  • Create a separate section of your card wall for blocked items
  • If something is blocking a feature, put a post-it note on the card and write what the blocker is
  • Structure your card wall so that you can see problems immediately just by glancing at it

Let’s look at some examples of some simple card walls and we’ll interpret what we see.

Example #1

board
In this example, we can easily see that we are either developing things faster than we can test them, or things are getting stuck in testing due to bugs. We may need to assign more people to testing or work on reducing bugs.

Example #2

blockers
There are a lot of features that are blocked. We should try and address the blocking issues and look and see if there is some greater problem that is causing things to get blocked. Maybe we need to write better features, or maybe we need to get more time from people in the business who can answer questions.

Example #3

no-backlog
We don’t have much in our backlog, so the developers are going to be out of stuff to do really soon. We may need to get more people working on requirements gathering.

Example #4

good
Things are flowing pretty smoothly. We have a good sized backlog, no blockers, the work is evenly distributed, and we’re getting a lot done.

The key is that we want to see problems as soon as possible so that we can take the necessary steps to correct the problem and keep things moving.

Address technical debt as part of the process

As much as we hate to say it, sometimes we are forced to shove in lower quality, untested code in order to meet a deadline. I don’t like having to do this at all because of the risks, but when this happens, keep track of all technical debt that will need to be fixed and create separate cards for fixing it. Make these cards a different color so that they stick out. Then use your board to explain to your manager or project sponsor that you’re going to need some time to go back and fix the technical debt. Many managers want to pretend that the work is done once you release and will convince themselves that they can just move on without addressing the technical debt. You know better, and it’s your job to state that case and show why it’s important.

Refactor your card wall

Your card wall is yours. You create it, you manage it, and it belongs to you. Don’t be afraid to rearrange and refactor your card wall so that it can better meet your needs. Don’t make excuses like “we’ve always done it this way” or “we read a book that said to do it this way” or things like that. Your process and tools need to serve you not the other way around.

January 6, 2011by Jon Kruger
Agile

Adapting Agile to the real world

Pick up a book on Agile practices and you might find a wonderful, yet often unrealistic view of a perfect world where everyone buys into Agile practices throughout the business and you glide gracefully down the road to success.

The problem is that for most of us, that perfect environment doesn’t (and will probably never) exist, and that’s OK.

Maybe your team isn’t staffed the way that it needs to be. Maybe the people on your team don’t have the right skillset (yet). Maybe you have to integrate with lots of other systems, so you have to do a lot of up front planning and design so that you can make sure everything gets done on time.

The point is not to implement 100% of Scrum or XP or Kanban or some other methodology. I like to boil Agile down to this:

Do more of what works and less of what doesn’t.

Implementing 100% of XP may not be the best thing for you, or it may not be feasible. That’s not XP’s fault, they’re just giving you a set of best practices to work with that have proven to work well for some people. It’s up to you to make it work for you. Frankly, I don’t think it matters if something you do falls in the category of “Agile”. I just want to find ways to improve the development process, regardless of what you call it.

One practical thing that we all can do (whether we’re in charge of a team or not) is to try to improve our development process every day. Try to find ways to do more of what works and less of what doesn’t, improve processes and communication, and help your team succeed. Set your sights on the end goal and start taking steps in that direction.

January 5, 2011by Jon Kruger
Agile

Thoughts on pair programming (and when it makes sense)

Pair programming is a development technique used in Agile software development techniques like XP. Lots of people I know are big fans of pair programming, and many teams have everyone pairing on pretty much all coding activities. I’m just wondering if this is really the best way to do things in all situations.

To be fair, I’ve never been on a project where we paired all the time. I’ve paired off and on for various things. So I can’t really present the argument from the side of someone who pairs on everything.

There are many obvious benefits to pair programming, as you could imagine.

  • Onboarding a new team member
  • Senior developers pairing with junior developers
  • Working together on something particularly challenging

I’m not debating the value in this kind of thing. I’m just questioning the value of doing it all the time on everything.

I’ve asked a lot of people who pair a lot why they find it to have so much value. I’ve heard various answers, some of which I’m not sure I agree with.

The hard part of programming is figuring out how to do something, not the actual typing part.

This may be somewhat true… but to what extent? For most features, I usually sit down at the beginning and think about how to design things at a high level (and often discuss it with others). This certainly is the hard part, but once we figure it out, then I have to plug through the work and get it done, and doing this design doesn’t usually take that long. At that point, I see less benefit in having someone else there watching me, especially when I’m doing mundane tasks like HTML layout, setting up test data, etc.

Pair programming is actually faster than doing tasks individually.

In order for this to be true, that means that at least 50% of my time spent doing a task individually is wasted time due to bugs, rework, getting stuck, time spent figuring things out, etc. I don’t doubt that two people working together end up with better quality code in less time. But how much better? And can you honestly say that two of you can do it in half of the time compared to one of you doing it individually? Maybe in some cases this is true, but I would think that more often this wouldn’t be the case.

There are diminishing returns to pair programming. What I mean by that is this: if you and I paired on the same project, over time we would both learn the system better, we would start doing things the same way, we would design code better, we would learn new tricks and techniques from each other, we would work better with our team, and we would become more disciplined about writing tests and not cutting corners. But as time goes on, we would also be getting better at doing these things individually. We would be able to design things better individually, we would learn to be disciplined to write tests, and we would get better and doing things right the first time.

What if we were already able to understand how to design things correctly, we were already disciplined to write tests and not cut corners, we already communicated well and were team players, and we were better at development in general? In that case, I feel like pair programming makes less sense because the value we’re getting with pairing over individual development would be less.

On every project there has to be some balance between speed and quality. On one end of the spectrum you have startups who have to ignore quality and things like automated tests to just throw something together that seems to work so that they don’t lose their funding. On the other end you have some mission-critical project like a nuclear power plant or a pacemaker that can’t afford to fail. Those mission-critical projects need higher quality, but that comes with a lot of extra cost. Somewhere is the middle are our projects.

Obviously quality is very important, and if you know me you know how much I am a fan of TDD. But TDD, pairing, and anything else needs to be justified in terms of cost (both short-term and long-term). Is what we’re doing worth the time that we’re going to spend on it? The code has to work, that’s not negotiable. But since we have a finite amount of time to finish a project, we can only sacrifice so much speed in order to make sure we have quality.

When it comes to pairing, there are a lot of factors that need to be considered, namely how difficult your project is, what the business problem is, who is on your team, how experienced they are, and so forth. I’m not saying that pairing is bad in all situations. I’ve seen it work very well on several different projects, and like I said earlier, there are places where it definitely fits.

Now I am a proponent of having all code agreed upon by more than one person. You could do this with code reviews, pair programming, or assigning features to two people (who will spend time agreeing on the design, but won’t necessarily sit at the same machine and do the work together). I just want to make sure that we don’t have to waste time due to rework. I also emphasize to people that if they get stuck on something to please please please ask someone for help instead of trying to be a hero and spending a whole day trying to figure something out just because they feel like they should be smart enough to solve it on their own.

Again, I’m not saying that all pairing is bad, or that if you’re pairing on everything on your project that you’re doing it wrong. My whole point in this is that I think we need to evaluate each situation and decide how we can best deliver a solution with a sufficient level of quality in the least amount of time possible. Maybe that involves pairing, but maybe not. But I think we have to at least ask that question.

September 21, 2010by Jon Kruger
Agile, TDD

A TDD success story

In a month or so, my co-worker and I will be wrapping up the project that we have been working on for the last 15 months. It’s a website for a company in the construction industry that bids on jobs and then tracks the progress of the jobs, purchase orders, billing, and everything else they need to run their business. We used ASP.NET MVC, Fluent NHibernate, AutoMapper, and SQL Server 2008.

We practiced test-driven development from day one. We wrote tests for our .NET code, tests for our JavaScript code, and tests for our SQL code. Right now we have over 14,000 tests, and I think we can break the 15,000 test barrier in the next month. I can run them all in about 5 minutes.

I cannot tell you how invaluable these tests have been. First of all, our application deals with money. The users will input a bunch of data about a job and then our application will tell them how much to bid on the job. We cannot afford to have bugs in our code that would miscalculate the amount to bid on a job, because that would lead either to over-bidding (in which case they would win very few) or underbidding (in which case they would win jobs and take a big hit). It just has to work.

Second, we did not have a QA team on this project, it was just the two of us developers. Frankly, I don’t have time to go back and manually test stuff in the app or regression test it when we need to make a change and deploy something. We do have bugs from time to time, but we haven’t had any critical bugs.

Because of our tests, we have been able to get as close to continuous deployment as I would feel comfortable with. On average, we deploy 2-3 times a week. When we go to do a deployment, I usually go through the site and manually test the new features that we are about to release. If I don’t find any problems, I run our deployment (which is all automated), and 5 minutes later, the changes have been deployed. I never go back and regression test old features or stuff in areas that we didn’t change.

Since the whole test and deploy process takes only about 15 minutes, users get their changes quickly. They don’t have to wait until later in the week, or until our next scheduled release. We have reduced the cost of change to pretty much just the time that it takes to code the changes.

All of this is possible because we were diligent about test-driven development and writing good unit tests for everything. The reason that we don’t spend time regression testing is that we don’t expect anything to be broken, and it very rarely ever is. This means that we can spend more time delivering business value and less time ensuring that we didn’t break something we wrote a year ago.

I’m not writing this to say how awesome we are as developers, because anyone can write tests and have the same kind of success. Also, we could’ve cheated and not written tests and ended up with potentially costly bugs and more time spent regression testing.

This is why I practice test-driven development. You end up with well-designed code, you drastically reduce bug counts, you can release more often, your codebase stays under control, and you have a lot less stress.

August 1, 2010by Jon Kruger
Agile

Done means Done

One of the commonly held principles of Agile is that you build software incrementally. I know a lot of you have heard this and think you understand what it means, but are you actually living it out?

Here’s what I mean: as a developer, when you say that a feature that you’re working on is done, are you sure that it meets all of the requirements? Have you accounted for all of the edge cases? Is it production ready code?

If you answered anything other than “yes” for any of those questions, then I would question what the word “done” means to you. “Done” does not mean that you’ve coded it to work in most situations and that you’ll rely on your QA team to find bugs for you to fix.

The problem is that when other people hear you say “done”, they will assume that you really mean done. This is especially true with business people and management. In their world, done means done.

There is really no point in not using the same definition of “done” as business people, because they’re the ones paying for your project. So when you come back to them and say that you need a few weeks to just fix bugs, they’re going to give you weird looks. “Wait, I thought you said that was done.”

Before you even start developing a feature, sit down with your BAs and QAs and define what “done” means for this particular feature. Think of all of the requirements, edge cases, and non-functional requirements (like how fast it should load).

Now you start coding. Write unit tests first that will prove that your code will fulfill the requirements. Then write the code to make the tests pass. Then go through the requirements and manually test it to make sure that you got it all right (you can’t easily write a test to see if you got your CSS right, or if the page loads fast enough). If you have to, refactor your code so that you don’t have any hacks or technical debt. Now you hand it off to your QA team. You should expect that your QA team will find no bugs in your code. Maybe they will find bugs (because you’re not perfect), but that will be the exception instead of the norm. You should think that your code is ready to go to production.

Now you can really say that your feature is done! My definition of “done” is that there is no more work to be done on the feature. That means that not only should it do everything that the requirements say, but there should not be any technical debt added or things that you have to go back and refactor later, because then you’re not really done.

So when you say you’re building software incrementally, make sure that you really are done before you move on. Have high standards! There’s no point in settling for anything less.

August 1, 2010by Jon Kruger
Agile, TDD

Reducing the cost of change

If there’s one constant in software development, it is change. Our entire workday is spent changing things and responding to change.

Every time you write a line of code, you are changing it. You might add new features, fix bugs, or make changes to existing code. However you put it, you’ll be changing the code.

Requirements will change. You often find this out after you’ve coded a feature, and now the business either changes their mind or you find out that you made some wrong assumptions.

Business priorities will change. What was important yesterday may not be important today, and six months from now, all kinds of things might change. There could be new, more important projects on the horizon, new people in charge, or new business opportunities.

Software development teams change too. You might stay at your company for many years, but during that time, you might get moved from project to project. Developers will leave the company, and others will join. The end result is that many different people will end up working on the code that you’re writing today.

Since we know that we are going to have a lot of change, it would therefore make sense to reduce the cost of change so that we can respond to change as quickly and easily as possible. So how can we reduce the cost of change?

Automated Testing

Every time I add a line of code, I risk breaking my application. Breaking the application is just not acceptable. We’ve come to accept bugs as a part of the process, but that doesn’t mean that it’s OK to write bugs. If you’re not striving to write bug-free code, then maybe you need to raise your standards.

Nevertheless, the fact is that we all screw up and we all have the capability to create bugs. Knowing that, I want a way that I can easily test my application so that I can ensure that I find out if I broke something once I change it.

On my current project, I’m writing an application that helps my client bid on construction projects. They can’t afford to have bugs in their system that will cause them to incorrectly bid on these jobs or they could be out a lot of money. The bottom line is that it has to work because their entire business is now running on the application that I’m writing. They also come to me on a regular basis with new feature requests and things they need changed. They don’t want to wait months to get this functionality, and they also don’t want me to break any existing code.

Thankfully I have a large suite of automated tests that I can run to ensure that I didn’t break anything. This isn’t foolproof and things sneak through, but it’s usually little stuff that isn’t critical. But it’s good enough proof for me that I didn’t break the existing functionality. As a result, I can release to production daily and I spend virtually no time manually regression testing my application when I deploy. My unit test suite has reduced my cost of change to pretty much just the time it takes me to code the changes, so now I can react quickly to changes, release all the time, and I can do it without breaking existing code.

Clean Code

Sometimes people will write their unit tests, write the code to make the tests pass, and then assume that that is good enough. That’s great that you wrote tests, but how easy is it for someone to make a change in your code?

I feel that clean, readable code is very underrated these days. When you write code, are you thinking of the person that is going to need to understand what you did once you’re not around anymore? That scenario is very likely to play out at some point. So when you write code, create methods, variables, and classes that are very descriptive. Place a priority in making your code easy for someone else to read.

“Clever code” is the opposite of clean code. I’m talking about using complex algorithms to solve simple problems, trying to using a complicated LINQ statement to do an operation that would be more readable in a foreach loop, or trying to implement something in the fewest lines of code as possible. There are times where you might want to do things like this, but usually it’s more important to write code that is easier for someone else to read and understand. Again, remember that someday someone else is going to have to change your code, so write descriptive code that makes it easier for that other someone to know what to do.

Tests Are Documentation

Your unit tests are documentation of what your code is supposed to do. I practice behavior driven development, which means that my unit test methods describe some business functionality that my code is in charge of executing. This way, if someone needs to know what my code does, they can look at the test classes and methods and see what it is supposed to do.

Lately I’ve started adding a lot more comments in my test methods. The class names and methods names may describe what the code is supposed to do, but it doesn’t always explain why. I’ve found that sometimes it helps to write down the why because that is also important information. Since people can look at my tests as documentation of what my code does, I figured that this would be the best place to put the whys, because if someone has to change my tests, they’ll immediately know why I did what I did and they’ll have a reminder that they need to update my comment.

Build Iteratively

Since business priorities and requirements are going to change, we want to reduce the cost of this change too. If the business comes to you and drastically changes the requirements or certain assumptions that you might’ve made, it might be really costly and painful to change, and you can only do so much about that. What we can do is make sure that we’re constantly checking back with the business to see what they want now so that we have as few surprises and as little rework as possible.

This is one reason why Agile projects often run on iterations. As a part of this process, meet with your business sponsor every week or two and talk about what you’re going to do next. Show them what you’ve done in the last week or two, and make sure you’re on the right track. This way, if they’re going to change their minds, you’re giving them permission to do so and you can adjust what you’re doing as soon as possible so that you have the least amount of rework.

Always Be Aware of Change

Quit thinking short-term and quit shoving code in just to get it done as fast as you can. You may think you’ve done something good by getting it done faster, but if you create more work and pain in the future, it’s a net loss. Instead, always think about what the effects of what you are doing now will be two years from now. Your goal is to create business value without creating technical debt. A home builder can do shoddy construction and put nice looking paint and siding on the house, but 10 years from now when the problems arise, people won’t be thinking very highly of that builder. Don’t make the same mistake. Take pride in your work and strive to always leave your code base cleaner than you found it.

July 30, 2010by Jon Kruger
Page 5 of 6« First...«3456»

About Me

I am a technical leader and software developer in Columbus, OH. Find out more here...

I am a technical leader and software developer in Columbus, OH, currently working as a Senior Engineering Manager at Upstart. Find out more here...