Why this matters
Dijkstra showed that testing can never prove a program correct — only that it hasn't been found incorrect yet. This shifts the scientific framing: programs are falsifiable hypotheses, and a test suite is the ongoing attempt to falsify them. A passing test suite doesn't mean your code is right; it means it hasn't been proven wrong yet.
This has a direct architectural consequence: if a module cannot be falsified easily, it is an architectural failure. Code that mixes I/O, parsing, validation, and network calls in a single function has too many reasons to be wrong and too many dependencies to be tested in isolation. Good architecture forces the important logic into pure, isolated units that can be probed from any angle with any input — making the hypothesis easy to attempt to falsify.
The problem
A function that reads a file, parses it, validates data, and sends email cannot be unit-tested without a real file system and a live SMTP server. It is architecturally unfalsifiable.
Bad
import smtplib, csv
def process_user_file(path: str) -> None:
with open(path) as f:
for row in csv.DictReader(f):
if "@" not in row["email"]:
raise ValueError(f"Bad email: {row['email']}")
with smtplib.SMTP("smtp.example.com") as smtp:
smtp.sendmail("no-reply@app.com", row["email"], "Welcome!")
async function processUserFile(path: string): Promise<void> {
const rows = parseCSV(fs.readFileSync(path, "utf8"));
for (const row of rows) {
if (!row.email.includes("@")) throw new Error(`Bad email: ${row.email}`);
await smtp.sendMail({ to: row.email, subject: "Welcome!" });
}
}
The solution
Extract the core logic into a pure function. Now it is fully falsifiable — any input, any environment, no infrastructure required.
Good
def is_valid_email(email: str) -> bool:
"""Pure function — testable with any input, no I/O, no side effects."""
return "@" in email and "." in email.split("@")[-1]
# Tests need nothing but the function itself
assert is_valid_email("user@example.com") is True
assert is_valid_email("not-an-email") is False
assert is_valid_email("missing@dot") is False
function isValidEmail(email: string): boolean {
const [local, domain] = email.split("@");
return !!local && !!domain && domain.includes(".");
}
// Falsifiable with any input — no mocks, no network, no files
console.assert(isValidEmail("user@example.com") === true);
console.assert(isValidEmail("not-an-email") === false);
Key takeaway
A function that cannot be tested in isolation is an architectural defect — the inability to falsify it is the symptom, and poor separation of concerns is the cause.