Before we started using JIRA, we had Kanban boards made of electrical tape on the walls. They had 4 columns: Backlog, In Progress, Done, and Done & Done. Three of those 4 columns were self-documenting, but the In Progress column had cards covered in post-it notes for what work was being done on it and who was doing that work.
When we moved to JIRA, the first thing we did was customise the board. By default, the standard scrum board comes with three columns (and corresponding statuses) - TODO, In Progress, and Done. We've expanded that to 5. We tried including extra statuses for each column, but JIRA couldn't visually transition between statuses on the same column.
As we set up statuses, we didn't put a workflow on them. Any card can be changed to any other status at any time.
One reason for this is that the kinds of tasks don't always have the same workflow. We need the flexibility to go from development to done, or go back from product owner review. The default catch-all In Progress does this well but lacks the explicit documenting of where the process is up to that we ate trying to achieve with the extra columns.
Another reason is that the columns are visually documenting of the general process. Moving the flow from left to right is natural, so it's done by convention and doesn't need to be forced.
The final reason is that all the people in the project are professionals, such that there's no need to constrain their use of the tool. JIRA is for the team to use as a guide to development, so it should be up to them how they make the best of it. There's just no need to constrain the team's agility.
Thursday, October 20, 2016
Wednesday, October 19, 2016
The Value of Values
The most attractive thing about any agile methodology is that the processes are am embodiment of values. What makes agile agile is the ability to change those processes if and when doing is what's best for the project.
Scrum, XP, and Lean all have their own ways of doing things - but the adoption of those practices doesn't embody agility.
For example, we are using the scrum methodology. This means designated sprints, daily stand-ups, planning, and retrospectives. But these aren't what makes us agile. It's the Scrum values - commitment, openness, courage, respect, and focus - that makes us agile.
The values that the different agile methodologies hold are also able to be utilised without adoption of the practices. The idea of seeing the whole is a value of lean, but it's just as useful a value to hold to while doing scrum.
The advantage of values is being able to respond and change to difficult situations without falling back on the process. Values are our metric by which change is guided and assessed. They are the why of the processes that allow us to know what those processes are for.
Processes without the values can be followed and confer the same advantages as a team who have internalised the values. But knowing the processes without the values makes it harder to realise those advantages when the processes become burdensome or sub-optimal. An agile team has the ability to better utilise the processes than one who follow the processes without the values guiding them.
Scrum, XP, and Lean all have their own ways of doing things - but the adoption of those practices doesn't embody agility.
For example, we are using the scrum methodology. This means designated sprints, daily stand-ups, planning, and retrospectives. But these aren't what makes us agile. It's the Scrum values - commitment, openness, courage, respect, and focus - that makes us agile.
The values that the different agile methodologies hold are also able to be utilised without adoption of the practices. The idea of seeing the whole is a value of lean, but it's just as useful a value to hold to while doing scrum.
The advantage of values is being able to respond and change to difficult situations without falling back on the process. Values are our metric by which change is guided and assessed. They are the why of the processes that allow us to know what those processes are for.
Processes without the values can be followed and confer the same advantages as a team who have internalised the values. But knowing the processes without the values makes it harder to realise those advantages when the processes become burdensome or sub-optimal. An agile team has the ability to better utilise the processes than one who follow the processes without the values guiding them.
Tuesday, October 18, 2016
Bitbucket for History
One really useful Bitbucket feature is being able to view the history of a file in a browser. This is useful for tracking changes in any given commit.
When combined with Blame, it's a great diagnostic tool for code history. It's easy to go back through code to the right commit, even when subsequent commits have occurred. It's just a matter of switching to the right commit and checking Blame again.
When combined with Blame, it's a great diagnostic tool for code history. It's easy to go back through code to the right commit, even when subsequent commits have occurred. It's just a matter of switching to the right commit and checking Blame again.
Monday, October 17, 2016
Programmatic vs Functional Testing
From a testing perspective, it makes no difference how a programmatic solution is implemented if the functionality remains the same. What matters is how the system behaves, and not what goes into that behaviour.
Functional testing ought to treat the system as a black box. This decouples the testing suite from the solution, allowing testers to focus on the quality of the software rather than getting bogged down in the details of how the software works.
This also gives the programmers the freedom to refactor the solution without causing extra rework on the testing suite.
The question, always, is what value does it provide? The cost of testing the programmatic details not only has the time expense of the testing, but the additional cost of not focusing that effort elsewhere.
Functional testing ought to treat the system as a black box. This decouples the testing suite from the solution, allowing testers to focus on the quality of the software rather than getting bogged down in the details of how the software works.
This also gives the programmers the freedom to refactor the solution without causing extra rework on the testing suite.
The question, always, is what value does it provide? The cost of testing the programmatic details not only has the time expense of the testing, but the additional cost of not focusing that effort elsewhere.
Labels:
programming,
testing,
value
Friday, October 14, 2016
Git Tricks: Working in the Wrong Branch
One of the tricky things about Git is getting into the mindset that a branch is a snapshot of files rather than a diff of a file system.
Another tricky thing is remembering to switch before starting to code.
One thing that's tripped up a few of my team members (and myself too!) is what to do when coding in the wrong branch. If they haven't committed, this is easily solved:
Another tricky thing is remembering to switch before starting to code.
One thing that's tripped up a few of my team members (and myself too!) is what to do when coding in the wrong branch. If they haven't committed, this is easily solved:
Simply switch between branches. The uncommitted files will be unaffected.The main thing to watch out for is when a changed version of that file is on the branch being switched to. At that point, manual merging needs to happen. But for the general case, it's as easy as pointing your local repository at the desired branch.
Thursday, October 13, 2016
Identifying and Eliminating Bottlenecks
"Don't be irreplaceable, if you can't be replaced, you can't be promoted." (from Dilbert's Laws of Work)
The easiest way to identify a bottleneck is to see what happens when time is a factor. If someone (or something) is critical to an operation, then things don't happen. That is obviously a less-than-ideal way to find where a bottleneck is.
Bottlenecks usually present themselves long before a crisis, but aren't seen as critical at the time. They are usually things that only occasionally matter, so general availability is usually enough.
Unusual situations aren't unavoidable situations. Taking steps to eliminate the bottleneck is sensible risk management. It is much better than the alternatives, such as cancelling leave or letting deadlines slip.
For those bottlenecks that are part of everyday development, they should be mitigated and eliminated as quickly as possible. In our team, only a few people had the ability to do deploys. This was liveable until those people went on leave. So we implemented automated deploys from Jenkins so that would never be a problem again.
The easiest way to identify a bottleneck is to see what happens when time is a factor. If someone (or something) is critical to an operation, then things don't happen. That is obviously a less-than-ideal way to find where a bottleneck is.
Bottlenecks usually present themselves long before a crisis, but aren't seen as critical at the time. They are usually things that only occasionally matter, so general availability is usually enough.
Unusual situations aren't unavoidable situations. Taking steps to eliminate the bottleneck is sensible risk management. It is much better than the alternatives, such as cancelling leave or letting deadlines slip.
For those bottlenecks that are part of everyday development, they should be mitigated and eliminated as quickly as possible. In our team, only a few people had the ability to do deploys. This was liveable until those people went on leave. So we implemented automated deploys from Jenkins so that would never be a problem again.
Wednesday, October 12, 2016
Purposes of Unit Testing
- As a development process
Test-driven development is a useful skill to learn. It encourages a clean design, as writing unit tests for messy design is both painful to write and painful to maintain. It also gives a target to code against, by setting what what the function ought to achieve before the function is even written. - Proving the code behaves correctly
Writing unit tests is the simplest way to show that code does what it is meant to do. Unit tests allow easy checking of boundary conditions, to ensure that the function behaves as expected. - Demonstrating robustness
In complex systems, well-written unit tests demonstrate that functions behave as expected. As more features are added, or as code is reused, unit tests demonstrate that these changes do not affect the existing functionality. Conversely, if unit tests easily brake when code changes, it's a good indicator of fragility. - Testing
Some tests algorithms are better for than humans. When testing a function involves a large amount of data, unit tests are best equipped for this job. This is also true for time-dependent functions, or testing algorithms. - Refactoring
Unit tests provide the assurance needed that refactoring the codebase hasn't accidentally changed functionality. Without unit tests, refactoring is fraught with risk.
Subscribe to:
Posts (Atom)