BY: Nicholas Snogren, Software QA Manager at TREND
In the fast-evolving world of software development, knowing when we’re truly “done” can feel elusive. Traditional test-case approaches, rooted in step-by-step instructions, often fail to capture the nuance of real-world behavior and risk. The TPO Behavior-Cases Framework offers a more powerful, flexible method for defining and verifying software quality: one that centers on behaviors instead of procedures. By focusing on Triggers, Parameters, and Outcomes (TPO), teams can uncover meaningful coverage, identify unknowns early, and communicate test logic with greater clarity and efficiency.
What is Done?
How do we know we’re “done” in software development?
We’re done when the behavior is right. Software behaviors need to be correct, performant, usable, and secure under real-world conditions. What tests would reveal the behaviors are not right? This paper defines a framework to find, communicate, and improve those tests as early in the SDLC as possible.
Test Cases
Testing often follows a “Test-case” format for organizing test activity. These test cases are procedural steps, with the idea that if you follow these steps, the app is tested. Where do these steps come from? How do we know what they’re covering? Why are we writing instructions for teams that are using the app all day, every day?
There’s a better way.
Behaviors
Testers learn, analyze, explore, and automate, all in order to discover and evaluate behaviors that might matter. Therefore, our documentation should focus on these behaviors. These behaviors are like our currency, our unit of measurement.
Test-cases should define behaviors rather than instructions.
- The behaviors that give confidence to release
- The behaviors that reveal significant problems
- The behaviors we discovered mattered, that no one anticipated
Behaviors fall into two categories:
- Behaviors we know to check (known unknowns)
- Behaviors we don’t know to check (unknown unknowns)
Every time we build or change something, there are behaviors from both categories. It’s relatively easy to test the known unknowns, especially with automation. Most bugs and difficulties come from the unknown unknowns. This technique helps us find them as early as possible.
The Requirements TPO Framework
Behaviors are born of requirements. Every requirement must contain triggers, parameters, and outcomes in the same way a sentence must contain a subject, verb, and object. These ingredients are used to analyze, brainstorm, and design test coverage.
- Trigger (or action)
- A trigger is whatever initiates the app to respond.
- Parameters (or conditions)
- The parameters are any data value or factor that influences or determines the behavior.
- Outcomes
- The outcomes are anything done, changed, or produced as a result.
Example Requirement
This example will be used throughout the rest of the paper. We’ll break it into its TPO, define the Acceptance Cases, and then brainstorm for any more behaviors that might matter.
- The system shall lock the account after five failed login attempts within 15 minutes
Trigger
- The user attempts to log in to their account
Parameters
- Login success/failure state = failed
- Number of failed login attempts = 5
- Time window = 15 minutesAccount lock status
-
- This is an implicit It wouldn’t make sense to lock an already locked account, right?
Output
- The account is locked.
- What message should display?
- How long should it be locked for?
- What is the effect of being locked?
The TPO framework helps us brainstorm, analyze, and design tests more easily.
Acceptance Cases
Now that the requirement is laid out clearly, it’s easy to design the behaviors that would indicate it’s met. They involve one happy path for the whole requirement, and one negative path for each parameter.
Happy Path
First is the happy path: if the action is triggered, and all the parameters are valid, then the results should be as described:
- Account is locked out after 5 login attempts using a valid email with incorrect password in 15 minutes.
Negative Paths
Next you have the minimum negative paths. Given the action is triggered, and one of the parameters is invalid, then the result should not happen as described. Repeat this for each parameter.
In this example we had 4 parameters, so there should be 4 negative cases:
- Account not locked after 5 successful login attempts within 15 minutes
- Account not locked after 4 failed login attempts
- Account not locked when the 5th failed attempt happens > 15 minutes after the first failed attempt
- Account already locked out… not sure what should happen…
Congratulations, you did the bare minimum to assess the requirement. These minimum cases should always be automated at the lowest level possible (Unit > Integration > API > UI). These automated cases preserve the logic from contradictions as the app changes. They are the backbone which gives us the confidence we haven’t messed anything up. Like BDD, they help us discover new questions, like what should happen if you’re already locked out? The TPO and minimum cases make it very easy for cross-functional teams to brainstorm and communicate, without the extra verbiage of gherkin.
You can communicate these cases in a table. Notice how each negative row invalidates a single parameter, while the Name describes the behavior being covered.
Predictable Cases
Every time you reread those triggers, parameters, and outcomes, especially if you come back to them later, you’ll probably think of more questions and variations. That’s exactly what’s supposed to happen. For instance, here are some of the ideas I came up with when rereading the example:
- What are more ways to fail logins, besides incorrect password?
- When does the lock occur? Is there a gap between the 5th failed attempt and the completion of the lock?
- What if your email is invalid? There’s no account to lock… but should we block X number of failed attempts to protect against brute-force attacks?
- Is the 15 minutes a rolling time window? When does the window start? Can you have overlapping time windows?
- Does a successful login attempt reset the count? i.e. you have 4 failures, then 1 success, then another failure. Per the explicit requirement, you’d be locked out.
These questions need answering, and since we found them early in the SDLC, they can be answered before development even starts.
Reinventing the Test Case
Instead of a list of steps, we create a list of behaviors. There’s a row for each behavior that might be different for some reason. We name each behavior after its reason. Those names make it easy for anyone to review coverage, inspire new thinking, and collaborate. We can even use the names to track questions, risks, or charters we want to explore.
Imagine how many steps you’d have to write in a traditional test case to cover all this!
If you are looking at my list and thinking to yourself, “I can think of more important ideas than this…” Then great, this method is working!
From here we can:
- Build deeper coverage on top of those cases, involving more variations of actions, parameters, and deeper evaluations of results. The time spent here will depend on the complexity of the requirements and system, the risk, and remaining time.
- Communicate these cases to developers, product owners, and other testers, for automating, brainstorming, and evaluating.
- Use each case to track test progress.
The Coastline Paradox
The trigger, “The user attempts to login to their account,” is very vague. If you look closer, you’ll see other triggers: navigating to the login page, submitting email, submitting password, etc. If you look closer again, you’ll realize there are many UI, network, and backend processes that happen in-between. Closer still, and you’ll start to appreciate the mass of layers and latency between your fingers and the server.
The Coastline Paradox is the counterintuitive observation that the coastline of a landmass does not have a well-defined length. The length depends on your measuring stick, and your measuring stick depends on your goal. It is the same with software.
Our measuring stick depends on the goal, which in software testing is informed by the risk. We intuitively select different measuring sticks all day, every day. The TPO framework relies on this interpretation, and can help inform us when we need to zoom in. Sometimes the risk doesn’t warrant applying the framework at all.
Mindmaps
Mindmaps also work well for this technique. Excel and mindmaps help to design, brainstorm, and communicate coverage. It’s easy to log results and modify them as you test. Test-case management tools include too much bloat to accomplish all those tasks concurrently.
Incorporating in the SDLC
Timing
Like in BDD, this analysis should happen before anyone starts writing code. It often uncovers clarifying questions that need answering, and the cases can inform TDD. Unlike BDD, it doesn’t require bloated verbiage.
Formats
The cases can be brainstormed as mindmaps, lists, excel tables, and more. We should explore tools that translate from mindmaps and tables into the test-case management tool of choice.
AI
AI can be used to translate a requirement into the TPO framework, which we can improve upon. I’ve developed a few prompts and experimented with Chat GPT, Claude, and Mistral with great success. We can design a JSON output for the chatbot that can be imported into mindmap or excel structure and then have an import tool to turn those into test-cases in a test management tool.
Test-case management tool
Since existing test tools aren’t designed for this style of documentation, we can manipulate the traditional test-case format for our purpose:
- Each test-case should be named after the requirement being tested and organized in folders or tags to relate to their parent features.
- Each “Step” in the test-case should a behavior-case, instead of an instruction for what to do.
The list of behaviors changes as we learn more through testing. Once they’re in the test-case tool they’re difficult to change. They’re much easier to maintain in Mindmap or Excel form. Therefore, a tool which is based on mindmap or tables at its core and builds execution data and summary reports on top of them, would be ideal.
The TPO Framework and Behavior Cases are a low overhead but highly informative way to brainstorm and track coverage. They’re many times more effective than traditional test-cases. They make collaboration much easier. They can be referenced in the future when existing requirements are changed, or test coverage needs to be reviewed in detail. Teams should abandon the step-by-step model, and the next generation of testing tools should focus on this new method of communication.
This article is part of TREND Health Partners’ thought leadership series on strengthening the healthcare financial ecosystem. We believe that true security isn’t just about technology, it’s built on culture, collaboration, and shared accountability. To explore more insights on a people-first approach to cybersecurity and revenue-cycle resilience, click here to read more from our team.