flaky-test-finder
Skill1 starsChanged 7 months agoMITView on GitHub
Run a named Apex test class N times against the target org and report tests with non-deterministic results. Useful when a test fails intermittently in CI but passes locally — runs prove flakiness.
In this repository53 other files it gives its agents.
- templates/CLAUDE.mdCLAUDE.md
- adrSkill
- agent-deploySkill
- agent-discoverSkill
- agent-eval-trendSkill
- agent-exchange-listSkill
- agent-specSkill
- agent-testSkill
- agent-vs-flow-vs-apexSkill
- before-vs-after-triggerSkill
- code-reviewSkill
- complexitySkill
- coverage-trendSkill
- dead-codeSkill
- dependency-graphSkill
- deploySkill
- destructive-changesSkill
- diff-deploySkill
- erdSkill
- field-impactSkill
- flow-auditSkill
- flow-vs-apexSkill
- fls-auditSkill
- gateway-configSkill
- generate-docsSkill
- limit-usageSkill
- lwc-vs-reactSkill
- mcp-tool-vs-restSkill
- notifySkill
- onboardSkill
- org-diffSkill
- org-exploreSkill
- package-versionSkill
- pattern-packSkill
- perf-reviewSkill
- permset-auditSkill
- pr-prepareSkill
- queueable-vs-batchSkill
- quick-deploySkill
- react-initSkill
- release-notesSkill
- scratch-orgSkill
- security-scanSkill
- sequence-diagramSkill
- sf-initSkill
- sharing-reviewSkill
- slack-agentSkill
- soql-analyzerSkill
- test-coverageSkill
- test-dataSkill
- test-planSkill
- trust-evalSkill
- trust-layer-auditSkill
The file
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 2 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 33
If <arg> ends in <testSuffix>, treat as test class directly
- Very specific: line 35
Verify the file exists in ${APEX_SRC}
- Distinctive: line 100
Be quick about it: Default 5 runs is a balance — enough to catch most flakiness, fast enough to iterate
- Distinctive: line 105
When you flag a test as flaky, prepend the most likely cause to the report based on heuristics from the test source:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
You are detecting flaky Apex tests by re-running them and looking for inconsistent results. A test is flaky if it passes some runs and fails others without code changes between them.
Read Project Config First
source "${CLAUDE_PLUGIN_ROOT}/hooks/lib/config.sh"
source "${CLAUDE_PLUGIN_ROOT}/hooks/lib/sf-cli.sh"
sf_cli_check || exit 2
ORG="$(sf_config_get '.platform.defaultTargetOrg' "$ENV")"
APEX_SRC="$(sf_config_get '.paths.apexSource' "$ENV")"
TEST_SUFFIX="$(sf_config_get '.naming.apex.testSuffix' "$ENV")"Input
$ARGUMENTS: required.
<TestClass>— class to scan (e.g.,OrderServiceTest)<ProductionClass>— production class; the skill infers<ProductionClass><testSuffix>--runs <n>— how many times to run (default 5)--methods <m1,m2,...>— only run specific test methods--target-org <alias>/--env <name>— standard overrides--ci— emit findings instead of a Markdown report
Steps
1. Resolve the test class
- If
<arg>ends in<testSuffix>, treat as test class directly - Else, treat as production class and append
<testSuffix> - Verify the file exists in
${APEX_SRC}
2. Discover test methods (if --methods not specified)
Grep the class for @isTest static void <name> patterns:
grep -E "@isTest\s+(public|private)?\s*static\s+void\s+(\w+)" "${APEX_SRC}/${TEST_CLASS}.cls" | sed -E 's/.*void (\w+).*/\1/'3. Run each method N times
for i in $(seq 1 "$RUNS"); do
sf apex run test --target-org "$ORG" --tests "${TEST_CLASS}.${METHOD}" --result-format json --synchronous --wait 10 > "/tmp/flaky-${TEST_CLASS}-${METHOD}-${i}.json"
done--synchronous is important here — async runs queue and may interfere with each other.
4. Aggregate per method
For each method, count passes vs. fails across runs. Capture the failure messages so the user can see whether they vary.
5. Output
Markdown report:
# Flaky Test Report: <TestClass>
Org: <ORG> | Runs per method: 5
| Method | Pass | Fail | Verdict |
|---------------------------|------|------|---------|
| createOrder_returnsId | 5/5 | 0/5 | ✅ stable |
| persist_handlesBulkUpdate | 3/5 | 2/5 | ⚠️ flaky |
| ...
## Flaky details
### persist_handlesBulkUpdate
Failed 2 of 5 runs. Failure messages:
- Run 2: "System.QueryException: Record not found"
- Run 4: "System.AssertException: Expected: 200, Actual: 199"
Common flakiness causes for this signature:
- Async work not flushed before assertion (missing Test.stopTest())
- Time-dependent assertions (Date.today() at midnight rollover)
- Shared state across test methods (static caches not reset)
- Order-dependent SOQL (no ORDER BY on lists asserted by index)CI mode: emit one finding per flaky method:
ruleId: "FLAKY-TEST",severity: "warning", file = test class file, line = method start, message includes pass/fail counts and a hint at likely cause
6. Exit codes
- 0 — all stable (or all failed deterministically — that's a different problem)
- 1 — at least one method is flaky (mixed pass/fail across runs)
- 2 — invocation error
Rules
- Run synchronously.
--synchronouskeeps runs from interfering. Async batches queue and can deliver out of order - Don't auto-fix. This skill detects; the user fixes
- Don't mute or skip flaky tests. Muting hides bugs. The fix is always to make the test deterministic (mock time, isolate state, use
Test.startTest/Test.stopTestcorrectly) - Be quick about it. Default 5 runs is a balance — enough to catch most flakiness, fast enough to iterate
- Persist history. Append the per-method pass/fail rates to
${CLAUDE_PLUGIN_DATA}/argo/flaky/<project>/<TestClass>.jsonlso trends are visible across runs
Likely causes catalog
When you flag a test as flaky, prepend the most likely cause to the report based on heuristics from the test source:
| Heuristic in test source | Likely cause |
Calls async (enqueueJob, Database.executeBatch) without Test.stopTest | Missing flush boundary |
Asserts on Datetime.now() or Date.today() against a stored value | Clock drift across runs |
Asserts on List<>[i] without an ORDER BY in the source SOQL | Order-dependent assertion |
| Touches a static variable that other tests also touch | Shared static state |
Reads from Custom Metadata without using @TestVisible loader (SF-17) | Real-org data leaking in |
| Queries Salesforce time-tracking objects (LoginHistory etc.) | Org-state-dependent |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

