Skip to main content

Analysing The Development Process

In A Simple Scenario we introduced some terms for talking about risk (such as Attendant Risk, Hidden Risk and the Internal Model).

We've also introduced a notation in the form of Risk-First Diagrams which allows us to represent the ways in which we can change the risks by Taking Action.

Now, we are going to start applying our new terminology to software. In the example below, we'll look at a "toy" process and use it for developing a new feature on a software project and see how our risk model informs it.

A "Toy" Process

Let's ignore for now the specifics of software methodology - we'll come to that later. For now, let's consider a simple, toy, process for developing software and understand how it works from a risk perspective.

Something like the following:

  1. Specification: a new feature is requested somehow, and a business analyst works to specify it.
  2. Code And Unit Test: a developer writes some code and some unit tests.
  3. Integration: they integrate their code into the code base.
  4. UAT: they put the code into a User Acceptance Test (UAT) environment and user(s) test it.
  5. All being well, the code is Released to Production.

A Simple Development Process

Can't We Improve This?

Is this a good process? Probably, it's not that great: you could add code review, a pilot phase, integration testing, whatever.

Also, the methodology being used might be Waterfall, it might be Agile. We're not going to commit to specifics at this stage.

For now though, let's just assume that it works for this project and everyone is reasonably happy with it.

We're just doing some analysis of what process gives us, and also why it is that we end up with processes for producing software at all.

Minimising Risks - Overview

I am going to argue that this entire evolved software production process is informed by software risk:

  1. We have a business analyst who talks to users and fleshes out the details of the feature properly. This is to minimize the risk of building the wrong thing.
  2. We write unit tests to minimize the risk that our code isn't doing what we expected, and that it matches the specifications.
  3. We integrate our code to minimize the risk that it's inconsistent with the other, existing code on the project.
  4. We have acceptance testing and quality gates generally to minimize the risk of breaking production, somehow.

A Much Simpler Process

We could skip all those steps above and just do this:

  1. Developer gets wind of new idea from user, logs onto production and changes some code directly.

A Dangerous Development Process

We can all see this might end in disaster, but why?

Two reasons:

  1. You're Meeting Reality all-in-one-go: all of these risks materialize at the same time, and you have to deal with them all at once.
  2. Because of this, at the point you put code into the hands of your users, your Internal Model is at its least-developed. All the Hidden Risks now need to be dealt with at the same time, in production.

Applying the Toy Process

Let's look at how our toy process should act to prevent these risks materializing by considering an unhappy path. One where, at the outset, we have lots of Hidden Risks. Let's say a particularly vocal user rings up someone in the office and asks for new Feature X to be added to the software. It's logged as a new feature request, but:

  • Unfortunately, this feature once programmed will break an existing Feature Y.
  • Implementing the feature will use some api in a library, which contains bugs and have to be coded around.
  • It's going to get misunderstood by the developer too, who is new on the project and doesn't understand how the software is used.
  • Actually, this functionality is mainly served by Feature Z...
  • which is already there but hard to find.

Development Process - Exposing Hidden Risks

The diagram above shows how this plays out.

This is a slightly contrived example, as you'll see. But let's follow our feature through the process and see how it meets reality slowly, and the Hidden Risks are discovered:

Specification

The first stage of the journey for the feature is that it meets the Business Analyst (BA). The purpose of the BA is to examine new goals for the project and try to integrate them with reality as they understand it. A good BA might take a feature request and vet it against his Internal Model, saying something like:

  • "This feature doesn't belong on the User screen, it belongs on the New Account screen"
  • "90% of this functionality is already present in the Document Merge Process"
  • "We need a control on the form that allows the user to select between Internal and External projects"

In the process of doing this, the BA is turning the simple feature request idea into a more consistent, well-explained specification or requirement which the developer can pick up. But why is this a useful step in our simple methodology? From the perspective of our Internal Model, we can say that the BA is responsible for:

