Agile Development Best Practices

Sprint Planning

How to ensure team has selected a group of stories to ensure delivering value to the company.

Lock Requirements During Sprints

Don't change stories during a sprint: during a sprint or iteration no changes be made that would affect the sprint goal.

Why?
Changes in mid-sprint jeopardise work investment:
- planning isn't free
- work toward discarded / delayed features isn't free
Increases risk:
- other features may not get delivered
- other features may have defects

Time-Boxing

- keep the duration of each iteration the short and consistent (usually 2 - 4 weeks)
- simplifies planning and allows everyone to establish rhythm

Why?
- easier planning
- detects problems with features sooner
- detects problems with development method sooner
- known end date lends sense of focus and urgency
- prevents feature creep

Usually, let stories drop if run out of time (don't extend the time).

Only the Team Estimates

Only team during the work should be ones estimating effort involved.

Why?
- they have unique insights into type of obstacles that will come up
- estimates can reveal incorrect assumptions about requirements

Product Owner Availability

Keep product owner available to answer team questions.

Product owner is expert on what features need to be implemented, and in what order
- product owner has unique domain knowledge
- needed for clarification during estimation
- at first, stories will be missing details needed to implement
- its a full time job

User Feedback

Demo Every Sprint

Only alternative is long-winded progress reports which can easily be misinterpreted.

Why?
Stakeholders need to see the product as early as possible:
- they don't have time to read details specs
- working software offers clearer picture than written specs
- a clearer picture allows better planning
- better planning means less wasted work

Make Feedback Easy

Need feedback from users too, but they're busy
- make it difficult and issues will go unreported
- make it easy and their feedback will boost product quality
- don't ignore what feedback you get: read it in standup
- good feedback boosts morale, negative feedback offers chance to improve

Testing

- ensure technical debt isn't accruing on project

Test at Development Time

Testing is far for effective in tandem with development.  After development the bugs are far harder to fix than during.

Untested code is dangerous technical debt
- lower velocity
- compounding defects
- rising support costs

If testers are at capacity, developers should step in and help them test

Shared Definition of Done

A list of all the tasks that must be completed before a feature is considered complete.

When team declares story is done, needs to be in a releasable state:
- avoids miscommunication
- keeps testing from slipping through

Test-Driven Development

Tests are written first, before code is implemented, and that tests drive the development (and are not just used as a validation tool).

The tenets of TDD are:
- code is written only when there is a failing test that requires the code to pass
- the bare minimum amount of code is written to ensure that the test passes
- duplication is removed at every step
- once all test are passing, the next failing test is added for the next required functionality

These rules ensure:
- code develops organically, and that every line of code is purposeful
- code remains highly modular, cohesive and reusable (as you need to be able to test it)
- a comprehensive array of tests to prevent future breakages and bugs
- the tests also act as specification, and thus documentation for future needs and changes

Next time you write a test, remember to answer all the questions:
What are you testing?
What should it do?
What is the actual output?
What is the expected output?
How can the test be reproduced?

import test from 'tape';

// For each unit test you write,
// answer these questions:
test('What component aspect are you testing?', assert => {  
  const actual = 'What is the actual output?';
  const expected = 'What is the expected output?';

  assert.equal(actual, expected,
    'What should the feature do?');

  assert.end();
});