Skip to content
The docs are now organized by product area. Old links still work. Report a broken link

Go reporter

Install qualflare-go, run go test through it so build failures are caught, and upload the qualflare-results folder with the Qualflare CLI.

Last updated

qualflare-go is the Qualflare reporter for Go 1.21 or later: it runs go test -json, writes every test and subtest as a test case, with steps and attachments, to qualflare-results, and qf <identifier> collect uploads the folder as one launch.

FactDetail
Packagequalflare-go, as a Homebrew cask or with go install
Works withGo 1.21 or later
LicenseApache-2.0
SourceQualflare/qualflare-go on GitHub
Without the reporter--format golang with the output of go test -json

Before you begin

  • The Qualflare CLI, qf: Install the CLI.
  • A saved login: qf login <identifier> with a project access token whose creator still holds the project role that uploads need Editor+ · project (requires the Editor role or higher in the project) (Authenticate with qf login).
  • The Identifier of the environment the results belong to (Environments).

Install

go install github.com/Qualflare/qualflare-go/cmd/qualflare-go@latest
# or, without a Go toolchain in the CI image
brew install qualflare/tap/qualflare-go

For the metadata calls, add the module to your project: go get github.com/Qualflare/qualflare-go. It has no dependencies of its own.

Configure

Options are flags of qualflare-go, or QUALFLARE_* variables; there is no config file.

OptionTypeDefaultRequiredDescription
--environmentstringdevelopmentNo

The environment's Identifier. Variable QUALFLARE_ENVIRONMENT.

--output-dirstringqualflare-resultsNo

Variable QUALFLARE_OUTPUT_DIR.

--run-idstringCI build, else randomNo

Every shard must share one. Variable QUALFLARE_RUN_ID.

--shard-indexnumber—No

Which shard produced these tests; 0 is a real shard. Variable QUALFLARE_SHARD_INDEX.

--repeatstringcollapseNo

collapse folds -count=N runs into one test with attempts; split keeps them separate. Variable QUALFLARE_REPEAT.

Every reporter shares the other settings: see Reporter configuration.

Set --environment to the environment's Identifier: a name such as Staging fails the upload with HTTP 400 (Environment).

Run and upload

qualflare-go ./...
qf <identifier> collect ./qualflare-results

qualflare-go ./... is short for qualflare-go -- go test ./... and adds -json; pass any go test flags after --, as in qualflare-go -- go test -race -timeout 5m ./....

Run go test through qualflare-go, not through a pipe

go test -json ./... | qualflare-go can't see go test's exit code or its stderr. On Go 1.21 and 1.23 a build failure writes no fail event, so a piped run can upload a passing launch for a broken build.

Run in CI

- name: Upload results to Qualflare
  if: ${{ !cancelled() }}
  env:
    QF_TOKEN: ${{ secrets.QF_TOKEN }}
    QF_BRANCH: ${{ github.head_ref || github.ref_name }}
    QF_COMMIT: ${{ github.event.pull_request.head.sha || github.sha }}
  run: |
    npm install -g @qualflare/cli
    qf login ci --force
    qf ci collect ./qualflare-results

if: ${{ !cancelled() }} uploads the results when tests fail, and QF_BRANCH and QF_COMMIT record a pull request's own branch and commit (Pull request branches). For GitLab CI/CD, Jenkins and Azure Pipelines, see Run the upload when tests fail.

Sharding and retries

Point every shard at the same --output-dir; in CI the run ID comes from the build, so shards agree. Set --shard-index per shard: Go has no worker number. See Merge sharded CI jobs into one launch.

Go has no retries: attempts and flakiness come only from -count=N. On GitHub Actions the run ID includes the run attempt, so a re-run gets its own launch.

What gets uploaded

Each subtest, such as TestUsers/rejects_a_blank_email, is its own test case. A test case carries:

  • Steps, only where you call qualflare.Step
  • Attachments
  • Labels, tags, links, priority and parameters
import "testing"
import "github.com/Qualflare/qualflare-go"

func TestCheckout(t *testing.T) {
    qualflare.Label(t, "feature", "checkout")

    qualflare.Step(t, "add to cart", func() {
        qualflare.Parameter(t, "sku", "widget")
        qualflare.MaskedParameter(t, "token")
    })
}

Every call takes the test's testing.TB, so a call outside a test doesn't compile. MaskedParameter takes no value, so a secret can't reach the report.

Troubleshooting

  • Metadata from a goroutine that outlives its test can land on the parent test.
  • The report carries qualflare.unparsedLines and qualflare.oversizedLines properties when the decoder skipped or truncated lines.
  • environment "Staging" does not exist in this project: use the environment's Identifier, or pass --environment on the upload (Environment).