TestKase
TestKase
|Docs
Test ManagementAutomation

Best Practices & FAQ

Best practices for automation integration, troubleshooting tips, and common questions.

Best Practices

  1. Always use continue-on-error or allow_failure on your test step. Your tests may fail, but you still want the reporting step to run. Without this flag, a test failure would skip the reporting step and you would lose visibility into the results.

  2. Run reporting with if: always() or when: always. Ensure the reporting step runs regardless of whether earlier steps passed or failed. This is the most common misconfiguration — tests fail but results never reach TestKase.

  3. Store tokens as CI/CD secrets. Never hardcode PATs in pipeline files. Use platform-specific secret management (GitHub Secrets, GitLab CI Variables, Jenkins Credentials, etc.). See the API Keys guide for platform-specific instructions.

  4. Include build IDs for traceability. Use --build-id with your CI build number (e.g., $GITHUB_RUN_NUMBER, $CI_PIPELINE_IID). This links each execution to a specific CI build, making it easy to trace results back to code changes.

  5. Create a dedicated test cycle for CI results — and link the test cases to it. Keep automated CI results in their own test cycle, separate from manual testing cycles. Every test case you report on must already be linked to that cycle: a result for an unlinked test case is rejected with Test case not linked with this test cycle and the reporter exits 1. TCYCLE-1 (the Master Cycle) always contains every test case, so it needs no setup.

  6. Use dry run first. Before enabling real reporting in your pipeline, run with --dry-run --verbose to see exactly which Automation IDs the reporter extracts from your results file. A dry run makes no API calls — unless you also pass --missing-id-in-script create, which still creates test cases — so it cannot confirm that those IDs exist in TestKase. Do one real run afterwards and check the resolve/unknown-ID lines in the output.

  7. Embed Automation IDs consistently. Generate 5-digit Automation IDs in TestKase and embed them in your test names using the [XXXXX] bracket pattern (e.g., test('[48271] should login with valid credentials', ...)). Apply this pattern consistently across all test frameworks.

  8. Pin the reporter's major version. An unpinned npx @testkase/reporter picks up the newest release, so a future major version rolls into every pipeline without warning. Use npx @testkase/reporter@1 (or add it to devDependencies) so upgrades are a deliberate change.

  9. Handle skipped tests intentionally. Decide how skipped tests should appear in TestKase. Use --report-skipped-as blocked if skipped tests indicate an environment issue, or --report-skipped-as ignore if they are intentionally excluded.

  10. Keep the repeated flags in a config file. Project ID, org ID, cycle ID and build ID can live in a committed .testkaserc.json with ${ENV_VAR} placeholders for anything secret, which keeps every pipeline file down to --format and --results-file. See Configuration Sources — and note that a value in the config file overrides the matching environment variable.

  11. Check the exit code, not just the log. The reporter exits 0 when the results file contained no tests, when no Automation IDs matched, and when every attachment failed to upload. Treat any code of 2 or higher as "reporting is broken" and fail the build. See Exit Codes.

Troubleshooting

▶Tests are reported but no test cases are matched

The reporter extracts 5-digit Automation IDs from test names using the regex \[(\d{5})\]. Steps to diagnose:

  1. Run with --dry-run --verbose to see which [XXXXX] IDs the reporter extracts from your test names.
  2. Verify that each extracted ID exists as an Automation ID on a test case in your TestKase project.
  3. If no IDs are extracted, ensure your test names include the [XXXXX] bracket pattern (e.g., [48271] should login).
  4. If IDs are extracted but not matched, check that the 5-digit ID in your test name matches the Automation ID linked to the test case in TestKase.
▶Authentication error (401)

Your PAT token may be expired or invalid. Steps to resolve:

  1. Check the token expiration date in API Keys settings.
  2. Generate a new token if expired.
  3. Update the CI/CD secret with the new token value.
  4. Verify the secret name in your pipeline file matches exactly.
▶Connection timeout or network error

