Positive, Negative & Edge Case Testing
Comprehensive test coverage requires testing three categories: positive cases (happy paths), negative cases (error paths), and edge cases (boundary conditions). Most beginners test only positive cases — which is exactly why 80% of production bugs are found in negative and edge scenarios.
The Three Categories
- Positive Testing: Valid inputs, expected usage, happy path. Tests that the system works correctly under normal conditions.
- Negative Testing: Invalid inputs, unexpected usage, error paths. Tests that the system handles bad data gracefully.
- Edge Case Testing: Boundary values, extreme inputs, unusual combinations. Tests the system at its limits.
- Coverage Ratio (rule of thumb): For every 1 positive test, write 2-3 negative tests and 2-3 edge case tests.
All Three Categories for a User Age Field
// Feature: User registration form with age field
// Requirement: Age must be between 18 and 120 (inclusive)
// ══════════════════════════════════════════════════════════════
// POSITIVE TESTS — valid inputs, should SUCCEED
// ══════════════════════════════════════════════════════════════
test("positive: age 25 — typical user age", () => {
expect(validateAge(25)).toBe(true);
});
test("positive: age 18 — minimum valid age", () => {
expect(validateAge(18)).toBe(true);
});
test("positive: age 120 — maximum valid age", () => {
expect(validateAge(120)).toBe(true);
});
// ══════════════════════════════════════════════════════════════
// NEGATIVE TESTS — invalid inputs, should FAIL gracefully
// ══════════════════════════════════════════════════════════════
test("negative: age 17 — below minimum", () => {
expect(validateAge(17)).toBe(false);
});
test("negative: age 121 — above maximum", () => {
expect(validateAge(121)).toBe(false);
});
test("negative: age -5 — negative number", () => {
expect(validateAge(-5)).toBe(false);
});
test("negative: age 'abc' — non-numeric string", () => {
expect(validateAge("abc")).toBe(false);
});
test("negative: age null — null value", () => {
expect(validateAge(null)).toBe(false);
});
test("negative: age empty string", () => {
expect(validateAge("")).toBe(false);
});
test("negative: age undefined", () => {
expect(validateAge(undefined)).toBe(false);
});
// ══════════════════════════════════════════════════════════════
// EDGE CASES — boundaries and unusual values
// ══════════════════════════════════════════════════════════════
test("edge: age 0 — zero value", () => {
expect(validateAge(0)).toBe(false);
});
test("edge: age 17.9 — float just under 18", () => {
expect(validateAge(17.9)).toBe(false);
});
test("edge: age 18.0 — float exact minimum", () => {
expect(validateAge(18.0)).toBe(true); // should be true
});
test("edge: age 1000000 — very large number", () => {
expect(validateAge(1000000)).toBe(false);
});
test("edge: age Infinity", () => {
expect(validateAge(Infinity)).toBe(false);
});
test("edge: age NaN", () => {
expect(validateAge(NaN)).toBe(false);
});
// The implementation that passes all these:
function validateAge(age) {
if (age === null || age === undefined || typeof age !== "number") return false;
if (isNaN(age) || !isFinite(age)) return false;
return age >= 18 && age <= 120;
}Common Mistakes
- Only positive testing — the most common mistake; beginners test the happy path and call it done
- Vague negative tests — 'test with invalid data' is not testable; specify exactly what invalid data (null, empty, out-of-range, wrong type)
- Missing edge cases at the exact boundary — test 17, 18, and 19 (not just 'a number under 18'); boundary bugs are extremely common
- Ignoring null/undefined/empty — these three alone cause 30% of production JavaScript runtime errors
Tip
Tip
Practice Positive Negative Edge Case Testing in small, isolated examples before integrating into larger projects. Breaking concepts into small experiments builds genuine understanding faster than reading alone.
Technical diagram.
Practice Task
Note
Practice Task — (1) Write a working example of Positive Negative Edge Case Testing from scratch without looking at notes. (2) Modify it to handle an edge case (empty input, null value, or error state). (3) Share your solution in the Priygop community for feedback.
Quick Quiz
Common Mistake
Warning
A common mistake with Positive Negative Edge Case Testing is skipping edge case testing — empty inputs, null values, and unexpected data types. Always validate boundary conditions to write robust, production-ready software testing code.
Key Takeaways
- Comprehensive test coverage requires testing three categories: positive cases (happy paths), negative cases (error paths), and edge cases (boundary conditions).
- Positive Testing: Valid inputs, expected usage, happy path. Tests that the system works correctly under normal conditions.
- Negative Testing: Invalid inputs, unexpected usage, error paths. Tests that the system handles bad data gracefully.
- Edge Case Testing: Boundary values, extreme inputs, unusual combinations. Tests the system at its limits.