This walks through real output. The routine under test is a small amount classifier.
CREATE FUNCTION classify_amount(p_amount numeric) RETURNS text AS $$
BEGIN
IF p_amount < 0 THEN RETURN 'negative';
ELSIF p_amount = 0 THEN RETURN 'zero';
ELSIF p_amount < 100 THEN RETURN 'small';
ELSE RETURN 'large';
END IF;
END;
$$ LANGUAGE plpgsql;
Running unitautogen --schema public generated 11 tests at 100% branch and 100% statement coverage. Each decision got a true-side and a false-side test, and the routine's actual output was recorded as the expected value. Two of the generated tests follow.
-- test_08 : the "< 100" decision, TRUE side (input 1)
RETURN NEXT is( (public.classify_amount((1)::numeric))::text,
'small',
'branch :: ELSIF p_amount < 100 => TRUE :: returns' );
-- test_09 : the "< 100" decision, FALSE side (input 100)
RETURN NEXT is( (public.classify_amount((100)::numeric))::text,
'large',
'branch :: ELSIF p_amount < 100 => FALSE :: returns' );
ok 7 - test_classify_amount.test_07_branch_elsif_p_amount_0_false
ok 8 - test_classify_amount.test_08_branch_elsif_p_amount_100_true
ok 9 - test_classify_amount.test_09_branch_elsif_p_amount_100_false
ok 10 - test_classify_amount.test_10_returns_a_stable_result_set_shape
ok 11 - test_classify_amount.test_11_returns_rows_matching_baseline
1..11
test_09 calls classify_amount(100) and expects 'large'. The routine takes the ELSE branch for 100 and returns 'large', so the assertion holds. Each passing line means the routine still does, for that input, what it did when the test was written.
Now a developer renames the middle tier in a one-line change.
- ELSIF p_amount < 100 THEN RETURN 'small';
+ ELSIF p_amount < 100 THEN RETURN 'reduced';
Re-running the same, unchanged tests gives this.
ok 6 - test_classify_amount.test_06_branch_elsif_p_amount_0_true
not ok 7 - test_classify_amount.test_07_branch_elsif_p_amount_0_false
# Failed test 7: "branch :: ELSIF p_amount = 0 => FALSE :: returns"
# have: reduced
# want: small
not ok 8 - test_classify_amount.test_08_branch_elsif_p_amount_100_true
# Failed test 8: "branch :: ELSIF p_amount < 100 => TRUE :: returns"
# have: reduced
# want: small
ok 9 - test_classify_amount.test_09_branch_elsif_p_amount_100_false
not ok 11 - test_classify_amount.test_11_returns_rows_matching_baseline
# (re-bless: accept the new output as the baseline once it is intended)
1..11
# Looks like you failed 3 tests of 11
test_08 calls classify_amount(1) and still expects 'small', the value recorded when the test was generated. The routine now returns 'reduced', so pgTAP reports have reduced, want small. The test caught that the behaviour changed for an input it used to handle a certain way.
test_09 still passes, because the change did not touch the ELSE branch. A real behaviour change fails exactly the tests whose recorded result moved and leaves the rest green, so a failure points straight at what changed.
A freshly generated suite is always green, because the generator records the routine's current behaviour as the expected value and drops any test that will not pass cleanly. A failing test never appears in a first run. It appears later, when your code changes in a way that alters behaviour a test had pinned. That is what a regression test is for.