November 1, 2023

A good test case tells one person exactly what to do, what to expect, and how to tell whether the software passed. That is the whole job. Writing test cases well is mostly about being specific enough that a stranger can run yours and get the same answer you would.
Most suites fail that test. Someone opens a case written eighteen months ago, follows the steps, and cannot tell whether the result counts as a pass. The original author left the company. The expected result says the system responds correctly. Nobody knows what correctly meant, so the case gets marked passed and the suite quietly loses a little more value.
This guide gives you the format and a weak case rewritten into a strong one. It covers the design techniques that decide what to test. It ends with a review checklist to run before any case joins your suite.
A test case has a fixed set of fields. What separates a useful one from a useless one is how each field gets filled.
| Field | What Goes In It | The Common Mistake |
|---|---|---|
| Test case ID | A stable unique identifier | Renumbering it, which breaks every link pointing at it |
| Title | The outcome being proved, in one line | Naming the feature instead of the behavior |
| Preconditions | Everything true before step one | Leaving out account state or required data |
| Test data | The exact values used | Writing valid data and expecting people to guess |
| Steps | One action each, numbered | Bundling three actions into one line |
| Expected result | Something observable | A judgment like works correctly |
| Priority | How much a failure costs | Marking everything high, which means nothing is |
| Requirement link | The requirement this proves | Leaving it blank, which makes coverage unmeasurable |
Two fields carry most of the weight. The expected result decides whether anyone can judge a pass. The preconditions decide whether the case runs at all.
Everything else is organization. Useful organization, but you can recover from a bad title. You cannot recover from an expected result nobody can check.
A short note on IDs. Give every case a stable identifier that never changes, even when the case is rewritten. Defect reports and traceability links point at that ID, and renumbering breaks both.
Keep the format identical across the whole suite. Consistency is what lets someone scan forty cases quickly instead of reading each one carefully. Our software testing services team sets that format once at the start of an engagement rather than letting it drift per tester.
Abstract advice about clarity does not help much. Here is the same case written twice.
Title: Login test
Preconditions: User exists
Steps: Go to the site. Log in.
Expected result: Login works correctly.
Four problems sit in those four lines. The title does not say which login behavior. The precondition does not say what kind of user. The steps assume the reader knows the URL, the field names, and what credentials to use. And the expected result cannot be judged by anyone who was not in the room.
Title: Valid credentials log a standard user into the dashboard
Preconditions: An active standard user account exists with a verified email and no multi-factor prompt enabled.
Test data: Email is a valid registered address. Password is the current valid password for that account.
Steps: One, open the login page. Two, enter the registered email in the Email field. Three, enter the valid password in the Password field. Four, select Sign in.
Expected result: The dashboard loads within five seconds. The header shows the user's display name. No error message appears.
The second version is longer, and that length is the point. Every ambiguity that would have cost a tester five minutes is now resolved on the page.
Notice what changed most. The expected result went from a judgment to three observable facts. Someone can check each one without asking anybody.
The title changed almost as much. Login test tells you nothing about what should happen. The rewritten title is a claim that the case either proves or disproves.
Test data moved out of the steps and into its own field. That single move makes the case reusable against a different account without touching the steps.
Work in this order. Skipping ahead is what produces cases that need rewriting.
That last step is the one teams skip, and it is the cheapest quality check available. A case that survives one fresh reader will survive a year of execution.
Work in small batches rather than writing forty cases at once. Patterns you get wrong show up faster, and fixing five cases beats fixing forty. Platform documentation such as Salesforce Developers is worth checking when your cases sit on top of a vendor platform with its own testing rules.
Format tells you how to write a case. Design techniques tell you which cases are worth writing.
The value here is not memorizing the list. It is knowing which technique fits the input you are looking at.
| Technique | Use It When | What It Gives You |
|---|---|---|
| Equivalence partitioning | An input accepts a range or a set of valid groups | One case per group instead of one per value |
| Boundary value analysis | The input has limits, minimums, or maximums | Cases at the edge, where defects actually cluster |
| Decision table | Several conditions combine to drive one outcome | Every rule combination covered, none missed |
| State transition | The feature moves through defined states | Cases for valid moves and the invalid ones |
| Pairwise testing | Many settings combine into too many permutations | Broad coverage from a fraction of the combinations |
| Error guessing | You know from experience where this breaks | Cases the formal techniques would never generate |
Most teams need three of these regularly. Equivalence partitioning and boundary value analysis cover the majority of input fields. Decision tables handle anything with combined rules.
Reach for the others when the shape of the problem calls for them. A multi-step wizard wants state transition. A settings screen with many toggles wants pairwise.
Error guessing deserves a mention even though it looks unscientific. Experienced testers know where a product tends to break, and cases built on that instinct catch real defects.
Use it alongside the formal techniques, never instead of them. Instinct finds the odd bug. Structure finds the systematic gap. Practitioner guides on SaaSGuru are a reasonable starting point if your team is learning these for the first time.
This is the question that divides teams, and the honest answer is that it depends on who runs the case.
Write more detail when the runner is new, when the domain is unfamiliar, when a regulator may read it, or when the case will feed an automated script.
Write less when an experienced tester who knows the product runs it daily. Prescribing every click to someone who built the feature wastes everyone's time and creates maintenance you do not need.
A practical rule. Detail the things that change the outcome. Skip the things that do not. Nobody needs to be told to open a browser.
Test data and expected results always get full detail. Navigation steps rarely do.
One more factor decides this. How often will the case run. A case executed every release deserves the detail that keeps it stable. A one-off exploratory check does not need the same treatment.
When in doubt, write for the person who joins your team next month. They are the real audience for everything you document. Discussions on Trailblazer Community show how differently teams land on this depending on their regulatory context.
Most cases get written for a human and later handed to someone automating them. That handoff is where a lot of rework happens.
A few habits make a manual case automation-ready without adding much effort.
Keep one behavior per case. Automated tests that check six things fail without telling you which one broke.
Make the case self-contained. It should create the data it needs and leave the system as it found it. Cases that depend on the previous case running first break the moment you run them in parallel.
Name the elements you interact with, not their position on the screen. The Sign in button survives a redesign. The second button on the right does not.
State the expected result as data, not appearance. A confirmation record exists is checkable by a script. The page looks right is not.
Write the teardown too. A case that creates an order should say what happens to that order afterward, because an automated suite will run it hundreds of times.
Our walkthrough on building a test automation framework covers how cases written this way turn into scripts that stay maintainable. The habits cost nothing at writing time and save a full rewrite later. Practitioner notes on SFDC Fanboy cover the same handoff from the developer side.
Run these questions over every new case. It takes two minutes and saves hours later.
That last question matters more than people expect. Duplicate cases are how suites grow without coverage improving, and our guide to the test management process covers the cleanup rhythm that keeps them out.
There is no target number, and any article giving you one is guessing.
The suite is the right size when every requirement has at least one linked case, no two cases check the same thing, and the whole set can run inside your release window.
Coverage by case count is a misleading metric. Two hundred shallow cases against forty requirements means little. Forty sharp cases against forty requirements means a great deal.
Write for requirements, not for volume. Then delete the cases that stop earning their place.
Risk should shape the distribution. A payment flow deserves many cases across many inputs. A rarely used settings page deserves one or two.
Spreading cases evenly across features feels fair and tests badly. Put the depth where a failure would actually hurt, which is the same logic our post on saving time and money with automated software testing applies to automation scope.
We treat test cases as engineering artifacts rather than documentation. A case that cannot be run by someone new, or converted to a script without a rewrite, has not been finished.
Our engineers write against requirements first, then apply design techniques to decide which inputs actually need a case. That order keeps suites small and coverage honest.
Every case we write is built to be automated later, even when it starts manual. Self-contained data, named elements, and observable results mean the handoff costs hours rather than weeks.
We also hand over the review checklist and the naming conventions, so your team keeps writing cases the same way after we leave.
When we inherit an existing suite, the first pass is usually subtraction. Duplicate cases come out, vague expected results get rewritten, and what remains is smaller and far more useful.
A test scenario names what to test at a high level, such as verifying login. A test case gives the exact steps, data, and expected result for one specific path through it. One scenario usually produces several cases.
Writing them alongside the requirement works best. It surfaces ambiguity while there is still time to fix the requirement, which is cheaper than finding it during execution.
Detailed enough that someone unfamiliar with the feature gets the same result you would. Test data and expected results always need full detail. Navigation usually does not.
Whoever understands the requirement best, reviewed by someone who does not. Testers write most of them, but developers writing cases for their own code catches a different class of gap.
Review the cases touching a feature whenever that feature changes. Review the whole suite once a quarter, looking for duplicates and cases that no longer match the product.
Writing test cases well comes down to one habit. Make every field specific enough that a stranger gets your answer without asking you a question. Format, design techniques, and review checklists all exist to serve that single goal, and a suite that meets it keeps its value long after the people who wrote it move on.
Minuscule Technologies approaches testing as an engineering discipline rather than a documentation exercise. Our engineers write cases against requirements, apply design techniques to keep the set small, and build every case so it converts to an automated script without a rewrite. You end up with fewer cases covering more of what matters.
What you get back is a suite your team can run, review, and extend on its own. The conventions and the review checklist are handed over, not held, so quality holds after the engagement ends. Book a free strategic call with our testing engineers and we will review your current cases with you.
You've seen what's possible. Now, let's make it happen for your business. Whether you need an end-to-end Salesforce solution, a complex integration, or ongoing managed services, our team is ready to deliver.
Schedule a Free Strategic Call