Monday, October 31, 2016

Having One Big Target

I've been in sprints where there are lots of little things to be done, as well as sprints where there's just one thing that has to happen. My experience is having one big target is much better than lots of little targets.

The reason, I think, is that one big target lacks the context switching that going from target to target. It allows all people to focus on one problem and gradually work to that.

A big target is not an ill-defined target. The same rules apply as apply in all scrum - it should be coherent enough that it can be worked on. Anything less and a big target has a chance of failure.

A big target should still be broken down to small targets. But the package of targets together provides a context to the work. A package of disparate targets has their own context, with the developers needing to adopt that mindset to begin work. Smaller tasks for a greater whole do not have that problem.

Friday, October 28, 2016

Burnout

I describe the agile process as sustainable development. The idea is that development should be able to be continued indefinitely. This is a big change from the usual development approach of big pushes and lulls.

It's a old habit, and old habits die hard. We know we can push harder at times to get over a line. And as individuals, we suffer for doing that. We run the risk of burnout.

We recently jumped deep into a problem that was complex and time sensitive. It required a big effort to get it over the line. At the end of it we made it, but it came at a cost. The following sprint has been deflated, with tired developers, a lack of enthusiasm and focus, and inevitably more mistakes.

The scrum process is set up to avoid this. That we agree to take in what we can handle, and base what we take in future sprints from past performance. We learn what we can achieve from what we have achieved. So those moments we go above and beyond throws that out.

It's an achievement to deliver 4 weeks of work in 2. But if the cost is tired unmotivated developers, there had better have been a very good reason for doing so.

Thursday, October 27, 2016

The Utility of a WIP Limit

One of the advantages of using a Kanban board for tracking scrum is that it identify bottlenecks in the process. The Kanban board has an interesting way to stop this - putting a limit on the amount of tickets that can be in a column at any given time.

Putting a WIP limit prevents too much work piling up. The team ought to be doing what it can to keep the flow going smoothly. It helps eliminate bottlenecks by preventing issues from piling up.

It also serves as a reminder to the team of collective commitment. That we are all in it together, and blockers affect everyone. Tickets stuck in analysis, development, or testing all have the same outcome - that feature doesn't get out. And given business value determines ranking order, the tickets in WIP are more valuable than tickets that are on the backlog.

Wednesday, October 26, 2016

Whatever Tools for the Job

When I was a child, I was amazed at just how many tools were in my grandfather's workshop. I didn't even know what most of the tools did, let one why there would be so many.

My toolkit is virtual rather than physical. Like the craftsman, knowing which tool is right for the job and how to use it effectively is vital.