BA Specification: exposing Hidden Risks as soon as possible

In surfacing these risks, there is another outcome: while Feature X might be flawed as originally presented, the BA can "evolve" it into a specification and tie it down sufficiently to reduce the risks. The BA does all this by simply thinking about it, talking to people and writing stuff down.

This process of evolving the feature request into a requirement is the BA's job. From our Risk-First perspective, it is taking an idea and making it Meet Reality. Not the full reality of production (yet), but something more limited.

Code And Unit Test

The next stage for our feature, Feature X is that it gets coded and some tests get written. Let's look at how our Goal meets a new reality: this time it's the reality of a pre-existing codebase, which has it's own internal logic.

As the developer begins coding the feature in the software, they will start with an Internal Model of the software, and how the code fits into it. But, in the process of implementing it, they are likely to learn about the codebase, and their Internal Model will develop.

Coding Process:  exposing more hidden risks as you code

At this point, let's review the visual grammar of the diagram above. Here, we're showing how the balance of risks will change if the developer Takes Action and writes some code. On the left, we have the current state of the world, on the right is the anticipated state after taking the action.

The round-cornered rectangles represent our Internal Model, and these contain our view of Risk, whether the risks we face right now, or the Attendant Risks expected after taking the action. We're not at the stage where taking this actions is completing the goal. In fact, arguably, we're facing worse risks after taking action than before, since we now have development difficulties to contend with!

But at least, taking the action of "coding and unit testing" is expected to mitigate the risk of "Duplicating Functionality".

Beneath the internal models we are also showing real-world tangible artifacts. That is, the physical change we would expect to see as a result of taking action. In the diagram above, the action will result in "New Code" being added to the project, needed for the next steps of the development process.

Integration

Integration is where we run all the tests on the project, and compile the code in a clean environment, collecting together the work from the whole development team.

So, within this example process, this stage is about meeting a new reality: the clean build.

Integration testing exposes Hidden Risks before you get to production

As shown in the diagram above, at this stage we might discover the Hidden Risk that we'd break Feature Y

User Acceptance Test

Next, User Acceptance Testing (UAT) is where our new feature meets another reality: actual users. I think you can see how the process works by now. We're just flushing out yet more Hidden Risks.

UAT - putting tame users in front of your software is better than real ones, where the risk is higher

Observations

Here are a few quick observations about managing risk which you are revealed both by this toy software process and also our previous example of The Dinner Party:

  • Taking Action is the only way to create change in the world.
  • It's also the only way we can learn about the world, adding to our Internal Model.
  • In this case, we discover a Hidden Risk: the user's difficulty in finding the feature.
  • In return, we can expect the process of performing the UAT to delay our release (this is an attendant schedule risk).

Major Themes

So, what does this kind of Risk-First analysis tell us about development processes in general? Below are four conclusions you can take away from the chapter, but which are all major themes of Risk-First that we'll be developing later:

First, the people who set up the development process didn't know about these exact risks, but they knew the shape that the risks take. The process builds "nets" for the different kinds of Hidden Risks without knowing exactly what they are. In order to build these nets, we have to be able to categorise the types of risk we face. This is something we'll look at in the Risks part of Risk-First.

Second, are these really risks, or are they problems we just didn't know about? I am using the terms interchangeably, to a certain extent. Even when you know you have a problem, it's still a risk to your deadline until it's solved. So, when does a risk become a problem? Is a problem still just a schedule-risk, or cost-risk? We'll come back to this question soon.

Third, the real take-away from this is that all these risks exist because we don't know 100% how reality is. We don't (and can't) have a perfect view of the universe and how it'll develop. Reality is reality, the risks just exist in our head. Again, this is a theme we'll develop later in Risk-First.

Fourth, hopefully you might be able to see from the above that really all this work is risk management and all work is testing ideas against reality.

In the next section, we're going to look at the concept of Meeting Reality in a bit more depth.