Skip to content

Commit 579fa9b

Browse files
abueideclaude
andcommitted
refactor(tests): consolidate test framework and use example project fixtures
Replace inline test frameworks across all 12 test files with a single shared test-framework.sh. Add missing assertion functions, fixture helpers pointing at example project device configs, and project-local temp directories (reports/tmp/) instead of /tmp/. Fix 2 failing android path resolution tests by unsetting ANDROID_CONFIG_DIR before the test block (matching existing iOS pattern). Delete unused tests/fixtures/ directory—example projects serve as the canonical test fixtures for read-only tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 37b500f commit 579fa9b

19 files changed

Lines changed: 480 additions & 1305 deletions

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@
2323
*.cache
2424
.claude/
2525

26-
# Test results (only last run kept locally)
26+
# Test results and temp dirs (only last run kept locally)
2727
/reports/
28+
/reports/tmp/
2829
/test-results/
2930
tests/test-results/
3031
examples/*/reports/

plugins/tests/README.md

Lines changed: 63 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,21 @@ This directory contains **pure unit tests** for plugin scripts. These tests veri
77
```
88
plugins/tests/
99
├── android/
10-
│ ├── test-lib.sh # Tests for lib.sh utility functions
11-
│ └── test-devices.sh # Tests for devices.sh CLI parsing
10+
│ ├── test-lib.sh # Tests for lib.sh utility functions
11+
│ ├── test-devices.sh # Tests for devices.sh CLI parsing
12+
│ ├── test-apk-detection.sh # Tests for APK metadata extraction
13+
│ ├── test-apk-resolution.sh # Tests for APK auto-detection
14+
│ ├── test-emulator-detection.sh # Emulator detection tests
15+
│ └── test-emulator-modes.sh # Emulator mode behavior docs
1216
├── ios/
13-
│ └── test-lib.sh # Tests for lib.sh utility functions
14-
└── test-framework.sh # Shared test utilities
17+
│ ├── test-lib.sh # Tests for lib.sh utility functions
18+
│ ├── test-devices.sh # Tests for devices.sh CLI parsing
19+
│ ├── test-app-resolution.sh # Tests for .app auto-detection
20+
│ ├── test-simulator-detection.sh # Simulator detection tests
21+
│ └── test-simulator-modes.sh # Simulator mode behavior docs
22+
├── react-native/
23+
│ └── test-lib.sh # Tests for Metro port management
24+
└── test-framework.sh # Shared test utilities
1525
```
1626

1727
## Running Tests
@@ -51,45 +61,79 @@ devbox run test:plugin:ios:lib
5161
- Config directory resolution
5262
- Requirement validation
5363

64+
### React Native (`test-lib.sh`)
65+
- Metro port allocation and retrieval
66+
- Metro environment file management
67+
- PID tracking
68+
- Suite isolation
69+
5470
## Test Framework
5571

56-
All tests use `test-framework.sh` utilities:
72+
All tests source `test-framework.sh` which provides assertions, fixture helpers, and test summary reporting.
5773

5874
```bash
5975
#!/usr/bin/env bash
6076
set -euo pipefail
6177

62-
# Source test framework
63-
. "path/to/test-framework.sh"
78+
script_dir="$(cd "$(dirname "$0")" && pwd)"
79+
. "$script_dir/../test-framework.sh"
80+
setup_logging
6481

6582
# Write tests
66-
assert_equal "expected" "$(my_function)"
67-
assert_command_success "Test description" my_command arg1 arg2
68-
assert_file_exists "path/to/file"
83+
start_test "My feature"
84+
assert_equal "expected" "$(my_function)" "Description"
85+
assert_success "some_command" "Should succeed"
86+
assert_failure "bad_command" "Should fail"
87+
88+
# Use example project fixtures for read-only tests
89+
devices_dir="$(fixture_android_devices_dir)"
90+
91+
# Use project-local temp dirs for write tests
92+
temp="$(make_temp_dir "my-test")"
93+
# ... use temp dir ...
94+
rm -rf "$temp"
6995

7096
# Show summary
71-
test_summary
97+
test_summary "suite-name"
7298
```
7399

100+
### Available Assertions
101+
102+
- `assert_equal expected actual message` - Value equality
103+
- `assert_success "cmd" message` - Command succeeds (eval-based)
104+
- `assert_failure "cmd" message` - Command fails (eval-based)
105+
- `assert_not_empty value message` - Value is non-empty
106+
- `assert_contains haystack needle message` - String contains substring
107+
- `assert_output "cmd" expected message` - Command output contains string
108+
- `assert_file_exists path message` - File exists
109+
- `assert_file_contains path pattern message` - File contains pattern
110+
- `assert_command_success message cmd args...` - Command succeeds (direct)
111+
112+
### Fixture Helpers
113+
114+
- `fixture_android_devices_dir` - Path to `examples/android/devbox.d/android/devices`
115+
- `fixture_ios_devices_dir` - Path to `examples/ios/devbox.d/ios/devices`
116+
- `make_temp_dir label` - Creates dir under `reports/tmp/` (project-local)
117+
74118
## Adding New Tests
75119

76120
1. Create test file in appropriate directory (`plugins/tests/{platform}/`)
77-
2. Use `test-framework.sh` utilities
78-
3. Add command to `devbox.json` if needed
79-
4. Ensure tests run in isolation (no external dependencies)
121+
2. Source `test-framework.sh` and call `setup_logging`
122+
3. Use example project fixtures for read-only tests, `make_temp_dir` for write tests
123+
4. Call `test_summary "suite-name"` at the end
124+
5. Add command to `devbox.json` if needed
80125

81126
## Guidelines
82127

83128
- **Pure unit tests only** - Test individual functions directly
84-
- **No integration** - Integration tests are in `/tests/integration/`
129+
- **No /tmp/** - Use `make_temp_dir()` for project-local temp directories
130+
- **Example fixtures** - Use `fixture_*_devices_dir()` for read-only device config tests
85131
- **Fast execution** - All tests should run in under 30 seconds total
86-
- **Isolated** - Tests should not depend on external state or example projects
87-
- **Self-contained** - Create any needed test data inline or in the test file
132+
- **Isolated** - Tests clean up after themselves
88133

89134
## Related Testing
90135

91-
- **Integration tests**: `/tests/integration/` - Test plugin workflows with fixtures
136+
- **Integration tests**: `/tests/integration/` - Test plugin workflows
92137
- **E2E tests**: `/tests/e2e/` - Test full application lifecycle
93-
- **Test fixtures**: `/tests/fixtures/` - Shared test data for integration tests
94138

95139
See `/tests/README.md` for complete testing guide.

plugins/tests/android/test-apk-detection.sh

Lines changed: 5 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -6,123 +6,14 @@
66

77
set -euo pipefail
88

9-
# Setup logging
10-
SCRIPT_DIR_NAME="$(basename "$(dirname "$0")")"
11-
SCRIPT_NAME="$(basename "$0" .sh)"
12-
mkdir -p "${TEST_LOGS_DIR:-reports/logs}"
13-
LOG_FILE="${TEST_LOGS_DIR:-reports/logs}/${SCRIPT_DIR_NAME}-${SCRIPT_NAME}.txt"
14-
exec > >(tee "$LOG_FILE")
15-
exec 2>&1
16-
17-
# ============================================================================
18-
# Test Framework
19-
# ============================================================================
20-
21-
test_passed=0
22-
test_failed=0
23-
test_name=""
24-
25-
start_test() {
26-
test_name="$1"
27-
echo ""
28-
echo "TEST: $test_name"
29-
}
30-
31-
assert_equal() {
32-
expected="$1"
33-
actual="$2"
34-
message="${3:-}"
35-
36-
if [ "$expected" = "$actual" ]; then
37-
echo " PASS${message:+: $message}"
38-
test_passed=$((test_passed + 1))
39-
else
40-
echo " FAIL${message:+: $message}"
41-
echo " Expected: '$expected'"
42-
echo " Actual: '$actual'"
43-
test_failed=$((test_failed + 1))
44-
fi
45-
}
46-
47-
assert_not_empty() {
48-
actual="$1"
49-
message="${2:-}"
50-
51-
if [ -n "$actual" ]; then
52-
echo " PASS${message:+: $message}"
53-
test_passed=$((test_passed + 1))
54-
else
55-
echo " FAIL${message:+: $message}"
56-
echo " Value was empty"
57-
test_failed=$((test_failed + 1))
58-
fi
59-
}
60-
61-
assert_success() {
62-
command_str="$1"
63-
message="${2:-}"
64-
65-
if eval "$command_str" >/dev/null 2>&1; then
66-
echo " PASS${message:+: $message}"
67-
test_passed=$((test_passed + 1))
68-
else
69-
echo " FAIL${message:+: $message}"
70-
echo " Command failed: $command_str"
71-
test_failed=$((test_failed + 1))
72-
fi
73-
}
74-
75-
assert_failure() {
76-
command_str="$1"
77-
message="${2:-}"
78-
79-
if ! (eval "$command_str") >/dev/null 2>&1; then
80-
echo " PASS${message:+: $message}"
81-
test_passed=$((test_passed + 1))
82-
else
83-
echo " FAIL${message:+: $message}"
84-
echo " Command should have failed: $command_str"
85-
test_failed=$((test_failed + 1))
86-
fi
87-
}
88-
89-
test_summary() {
90-
total=$((test_passed + test_failed))
91-
echo ""
92-
echo "========================================"
93-
echo "Test Summary"
94-
echo "========================================"
95-
echo "Total: $total"
96-
echo "Passed: $test_passed"
97-
echo "Failed: $test_failed"
98-
echo ""
99-
100-
# Write results file for summary aggregation
101-
results_dir="${TEST_RESULTS_DIR:-$(cd "$(dirname "$0")/../../../reports/results" 2>/dev/null && pwd || echo "/tmp")}"
102-
mkdir -p "$results_dir" 2>/dev/null || true
103-
cat > "$results_dir/android-apk-detection.json" << EOF
104-
{
105-
"suite": "android-apk-detection",
106-
"passed": $test_passed,
107-
"failed": $test_failed,
108-
"total": $total
109-
}
110-
EOF
111-
112-
if [ "$test_failed" -gt 0 ]; then
113-
echo "RESULT: FAILED"
114-
exit 1
115-
else
116-
echo "RESULT: ALL PASSED"
117-
exit 0
118-
fi
119-
}
9+
script_dir="$(cd "$(dirname "$0")" && pwd)"
10+
. "$script_dir/../test-framework.sh"
11+
setup_logging
12012

12113
# ============================================================================
12214
# Setup
12315
# ============================================================================
12416

125-
script_dir="$(cd "$(dirname "$0")" && pwd)"
12617
deploy_path="$script_dir/../../android/virtenv/scripts/domain/deploy.sh"
12718
lib_path="$script_dir/../../android/virtenv/scripts/lib/lib.sh"
12819
core_path="$script_dir/../../android/virtenv/scripts/platform/core.sh"
@@ -215,8 +106,7 @@ assert_failure "android_resolve_apk_glob '$script_dir/fixtures' 'nonexistent-*.a
215106
# ============================================================================
216107

217108
start_test "deploy saves app-id.txt after metadata extraction"
218-
test_runtime="/tmp/android-apk-test-$$"
219-
mkdir -p "$test_runtime"
109+
test_runtime="$(make_temp_dir "android-apk")"
220110
ANDROID_RUNTIME_DIR="$test_runtime" ANDROID_USER_HOME="$test_runtime"
221111

222112
# Simulate what android_run_app does after extraction
@@ -239,4 +129,4 @@ rm -rf "$test_runtime"
239129
# Summary
240130
# ============================================================================
241131

242-
test_summary
132+
test_summary "android-apk-detection"

0 commit comments

Comments
 (0)