In the SAFe DevOps Health Radar, Develop is where we take the features from continuous exploration and turn them into working code. We split features into user stories, implement them with a strong focus on built-in quality, and commit everything to version control. In this video, I walk through the Develop step and explain why quality practices like TDD and BDD are so important.
Where Develop Fits in the Pipeline#
In previous videos we looked at Continuous Exploration: gathering ideas from the business and customers, transforming them into epics with clear hypothesis statements, validating those hypotheses through client interviews and market research in Collaborate and Research, defining the minimal architecture in Architect, and synthesizing everything into features for our backlog and roadmap.
With those features in hand, we now enter the Develop step. Here we split features into stories, implement those stories, and commit the code into version control.
Splitting Features into Stories#
A feature is typically bigger than a single iteration or sprint. That is why we need to break features down into smaller user stories. The goal is to identify the minimum piece that delivers value to the business or the customer and can be built right now.
For example, if we need to build a website with multiple input forms, the smallest valuable story might be: build the website skeleton, connect it to the backend and an external system or database, and display something on the screen. This proves we can integrate and already delivers value.
Writing Good User Stories#
Splitting features alone is not enough. We need to write the stories properly. A user story follows a clear template:
- Title that describes the story
- Sentence in the form: “As a [user], I want to [action], so that [business value]”
- Acceptance criteria written in the Given/When/Then format (Behavior Driven Development)
For example: “As a driver, I want to limit the amount of money before I fuel, so that I can control my expenditure.” The acceptance criteria then specify: “Given that the driver indicates a maximum amount of money, when the fuel costs reach the amount, then the fuelling process stops automatically.”
With BDD we get an executable specification directly from the acceptance criteria. This gives us test cases we can implement straight away.
Test Driven Development#
For implementation we use a test first approach: Test Driven Development (TDD). The cycle is simple:
- Write a test. Run it. It fails (red) because the implementation is missing.
- Write just enough code to make the test pass (green).
- Refactor safely, because all tests still pass.
- Repeat with the next test.
The benefit is clear: we get tests for every piece of our implementation, and we know the implementation does exactly what is specified. When the user story is already written with BDD acceptance criteria in Given/When/Then form, creating the tests becomes even easier.
Built-in Quality and the Shift Left Approach#
We want to build quality in from the beginning instead of testing it in afterwards. This is the shift left approach: instead of the traditional V-model where testing happens after coding, we move testing to the left.
With shift left:
- Features are written directly with BDD (tests in Given/When/Then form)
- User stories have executable acceptance criteria
- Code is written using TDD (test first)
- Pair work (e.g. pair programming) improves both quality and speed
This means tests are written at every level, right from the start. Quality is built in, not bolted on afterwards.
Everything in Version Control#
Once the code is written, we commit it to version control. But not just the code. Everything should be in version control: code, infrastructure configuration, tests, test data, requirements, and architecture documentation.
By having everything under version control, we gain full traceability. For any given version, we can see exactly what code, configuration, tests, and requirements were part of that deployment.
Application Telemetry#
In the Architect step, we designed for operability. Now in Develop, we implement that design. We add logging statements and application telemetry to collect the information needed to operate the system efficiently in production, without logging into the production server to hunt for bugs.
Application telemetry serves two purposes:
- Operational data: monitoring system health and diagnosing issues quickly
- Business data: evaluating our hypothesis and measuring the value we deliver
Addressing Security Concerns#
In the Architect step, we performed threat modelling to identify threats, attackers, and attack vectors. In the Develop step, we write the code that addresses exactly those security concerns. Security is not an afterthought. It is implemented as part of the development work.
The Maturity Levels#
The SAFe DevOps Health Radar provides a maturity assessment for Develop:
- Sit: The team backlog does not exist or is not used to manage daily work.
- Crawl: Stories are either incomplete or too verbose. Unit tests are generally not written. Peer reviews are not conducted.
- Walk: Stories are complete. Most changes have unit tests. Peer reviews are usually conducted.
- Run: Code is checked in daily. Unit test coverage is above 80%. Peer reviews are always conducted.
- Fly: Code is checked in multiple times per day. Tests are written before code (TDD). Pair work and other built-in quality practices are the norm.
A note on unit test coverage: having a coverage metric is useful as an indicator for the development team. It can highlight areas that need improvement. However, it is a decision of the developer or team where high coverage makes sense. There are areas in the code where zero percent coverage is perfectly acceptable.
What Develop Produces#
The output of the Develop step is:
- User stories that are refined and ready for implementation
- Code committed to the source code repository
- Tests (unit tests, integration tests, end-to-end tests) that verify the committed code
This code then moves to the next step in the pipeline: Build. There, the committed source code is compiled and packaged into deployable artifacts.
Key Takeaways#
- Split features into small, valuable stories. Each story should deliver something meaningful within a single iteration.
- Write stories with BDD. Given/When/Then acceptance criteria give you executable specifications and ready-made test cases.
- Use TDD for implementation. Write tests first, then code. This builds quality in from the start.
- Embrace pair work. Two people working together on a story improves both quality and speed.
- Put everything in version control. Code, configuration, tests, requirements, architecture. Full traceability depends on it.
- Implement application telemetry. Design it in the Architect step, build it in the Develop step. You need it for operations and hypothesis validation.
- Address security concerns in code. Threat modelling identifies the risks; Develop is where you mitigate them.