Verify the --api-url value is correct and accessible from your CI environment. Common causes:

  • Incorrect API URL. Pass the base host only (e.g. https://api.testkase.com) — the reporter appends /api/v1 for you. Including /api/v1 yourself produces a doubled /api/v1/api/v1 path and 404s.
  • Firewall or network policy blocking outbound requests from CI runners.
  • For self-hosted TestKase, ensure the CI runner can reach your API server.
  • Proxy configuration needed but not set.

The reporter does not retry a failed call — each API call has a 30-second timeout and a failure ends the run with exit 2. It is safe to simply run the same command again: results are stored per (test case, automation ID, environment) and updated in place, so a re-run repairs a partially reported run instead of duplicating it. Batches that already succeeded before the failure stay applied.

▶What does the reporter's exit code mean?
CodeMeaning
0Success — but also returned when the file had no test results, when no Automation IDs matched, and for every --dry-run
1Some results were rejected by the API — usually test cases not linked to the target cycle
2Authentication, network or API failure
3Results file missing or unreadable, or --format does not match the file
4Untagged or unknown Automation IDs, with --missing-id-in-script fail or --unknown-id-in-testkase fail

See the Exit Codes reference for what to check for each one.

▶Screenshots or videos did not upload

Attachment problems are reported as warnings and never change the exit code — the run can exit 0 with nothing uploaded. Check the Attachments: N uploaded, N skipped, N failed line, then:

  • Files over 50 MB are skipped.
  • Only images, video and common document types are accepted. .zip (including Playwright traces), .json, .html and .xml are rejected as unsupported file types.
  • Files whose extension the reporter cannot map — including .mov, .mkv, .bmp, .tiff, .heic, .md and Office documents — are sent as application/octet-stream and rejected, even though the API accepts those formats under their proper content type. Convert recordings to .mp4 or .webm.
  • Uploads fail once your organization storage quota is full.
  • Re-run with --verbose to see the per-file decision.

See Attachments for the full list.

▶Rate limit exceeded (429)

The API allows 200 requests per minute from the same address. Reporting results is only a handful of calls, so this is almost always caused by attachments: each file is uploaded once per test case it is attached to, at two API calls apiece. A file whose name contains no Automation ID is attached to every test case executed in the run.

Name artifacts after the Automation ID they belong to so each file uploads once, and wait a minute before retrying. The filename is matched with the same --automation-id-format regex as your test names, so with the default pattern the brackets are required: login-[48271].png, not login-48271.png.

▶Skipped tests are reported as 'Blocked'

By default, skipped tests are mapped to "Blocked". To change this behavior:

  • --report-skipped-as blocked — marks them as Blocked (default behavior)
  • --report-skipped-as not-executed — marks them as Not Executed
  • --report-skipped-as ignore — ignores them entirely (skipped tests are not reported)
▶'Results file not found' error

The reporter cannot find the results file at the specified path. Common causes:

  • Tests did not produce the expected output file (check test framework configuration).
  • The path is relative and the working directory is different from expected.
  • In multi-stage CI pipelines, artifacts may not be carried over to the reporting stage (e.g., GitLab needs artifacts configuration).
▶Partial results — some tests matched, others didn't

This is normal if not all test names contain a [XXXXX] Automation ID, or if some IDs have not been linked to test cases in TestKase yet. To handle this:

  • Check the dry-run output to see which tests are unmatched (missing [XXXXX] or unknown ID).
  • For unmatched tests, generate Automation IDs in TestKase and embed them in the test names.
  • Use --missing-id-in-script skip (default) to silently ignore tests without embedded IDs.
  • Or accept partial matching if some tests are intentionally not tracked in TestKase.

FAQ

▶Can I report results from multiple test frameworks in one pipeline?

Yes. Run the reporter multiple times in the same pipeline with different --format and --results-file flags. Each invocation can target the same or different test cycles.

▶Can I report results to multiple test cycles?

Yes. Run the reporter once per cycle, changing the --cycle-id flag. For example, report to both a "CI Automated" cycle and a "Sprint 14 Regression" cycle. Each cycle must already contain the test cases you are reporting on, or that run's results are rejected and the reporter exits 1.

▶What happens if I run the reporter twice for the same cycle?

When you re-run the reporter for the same automation ID, TestKase updates the existing automation run entry rather than creating a duplicate. The status, actual result, duration, error message, and executed-on fields all reflect the latest run.

The cycle history tab always records the full timeline of every execution — including older runs — so you retain the complete audit trail.

The test case's overall status uses worst-status-wins precedence: if any automation ID reports a failure, the overall status stays as Fail until that specific automation ID reports Pass again.

▶How do I start a fresh test run after a build fix?

Use the Reset Executions feature on the execute page (available in the ⋯ more-actions menu). It clears all execution statuses, actual results, and automation runs for the cycle while keeping the test cases and cycle metadata intact. You can reset every test case in the cycle, or select specific test cases to reset only those. See Reset Executions for full details.

▶Will I see retry details for flaky tests?

Yes — for Playwright JSON and JUnit XML written by Maven Surefire (its <flakyFailure>, <flakyError>, <rerunFailure> and <rerunError> elements). The reporter captures each attempt's status, duration (Playwright only), and error message. On the execute page, the Error Message field shows the full retry log and the Actual Result field labels flaky tests explicitly — Flaky — passed after 2 retry(ies).

Gradle's test-retry plugin is the exception: it writes each attempt as a separate <testcase> element rather than nesting them, so its retries arrive as separate results instead of attempts of one test.

For Cypress, TestNG, NUnit, and Cucumber, per-attempt retry data is not available in the output format — the framework's own reporter only writes the final attempt. See Retry Details for the full support matrix.

▶Does the reporter create test cases automatically?

By default, no. With --missing-id-in-script skip (the default), results whose test name carries no Automation ID are logged and dropped — nothing is created.

If you pass --missing-id-in-script create, the reporter does create data in your project: for each untagged test it creates a test case, generates an Automation ID for it, links the two, and then reports the result against the new test case.

--missing-id-in-script create writes new test cases into your project on every run. A typo in --project-id, or a branch with renamed tests, will create test cases you did not intend. Prefer the default skip in shared pipelines. Note that --dry-run is not a safe preview here: creation happens before the dry-run check, so --dry-run --missing-id-in-script create still creates the test cases. Preview with the default skip instead.

▶Can I use the reporter without npm/Node.js?

Currently, the @testkase/reporter CLI requires Node.js. If your CI environment does not have Node.js, use a Docker image that includes it (e.g., node:20) or add a Node.js setup step to your pipeline.

▶Is there a GitHub Action or GitLab CI template available?

The pipeline templates shown in the platform-specific guides are the recommended starting point. Copy the template for your platform, update the flags with your project details, and you are ready to go. There is no separate marketplace action at this time.

▶How do I handle dynamic test cycle IDs?

If you create test cycles dynamically (e.g., one per PR), you can pass the cycle ID as an environment variable. Create the cycle via the TestKase API first and capture the ID, then pass it to the reporter with --cycle-id.

A cycle created through the API — or with npx @testkase/reporter create-run — is empty. Nothing links test cases to it automatically, so reporting straight into it fails every result with Test case not linked with this test cycle and exits 1. Link the test cases to the new cycle first, or report into a cycle that already contains them and tell the builds apart with --build-id.

▶Can I use the reporter in a Docker container?

Yes. Use any Node.js-based Docker image (e.g., node:20, cimg/node:20.0) and run npx @testkase/reporter in a script step. No additional Docker configuration is needed.