Skip to content

Commit 386a509

Browse files
committed
test: add unit tests for benchmark, coverage, parallel, and reports modules
- Add 16 tests for benchmark.sh (parse_annotations, add_result, print_results, run_function) - Add 25 tests for coverage.sh helper functions (get_coverage_class, calculate_percentage, html_escape, extract_functions, etc.) - Add 16 tests for parallel.sh (is_enabled, init/cleanup, stop_on_failure, aggregate_test_results) - Add 15 tests for reports.sh (wrapper functions, add_test, generate_junit_xml, generate_report_html) - Add benchmark fixture functions for edge case testing
1 parent 04d6e5b commit 386a509

File tree

5 files changed

+925
-8
lines changed

5 files changed

+925
-8
lines changed

tests/benchmark/fixtures/bashunit_sleep_bench.sh

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,32 @@ function bench_sleep() {
99
function bench_sleep_synonym() {
1010
sleep 0.005
1111
}
12+
13+
# No annotations - should use defaults (revs=1, its=1)
14+
function bench_no_annotations() {
15+
sleep 0.001
16+
}
17+
18+
# Only revs annotation
19+
# @revs=10
20+
function bench_only_revs() {
21+
sleep 0.001
22+
}
23+
24+
# Only its annotation
25+
# @its=5
26+
function bench_only_its() {
27+
sleep 0.001
28+
}
29+
30+
# Only max_ms annotation
31+
# @max_ms=100
32+
function bench_only_max_ms() {
33+
sleep 0.001
34+
}
35+
36+
# Slow function that will exceed threshold
37+
# @max_ms=1
38+
function bench_slow_for_threshold() {
39+
sleep 0.02
40+
}

tests/unit/benchmark_test.sh

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,225 @@ function test_run_function_collects_results() {
3232
assert_same "1" "${_BASHUNIT_BENCH_ITS[0]}"
3333
[[ -n "${_BASHUNIT_BENCH_AVERAGES[0]}" ]]
3434
}
35+
36+
# Parse annotations edge cases
37+
38+
function test_parse_annotations_returns_defaults_when_no_annotations() {
39+
assert_same "1 1" "$(bashunit::benchmark::parse_annotations bench_no_annotations "$SCRIPT")"
40+
}
41+
42+
function test_parse_annotations_with_only_revs() {
43+
assert_same "10 1" "$(bashunit::benchmark::parse_annotations bench_only_revs "$SCRIPT")"
44+
}
45+
46+
function test_parse_annotations_with_only_its() {
47+
assert_same "1 5" "$(bashunit::benchmark::parse_annotations bench_only_its "$SCRIPT")"
48+
}
49+
50+
function test_parse_annotations_with_only_max_ms() {
51+
assert_same "1 1 100" "$(bashunit::benchmark::parse_annotations bench_only_max_ms "$SCRIPT")"
52+
}
53+
54+
# Add result tests
55+
56+
function test_add_result_appends_to_arrays() {
57+
_BASHUNIT_BENCH_NAMES=()
58+
_BASHUNIT_BENCH_REVS=()
59+
_BASHUNIT_BENCH_ITS=()
60+
_BASHUNIT_BENCH_AVERAGES=()
61+
_BASHUNIT_BENCH_MAX_MILLIS=()
62+
63+
bashunit::benchmark::add_result "test_fn" "5" "3" "42.5" "100"
64+
65+
assert_same "test_fn" "${_BASHUNIT_BENCH_NAMES[0]}"
66+
assert_same "5" "${_BASHUNIT_BENCH_REVS[0]}"
67+
assert_same "3" "${_BASHUNIT_BENCH_ITS[0]}"
68+
assert_same "42.5" "${_BASHUNIT_BENCH_AVERAGES[0]}"
69+
assert_same "100" "${_BASHUNIT_BENCH_MAX_MILLIS[0]}"
70+
}
71+
72+
function test_add_result_handles_empty_max_ms() {
73+
_BASHUNIT_BENCH_NAMES=()
74+
_BASHUNIT_BENCH_REVS=()
75+
_BASHUNIT_BENCH_ITS=()
76+
_BASHUNIT_BENCH_AVERAGES=()
77+
_BASHUNIT_BENCH_MAX_MILLIS=()
78+
79+
bashunit::benchmark::add_result "test_fn" "2" "1" "10.0" ""
80+
81+
assert_same "test_fn" "${_BASHUNIT_BENCH_NAMES[0]}"
82+
assert_same "" "${_BASHUNIT_BENCH_MAX_MILLIS[0]}"
83+
}
84+
85+
# Print results tests
86+
87+
function test_print_results_returns_early_when_bench_mode_disabled() {
88+
function bashunit::env::is_bench_mode_enabled() { return 1; }
89+
90+
_BASHUNIT_BENCH_NAMES=("test_fn")
91+
local output
92+
output=$(bashunit::benchmark::print_results)
93+
94+
assert_empty "$output"
95+
}
96+
97+
function test_print_results_returns_early_when_no_results() {
98+
function bashunit::env::is_bench_mode_enabled() { return 0; }
99+
100+
_BASHUNIT_BENCH_NAMES=()
101+
local output
102+
output=$(bashunit::benchmark::print_results)
103+
104+
assert_empty "$output"
105+
}
106+
107+
function test_print_results_outputs_header_without_threshold() {
108+
function bashunit::env::is_bench_mode_enabled() { return 0; }
109+
function bashunit::env::is_simple_output_enabled() { return 1; }
110+
function bashunit::console_results::print_execution_time() { :; }
111+
function bashunit::print_line() { :; }
112+
113+
_BASHUNIT_BENCH_NAMES=("test_fn")
114+
_BASHUNIT_BENCH_REVS=("2")
115+
_BASHUNIT_BENCH_ITS=("1")
116+
_BASHUNIT_BENCH_AVERAGES=("10")
117+
_BASHUNIT_BENCH_MAX_MILLIS=("")
118+
119+
local output
120+
output=$(bashunit::benchmark::print_results)
121+
122+
assert_contains "Benchmark Results" "$output"
123+
assert_contains "Name" "$output"
124+
assert_contains "Revs" "$output"
125+
assert_contains "Its" "$output"
126+
assert_contains "Avg(ms)" "$output"
127+
assert_not_contains "Status" "$output"
128+
}
129+
130+
function test_print_results_outputs_header_with_threshold() {
131+
function bashunit::env::is_bench_mode_enabled() { return 0; }
132+
function bashunit::env::is_simple_output_enabled() { return 1; }
133+
function bashunit::console_results::print_execution_time() { :; }
134+
function bashunit::print_line() { :; }
135+
136+
_BASHUNIT_BENCH_NAMES=("test_fn")
137+
_BASHUNIT_BENCH_REVS=("2")
138+
_BASHUNIT_BENCH_ITS=("1")
139+
_BASHUNIT_BENCH_AVERAGES=("10")
140+
_BASHUNIT_BENCH_MAX_MILLIS=("100")
141+
142+
local output
143+
output=$(bashunit::benchmark::print_results)
144+
145+
assert_contains "Status" "$output"
146+
}
147+
148+
function test_print_results_outputs_row_without_threshold() {
149+
function bashunit::env::is_bench_mode_enabled() { return 0; }
150+
function bashunit::env::is_simple_output_enabled() { return 1; }
151+
function bashunit::console_results::print_execution_time() { :; }
152+
function bashunit::print_line() { :; }
153+
154+
_BASHUNIT_BENCH_NAMES=("my_test")
155+
_BASHUNIT_BENCH_REVS=("5")
156+
_BASHUNIT_BENCH_ITS=("3")
157+
_BASHUNIT_BENCH_AVERAGES=("25")
158+
_BASHUNIT_BENCH_MAX_MILLIS=("")
159+
160+
local output
161+
output=$(bashunit::benchmark::print_results)
162+
163+
assert_contains "my_test" "$output"
164+
assert_contains "5" "$output"
165+
assert_contains "3" "$output"
166+
assert_contains "25" "$output"
167+
}
168+
169+
function test_print_results_outputs_passing_threshold_status() {
170+
function bashunit::env::is_bench_mode_enabled() { return 0; }
171+
function bashunit::env::is_simple_output_enabled() { return 1; }
172+
function bashunit::console_results::print_execution_time() { :; }
173+
function bashunit::print_line() { :; }
174+
175+
_BASHUNIT_BENCH_NAMES=("fast_fn")
176+
_BASHUNIT_BENCH_REVS=("1")
177+
_BASHUNIT_BENCH_ITS=("1")
178+
_BASHUNIT_BENCH_AVERAGES=("10")
179+
_BASHUNIT_BENCH_MAX_MILLIS=("100")
180+
181+
local output
182+
output=$(bashunit::benchmark::print_results)
183+
184+
assert_contains "≤ 100" "$output"
185+
}
186+
187+
function test_print_results_outputs_failing_threshold_status() {
188+
function bashunit::env::is_bench_mode_enabled() { return 0; }
189+
function bashunit::env::is_simple_output_enabled() { return 1; }
190+
function bashunit::console_results::print_execution_time() { :; }
191+
function bashunit::print_line() { :; }
192+
193+
_BASHUNIT_BENCH_NAMES=("slow_fn")
194+
_BASHUNIT_BENCH_REVS=("1")
195+
_BASHUNIT_BENCH_ITS=("1")
196+
_BASHUNIT_BENCH_AVERAGES=("200")
197+
_BASHUNIT_BENCH_MAX_MILLIS=("100")
198+
199+
local output
200+
output=$(bashunit::benchmark::print_results)
201+
202+
assert_contains "> 100" "$output"
203+
}
204+
205+
function test_print_results_adds_newline_in_simple_mode() {
206+
function bashunit::env::is_bench_mode_enabled() { return 0; }
207+
function bashunit::env::is_simple_output_enabled() { return 0; }
208+
function bashunit::console_results::print_execution_time() { :; }
209+
function bashunit::print_line() { :; }
210+
211+
_BASHUNIT_BENCH_NAMES=("test_fn")
212+
_BASHUNIT_BENCH_REVS=("1")
213+
_BASHUNIT_BENCH_ITS=("1")
214+
_BASHUNIT_BENCH_AVERAGES=("10")
215+
_BASHUNIT_BENCH_MAX_MILLIS=("")
216+
217+
local output
218+
output=$(bashunit::benchmark::print_results)
219+
220+
# Simple mode adds an extra newline at the start
221+
assert_contains "Benchmark Results" "$output"
222+
}
223+
224+
# Run function additional tests
225+
226+
function test_run_function_stores_max_ms() {
227+
# shellcheck disable=SC1090
228+
source "$SCRIPT"
229+
230+
_BASHUNIT_BENCH_NAMES=()
231+
_BASHUNIT_BENCH_REVS=()
232+
_BASHUNIT_BENCH_ITS=()
233+
_BASHUNIT_BENCH_AVERAGES=()
234+
_BASHUNIT_BENCH_MAX_MILLIS=()
235+
236+
bashunit::benchmark::run_function bench_sleep 1 1 "50"
237+
238+
assert_same "50" "${_BASHUNIT_BENCH_MAX_MILLIS[0]}"
239+
}
240+
241+
function test_run_function_with_multiple_iterations() {
242+
# shellcheck disable=SC1090
243+
source "$SCRIPT"
244+
245+
_BASHUNIT_BENCH_NAMES=()
246+
_BASHUNIT_BENCH_REVS=()
247+
_BASHUNIT_BENCH_ITS=()
248+
_BASHUNIT_BENCH_AVERAGES=()
249+
_BASHUNIT_BENCH_MAX_MILLIS=()
250+
251+
bashunit::benchmark::run_function bench_sleep 1 3 ""
252+
253+
assert_same "bench_sleep" "${_BASHUNIT_BENCH_NAMES[0]}"
254+
assert_same "3" "${_BASHUNIT_BENCH_ITS[0]}"
255+
[[ -n "${_BASHUNIT_BENCH_AVERAGES[0]}" ]]
256+
}

0 commit comments

Comments
 (0)