Testing and Debugging
Table Tests
A small table can run the same check over several inputs.
test case
Each row gives an input and the expected output.
failure count
Counting mismatches gives one summary result after all rows have run.
Table Tests
table_tests.c
Replay: real traced execution (multi-file project)
#include <stdio.h>
int clamp_low(int value) {
if (value < 0) {
return 0;
}
return value;
}
int main(void) {
int offset = 0;
int inputs[3] = {-2, 0, 5};
int expected[3] = {0, 0, 5};
int failures = 0;
for (int i = 0; i < 3; i++) {
int actual = clamp_low(inputs[i] + offset);
if (actual != expected[i]) {
failures = failures + 1;
}
}
printf("failures=%d\n", failures);
return 0;
}
#include <stdio.h>
int clamp_low(int value) {
if (value < 0) {
return 0;
}
return value;
}
int main(void) {
int offset = -1;
int inputs[3] = {-2, 0, 5};
int expected[3] = {0, 0, 5};
int failures = 0;
for (int i = 0; i < 3; i++) {
int actual = clamp_low(inputs[i] + offset);
if (actual != expected[i]) {
failures = failures + 1;
}
}
printf("failures=%d\n", failures);
return 0;
}
#include <stdio.h>
int clamp_low(int value) {
if (value < 0) {
return 0;
}
return value;
}
int main(void) {
int offset = 2;
int inputs[3] = {-2, 0, 5};
int expected[3] = {0, 0, 5};
int failures = 0;
for (int i = 0; i < 3; i++) {
int actual = clamp_low(inputs[i] + offset);
if (actual != expected[i]) {
failures = failures + 1;
}
}
printf("failures=%d\n", failures);
return 0;
}
offset ← 0, inputs ← ⟨addr A⟩, expected ← ⟨addr B⟩, failures ← 0
11int main(void) {12 int offset→ 0 = 0; //@offset=-1, 213 int inputs→ ⟨addr A⟩[3] = {-2, 0, 5};14 int expected→ ⟨addr B⟩[3] = {0, 0, 5};15 int failures→ 0 = 0;for (int i = 0; i < 3; i++)
pass 1 of 317for (int i0 = 0; i < 3; i++) {18 int actual = clamp_low(inputs[i]-2 + offset0);19 if (actual != expected[i]) {All 3 passes — pass 1 is the card above pass iinputs[i]value1 0 -2 -2 2 1 0 — 3 2 5 — int clamp_low(int value)
pass 1 of 33int clamp_low(int value-2) {4 if (value < 0) {All 3 passes — pass 1 is the card above pass value1 -2 2 0 3 5 if (value < 0)
3int clamp_low(int value) {4 if (value-2 < 0) {5 return 0;6 }actual ← 0
17for (int i = 0; i < 3; i++) {18 int actual→ 0 = clamp_low(inputs[i]-2 + offset0);19 if (actual != expected[i]) {actual ← 0
17for (int i = 0; i < 3; i++) {18 int actual→ 0 = clamp_low(inputs[i]0 + offset0);19 if (actual != expected[i]) {actual ← 5
17for (int i = 0; i < 3; i++) {18 int actual→ 5 = clamp_low(inputs[i]5 + offset0);19 if (actual != expected[i]) {printf("failures=%d ", failures);
24 printf("failures=%d\n", failures0);25 return 0;26}outputfailures=0
offset ← -1, inputs ← ⟨addr A⟩, expected ← ⟨addr B⟩, failures ← 0
11int main(void) {12 int offset→ -1 = -1;13 int inputs→ ⟨addr A⟩[3] = {-2, 0, 5};14 int expected→ ⟨addr B⟩[3] = {0, 0, 5};15 int failures→ 0 = 0;for (int i = 0; i < 3; i++)
pass 1 of 317for (int i0 = 0; i < 3; i++) {18 int actual = clamp_low(inputs[i]-2 + offset-1);19 if (actual != expected[i]) {All 3 passes — pass 1 is the card above pass iinputs[i]value1 0 -2 -3 2 1 0 -1 3 2 5 — int clamp_low(int value)
pass 1 of 33int clamp_low(int value-3) {4 if (value < 0) {All 3 passes — pass 1 is the card above pass value1 -3 2 -1 3 4 if (value < 0)
pass 1 of 23int clamp_low(int value) {4 if (value-3 < 0) {5 return 0;6 }actual ← 0
17for (int i = 0; i < 3; i++) {18 int actual→ 0 = clamp_low(inputs[i]-2 + offset-1);19 if (actual != expected[i]) {if (value < 0)
pass 2 of 23int clamp_low(int value) {4 if (value-1 < 0) {5 return 0;6 }actual ← 0
17for (int i = 0; i < 3; i++) {18 int actual→ 0 = clamp_low(inputs[i]0 + offset-1);19 if (actual != expected[i]) {actual ← 4
17for (int i = 0; i < 3; i++) {18 int actual→ 4 = clamp_low(inputs[i]5 + offset-1);19 if (actual != expected[i]) {failures ← 1
18int actual = clamp_low(inputs[i] + offset);19if (actual4 != expected[i]5) {20 failures→ 1 = failures + 1;21}printf("failures=%d ", failures);
24 printf("failures=%d\n", failures1);25 return 0;26}outputfailures=1
offset ← 2, inputs ← ⟨addr A⟩, expected ← ⟨addr B⟩, failures ← 0
11int main(void) {12 int offset→ 2 = 2;13 int inputs→ ⟨addr A⟩[3] = {-2, 0, 5};14 int expected→ ⟨addr B⟩[3] = {0, 0, 5};15 int failures→ 0 = 0;for (int i = 0; i < 3; i++)
pass 1 of 317for (int i0 = 0; i < 3; i++) {18 int actual = clamp_low(inputs[i]-2 + offset2);19 if (actual != expected[i]) {All 3 passes — pass 1 is the card above pass iinputs[i]1 0 -2 2 1 0 3 2 5 int clamp_low(int value)
pass 1 of 33int clamp_low(int value0) {4 if (value < 0) {5 return 0;6 }78 return value0;9}All 3 passes — pass 1 is the card above pass value1 0 2 2 3 7 actual ← 0
17for (int i = 0; i < 3; i++) {18 int actual→ 0 = clamp_low(inputs[i]-2 + offset2);19 if (actual != expected[i]) {actual ← 2
17for (int i = 0; i < 3; i++) {18 int actual→ 2 = clamp_low(inputs[i]0 + offset2);19 if (actual != expected[i]) {failures ← 1
pass 1 of 218int actual = clamp_low(inputs[i] + offset);19if (actual2 != expected[i]0) {20 failures→ 1 = failures + 1;21}actual ← 7
17for (int i = 0; i < 3; i++) {18 int actual→ 7 = clamp_low(inputs[i]5 + offset2);19 if (actual != expected[i]) {failures ← 2
pass 2 of 218int actual = clamp_low(inputs[i] + offset);19if (actual7 != expected[i]5) {20 failures→ 2 = failures + 1;21}printf("failures=%d ", failures);
24 printf("failures=%d\n", failures2);25 return 0;26}outputfailures=2
Exercise: table_tests.c
Add boundary and failure rows that make one broken implementation fail visibly