Test Fixture: Setup and Teardown
Problem
A small test runner runs tests one by one. For every test it prints setup, then run NAME, then passed NAME or failed NAME, and always teardown at the end, even if the test failed. Each input line is pass NAME or fail NAME (the test passes or fails). After the last test print passed=P failed=F.
Constraints
- 1 <= tests <= 100
- NAME has no spaces
Examples
Input
pass a fail b
Output
setup run a passed a teardown setup run b failed b teardown passed=1 failed=1
Solutions
The runner treats a thrown error as a failed test. The finally block makes sure that teardown runs after a pass and after a fail.
/*
* Problem : Run the tests.
* Input : Test lines.
* Output : The report lines.
* Approach: try/catch/finally
* Time : O(n)
* Space : O(n)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// This method solves the task. It receives the input and returns the answer.
static String[] solve(String[] lines) {
java.util.List<String> out = new java.util.ArrayList<String>();
int passed = 0;
int failed = 0;
for (String line : lines) {
String[] part = line.split(" ");
out.add("setup");
// Step 1: A failing test throws an error, like a real assertion does.
try {
out.add("run " + part[1]);
if (part[0].equals("fail")) {
throw new AssertionError("expected pass");
}
out.add("passed " + part[1]);
passed++;
} catch (AssertionError e) {
// Step 2: The runner records the failure and goes on with the next test.
out.add("failed " + part[1]);
failed++;
} finally {
// Step 3: Teardown always runs, so one failure cannot leave dirty state.
out.add("teardown");
}
}
out.add("passed=" + passed + " failed=" + failed);
return out.toArray(new String[0]);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
java.util.List<String> all = new java.util.ArrayList<>();
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (!line.isEmpty()) {
all.add(line);
}
}
String[] lines = all.toArray(new String[0]);
System.out.println(String.join("\n", solve(lines)));
}
}
Hints (2)
- Where must teardown be written?
- What does catch do with the error?