One recent task I had to do was to query our database and get some intelligible information from it. To do this, I used a combination of SQL Developer and Excel, taking advantage of features in both to perform the task. A DBA may have been able to solve it purely in SQL (just as I'd easily be able to solve it with a targeted Java function), but the combination of tools worked for me. I used SQL Developer and Excel for what each was good at doing.

Knowing multiple ways to solve a problem gives flexibility when issues arise. Sometimes a spreadsheet or even Notepad are the right tools for the job in the right circumstances.

Tuesday, October 25, 2016

The Nature of Agile Testing

"The focus of agile development is producing high-quality software in a time frame that maximizes its value to the business. This is the job of the whole team, not just testers or designated quality assurance professionals. Everyone on an agile team gets “test-infected.” Tests, from the unit level on up, drive the coding, help the team learn how the application should work, and let us know when we’re “done” with a task or story. An agile team must possess all the skills needed to produce quality code that delivers the features required by the organization. While this might mean including specialists on the team, such as expert testers, it doesn’t limit particular tasks to particular team members. Any task might be completed by any team member, or a pair of team members. This means that the team takes responsibility for all kinds of testing tasks, such as automating tests and manual exploratory testing. It also means that the whole team thinks constantly about designing code for testability." [Crispin, L. and Gregory, J., Agile Testing, p.15]

Monday, October 24, 2016

Our JIRA Scrum Board Columns

  • TODO
    It holds the list of all unassigned tickets for the sprint. The expectation is that for the tickets to get into this column, they've had enough refinement done before the sprint that they can be worked on with minimal further clarification. The tickets are ordered vertically by business rank.

  • Development
    For when the ticket is being actively developed. The ticket is assigned to the person doing the work, and will remain in this column until the work is complete. If the work being done is Java, then branches are made off the ticket. Tickets with branches that have a pending pull request get coloured orange, while tickets with merged pull requests are green.

  • Testing
    When the development work is ready to test, tickets are moved into Test. It will be up to whoever in the testing team is available to assign themselves the work. If a severe defect is found, then a sub-task is created from the ticket. If the defect is not a problem for the functionality, then a new ticket is created and put on the backlog.

  • Product Owner Review
    The product owner gets final say over whether a unit of work is done. This column is the for the final verification by the product owner that the ticket meets the business expectation.

  • Done
    The product owner moves the cards to this column when they are satisfied the story is complete. When a sprint ends, any tickets not in this sprint will be moved either to the next available sprint, or into the backlog.

Friday, October 21, 2016

Dude's Law: Value = Why / How

The one of the consequences of agile development is the focus on a minimum viable product. The product owner sets the work by business value, so the user stories with the highest value are always worked on first.

The business need for a user story (or the amount of work done on a user story) does depend on the ability for the development team to deliver that story. A really complex piece of work might be the best thing from the business perspective, but is it more important than multiple smaller tickets? This is where Dude's Law comes in.
Dude's Law: Value = Why / How

If something takes a lot of effort, that's effort that could be expended on something else. So if a user story is going to take a lot of effort, it's value ought to be weighed up against what alternatives could be done instead.

The inverse holds for where the how is minimal. Changes that are trivial to implement can high value even if they are not priorities from a business perspective. But a user story that's difficult to implement and of low business importance holds very little value.

Applying Dude's Law gives a way to quantify what tasks ought to be achieved in a sprint. Like everything, the code should be written such that if the project were to be shut down tomorrow, as much business value as possible should have been added until that point.

Thursday, October 20, 2016

JIRA Tip - Use Columns, Not Workflows

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.

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.

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.

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.

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:
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.

Wednesday, October 12, 2016

Purposes of Unit Testing

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. Refactoring
    Unit tests provide the assurance needed that refactoring the codebase hasn't accidentally changed functionality. Without unit tests, refactoring is fraught with risk.

Tuesday, October 11, 2016

Chickens and Pigs

A Pig and a Chicken are walking down the road.
The Chicken says: "Hey Pig, I was thinking we should open a restaurant!"
Pig replies: "Hm, maybe, what would we call it?"
The Chicken responds: "How about 'ham-n-eggs'?"
The Pig thinks for a moment and says: "No thanks. I'd be committed, but you'd only be involved."
Most people who are involved in a project are not committed. They are chickens. And while they make decisions that affect the project, they are not committed in the same way as the development team are.

The development team are the ones who are responsible for what is delivered. They are pigs. Their actions directly affect the project.

A chicken making decisions on behalf of the pigs can adversely affect the team's ability to do their job. As the chicken has no skin in the game, their decisions are divorced from the consequences.

A pig who acts like a chicken is also problematic. If they are not committed to delivery, their involvement detracts from the team's collective ability to deliver.

Monday, October 10, 2016

Branching from a Branch

In Git, everything is a branch. We branch off master for features and bugfixes. And with this, a curious case came up in our team. A feature was dependent on another feature, so he branched from the feature branch.

This strategy had one drawback. He finished before the first feature branch was finished, so merging back into master brought a lot of unnecessary code with it.

Reviewing the situation, of course this had to happen. The dependency between the two user stories required that parts of feature A were needed for feature B. And there was no way to merge feature B in without merging those parts of feature A.

In other words, this shouldn't have been an issue. Except that he wasn't prepared to take ownership of someone else's user story. That would be fair, except he tried to merge his changes that inevitably depended on the other user story.

What should have happened was that feature B should have been put on hold until feature A had been merged back to master. Or, ideally, that feature B should not have begun until its dependency (feature A) had been completed. At the very least, those parts of feature A needed for feature B should have been committed and code reviewed before feature B was merged.

What ended up happening was parts of feature A were merged into master as part of feature B, though they were ignored from the code review perspective. This is far from the ideal, and caused plenty of confusion.

Friday, October 7, 2016

An IDE is a Tool, so Learn to Wield One

In my dabbling in my youth with Linux, I learnt a few of the basic command-line commands. It was enough to get by, but I wasn't anywhere near as effective with it as my mate who had converted me to Linux was. He could do all sorts of things with ease from the command-line, while I was constrained by what the GUI would allow me to do.

I learnt the lesson that I should be just as comfortable writing code in Notepad (or on paper) as I am in an IDE. The IDE was dismissed as a crutch that poor developers leaned on.

Over the years, I've come to see that it's both wrong and short-sighted to dismiss IDEs that way.

If for no other reason, being able to code in an IDE takes away some of the more tedious parts of programming. It's a waste of energy to do things like match up every parenthesis, or to scour the code for spelling mistakes. Having syntax highlighted makes reading code so much easier. Having linked code makes drilling down through classes effortless.

There are direct advantages too. Auto-generation of boilerplate code. Autocomplete. Real time code analysis. Instant accompanying documentation. Easy refactoring. Compilation, unit test, and debugging all at the ready.

Learning the shortcuts for an IDE can make it even more powerful. With Eclipse, I take full advantage of some of the text editing shortcuts to make code entry quicker. There's just no way I'd be able to be that effective on a text editor. For most common actions, I don't even have to leave my keyboard.

That's not to say I do everything in my IDE. I find having command line batch scripts more useful for compilation. I prefer TortoiseGit over EGit for source control. But coding-wise, learning how to use Eclipse effectively makes me far more productive.

Thursday, October 6, 2016

When Algorithms Test

Code needs to be tested. Sometimes that testing is best done by an algorithm.

We recently had a user story that involved removing particular characters from the application number string. The purpose was to address a readability issues - at a glance certain characters and numbers are indistinguishable, so removing the offending characters from the string they were generated from. A simple enough coding exercise.

This card, however, sat in the testing column for a long while. It didn't need to, as we had built a unit test that did what a regular tester would do - throw lots of data at the generation and see whether those offending characters were present.

An automated test, in this case, could do what a human could not: quickly generate and accurately assess the functionality. It's checked 1000 times every time the code is compiled - overkill as far as what's needed to be tested, but that overkill is computationally negligible.

Writing the unit test first (TDD) gives the developer the target to aim for, as well as creating the before and after test artefacts. At the very least, the unit tests results could supplement the functional spot-checking that would constitute normal testing for such a story.

Writing code that verifies functionality is not simply for helping developers to write better code, but can be the best tool at the disposal of the testers for doing testing. It's leveraging technology at tasks it excels, which is what we ought to be using technology for.

Wednesday, October 5, 2016

Book Recommendation: The Nature of Software Development

Development has more than enough to keep anyone occupied on immediate concerns. But it's worth standing back in order to reflect on what it is we are doing.

The Nature of Software Development by Ron Jeffries can best be seen as an expansion on the agile manifesto. Like the manifesto, it's high level but gets right to the point. Like the manifesto, it's concise but profound. And like the manifesto, the aim is to identify what makes for successlooks like.

What we are doing when building software is trying to add value. The word can mean different things in different contexts, but in this case it is a strength rather than a weakness.

We build software because the software will serve a purpose. We should focus on delivering that which serves that purpose, and not waste time on features that are superfluous to that.

We should develop such that there will be value if the project winds up tomorrow. The code should always be ready to deploy. We should fix problems as we go along because that makes development quicker in the long run.

There's much more to the book than I'll cover here. It's a short book, and conversational in tone, and that fits with the message the cook conveys. Deliver what adds value, and don't waste time with filler that doesn't. This book is very valuable.

Tuesday, October 4, 2016

90% of Development is People

When I started out in software development, my biggest concern was my lack of technical ability. Each annual review I flagged technical proficiency as an area of improvement.

After about 5 years and a few projects, I was put on an assignment with absurd deadlines on a different technology stack. This forced me to talk to people more about what I was doing. This was a gestalt moment for me, as it forced me to see software development in a new light.

Raw technical proficiency has its place, and some jobs require it - 3D engine programmers, for example. But for the enterprise work I do, soft skills matter.

The ability to negotiate matters because ideas are seldom unambiguous. It also matters in navigating what can be achieved in the face of unrealistic expectations.

The ability to foster trust matters because it's essential for team cohesion and fostering working relations.

Being able to effectively communicate matters because if we can't express ourselves to others, then we can't get our ideas across.

Being able to listen matters because others need to be able to get their ideas across to us.

And being able to put all that together matters because effective collaboration requires all those skills. A developer who can collaborate is in a far better position than one where those skills are lacking.

Monday, October 3, 2016

Shuhari: first learn, then detach, and finally transcend

From Wikipedia:
  • shu (守) "protect", "obey" — traditional wisdom — learning fundamentals, techniques, heuristics, proverbs
  • ha (破) "detach", "digress" — breaking with tradition — detachment from the illusions of self
  • ri (離) "leave", "separate" — transcendence — there are no techniques or proverbs, all moves are natural, becoming one with spirit alone without clinging to forms; transcending the physical
When we learn something new, the accumulated wisdom of those who came before is the best place to start. We follow what they say because they know what they are talking about. This is shu.

As we progress, we are able to identify where the rules work for us and where they don't. We are in a position to know the difference between what works and what doesn't, so breaking the rules gives us valuable feedback. This is ha.

Finally we are in a position where the rules no longer matter. We have developed through experience practices that serve us well, as well as learnt many bad practices to avoid. This is ri.