Trying random things until software breaks will find some problems. Designing tests on purpose finds far more, with far fewer tries. This step in our software testing learning path shows how professionals do it, using one small example from start to finish.
If you are new to testing, read What Is Software Testing? and Errors, Defects, and Failures first.
The parts of a test case
A test case is a written description of one test, clear enough that someone else could run it and get the same answer. Teams format them differently, but almost every test case includes:
- ID and title. A short name that says what is being checked, such as "TC-04: Username at maximum length is accepted."
- Preconditions. What must already be true before you start: "The sign-up page is open. No account exists for this email."
- Steps. Exactly what to do, in order.
- Test data. The specific values to use.
- Expected result. What should happen if the software works correctly.
After running it, the tester records the actual result and whether the test passed or failed. Writing the expected result before running the test matters: it stops you from deciding after the fact that whatever happened was probably fine.
The example: a sign-up form
Imagine a sign-up form with one rule for usernames:
A username must be between 3 and 20 characters long.
How many tests would you write? You cannot try every possible username. There are effectively infinite. Two techniques help you pick a small set that covers the important possibilities.
Technique 1: equivalence partitioning
The idea: group inputs that the software should treat the same way, then test one value from each group. If one value in a group works, the others very likely do too, because the program handles them with the same logic.
For our username rule there are three groups, called partitions:
| Partition | Lengths | Should the form accept it? | Example value |
|---|---|---|---|
| Too short | 0 to 2 characters | No | ab |
| Valid | 3 to 20 characters | Yes | riverstone (10) |
| Too long | 21 or more characters | No | a 25-character name |
Three tests already cover a lot of ground: one too short, one valid, one too long.
Technique 2: boundary value analysis
Experience shows that defects cluster at the edges of each group. A programmer who meant "3 or more" might accidentally write "more than 3", which wrongly rejects a 3-character name. Boundary value analysis tests the values right at and next to each edge.
The boundaries in our rule sit at 3 and 20. So we test:
| Length | Why | Expected result |
|---|---|---|
| 2 | Just below the lower edge | Rejected |
| 3 | Exactly the lower edge | Accepted |
| 20 | Exactly the upper edge | Accepted |
| 21 | Just above the upper edge | Rejected |
These four tests are the ones most likely to catch an off-by-one mistake, one of the most common defects in all of programming.
Putting it together
Combining both techniques gives a compact, powerful set:
| ID | Test data (length) | Expected result |
|---|---|---|
| TC-01 | 0 (empty) | Rejected, with a message explaining the rule |
| TC-02 | 2 | Rejected |
| TC-03 | 3 | Accepted |
| TC-04 | 10 | Accepted |
| TC-05 | 20 | Accepted |
| TC-06 | 21 | Rejected |
Six tests, chosen for a reason, instead of dozens chosen at random. Notice that TC-01 also checks the error message. A form that rejects bad input but never tells the user why has a usability problem, and that is worth finding too.
Thinking beyond the written rule
The rule only mentions length. A thoughtful tester also asks questions the rule does not answer:
- What about spaces, emoji, or letters from other alphabets?
- Is
Riverstonethe same username asriverstone? - What happens if two people try to claim the same name at the same moment?
- Does the length count characters or bytes? Some characters take more space than others.
Each question is either a new test or a gap in the requirements that someone needs to decide. Raising those questions early is one of the most valuable things a tester does.
Try it yourself
Pick a rule from a form you know, such as "a password must be 8 to 64 characters" or "age must be 13 or older." Write down the partitions and the boundary values, then write four to six test cases using the format above. If you can, run them against a real site and record what actually happens.
When you are ready to go further, our QA Library has free test case templates that professional teams use. The next step in this path covers what to do when a test fails: writing a bug report that actually gets the problem fixed.