---
title: "Go Test Flags: -run, -count, -shuffle, -race e -json"
url: "https://golang.com.br/blog/go-test-flags-run-count-shuffle-race-json/"
markdown_url: "https://golang.com.br/blog/go-test-flags-run-count-shuffle-race-json.MD"
description: "Guia das principais flags do go test: filtre testes com -run, evite cache com -count, descubra dependências com -shuffle, detecte races e gere JSON para CI."
date: "2026-08-21"
author: "Golang Brasil"
---

# Go Test Flags: -run, -count, -shuffle, -race e -json

Guia das principais flags do go test: filtre testes com -run, evite cache com -count, descubra dependências com -shuffle, detecte races e gere JSON para CI.


**Resposta rápida:** as flags mais úteis do **`go test`** resolvem cinco problemas diferentes: **`-run`** filtra testes e subtests, **`-count=1`** força uma execução sem cache, **`-shuffle=on`** muda a ordem para revelar dependências ocultas, **`-race`** procura acessos concorrentes incompatíveis e **`-json`** produz eventos estruturados para CI. No dia a dia, comece com `go test ./...`; quando algo falhar, reduza o escopo com `-run`, repita com `-count`, reproduza a seed do `-shuffle` e só então amplie o diagnóstico.

O comando `go test` parece simples, mas suas flags transformam a experiência de investigar uma suíte grande. Saber combiná-las evita três desperdícios comuns: rodar o repositório inteiro para depurar um único caso, acreditar que um resultado em cache foi uma nova execução e tentar entender um teste instável sem preservar a ordem ou a repetição que provocou a falha.

Este guia funciona como referência operacional. Para aprender a escrever testes unitários, table-driven tests, mocks, `httptest`, fuzzing e cobertura desde o começo, leia primeiro o [guia completo de testes em Go](/aprenda/testes-go/). Aqui o foco é executar, filtrar, repetir e diagnosticar os testes que já existem.

## Tabela rápida das principais flags do go test

| Objetivo | Comando recomendado |
|---|---|
| Testar todo o módulo | `go test ./...` |
| Ver testes e logs | `go test -v ./...` |
| Rodar um teste exato | `go test -run '^TestCriarPedido$' ./internal/pedido` |
| Rodar um subtest | `go test -run 'TestCriarPedido/sem_estoque' ./internal/pedido` |
| Ignorar o cache | `go test -count=1 ./...` |
| Repetir um teste 20 vezes | `go test -run '^TestFila$' -count=20 ./internal/fila` |
| Randomizar a ordem | `go test -shuffle=on ./...` |
| Reproduzir uma ordem | `go test -shuffle=1740001234 ./...` |
| Definir limite de tempo | `go test -timeout=2m ./...` |
| Detectar data races | `go test -race ./...` |
| Gerar eventos JSON | `go test -json ./...` |
| Medir cobertura | `go test -cover ./...` |
| Gerar perfil de cobertura | `go test -coverprofile=coverage.out ./...` |
| Rodar apenas benchmarks | `go test -run='^$' -bench=. -benchmem ./...` |

Para consultar todas as opções disponíveis no toolchain instalado, rode:

```bash
go help test
go help testflag
```

Essa consulta local é importante porque o comportamento acompanha a versão de Go usada pelo projeto. O guia de [documentação Go em português](/aprenda/documentacao-go/) explica como combinar `go help`, `go doc` e `pkg.go.dev` sem depender de snippets desatualizados.

## `-run`: filtre testes e subtests com expressão regular

A flag `-run` recebe uma expressão regular aplicada ao nome do teste. Para executar exatamente `TestCriarPedido`, use âncoras:

```bash
go test -run '^TestCriarPedido$' ./internal/pedido
```

Sem `^` e `$`, a expressão pode casar com outros nomes, como `TestCriarPedidoComCupom`. Isso não é necessariamente ruim, mas pode confundir quando você pensa que isolou um único caso.

Subtests criados com `t.Run` formam um caminho separado por barras. Considere:

```go
func TestCriarPedido(t *testing.T) {
	t.Run("sucesso", func(t *testing.T) {
		// ...
	})
	t.Run("sem estoque", func(t *testing.T) {
		// ...
	})
}
```

Você pode executar somente o segundo cenário:

```bash
go test -run 'TestCriarPedido/sem_estoque' ./internal/pedido
```

O Go normaliza espaços nos nomes de subtests para facilitar a seleção. Ainda assim, prefira nomes curtos e descritivos. Em uma suíte baseada em tabelas, o nome do caso vira uma ferramenta de debugging, não apenas documentação. Veja padrões completos no artigo sobre [table-driven tests em Go](/blog/testes-tabela-go-guia-table-driven-tests/).

### Combine `-run` com `-v`

Quando você precisa ver `t.Log`, nomes de subtests e duração:

```bash
go test -v -run '^TestCriarPedido$' ./internal/pedido
```

`-v` é ideal para investigação humana. Evite deixá-lo como única fonte de diagnóstico no CI: milhares de linhas sem estrutura ficam difíceis de pesquisar e correlacionar. Para automação, a saída JSON é melhor.

## `-count`: ignore o cache ou repita o mesmo teste

Resultados bem-sucedidos de testes podem ser armazenados no cache do comando `go`. Quando o cache é usado, a saída inclui `(cached)`. Isso acelera muito o ciclo normal, mas pode esconder a diferença entre “o código continua igual” e “o teste realmente executou de novo”.

Para forçar uma execução:

```bash
go test -count=1 ./...
```

O mesmo flag também repete cada teste selecionado:

```bash
go test -run '^TestWorker$' -count=50 ./internal/worker
```

Essa repetição ajuda a encontrar flakiness causada por concorrência, relógio, ordem, portas, arquivos temporários ou estado global. Ela não substitui uma reprodução controlada: se o teste falhar na repetição 37, preserve também logs, seed, versão do Go, sistema operacional e configuração relevante.

### Quando `-count=1` não conserta o problema

Se um teste passa apenas com cache desativado, investigue a causa. Suspeitos frequentes:

- dependência de um arquivo ou serviço externo;
- uso de `time.Now` sem controle;
- variáveis de ambiente alteradas por outro teste;
- banco compartilhado sem limpeza;
- variável global ou singleton mutável;
- teste que depende de ordem;
- goroutine que continua viva depois do caso terminar.

Use `t.TempDir`, `t.Setenv` e `t.Cleanup` para isolar recursos. Para serviços reais como PostgreSQL ou Redis, prefira ambientes descartáveis e veja [Testcontainers em Go](/blog/go-testcontainers-testes-integracao-containers/).

## `-shuffle`: encontre dependências ocultas de ordem

Uma suíte deve produzir o mesmo resultado independentemente da ordem dos testes, desde que os casos sejam realmente isolados. `-shuffle=on` randomiza a ordem de execução dos testes e benchmarks:

```bash
go test -shuffle=on ./...
```

No início da execução, o comando informa a seed usada. Se ocorrer uma falha, copie esse número para reproduzir a ordem:

```bash
go test -shuffle=1740001234 ./...
```

A seed é parte do relatório de incidente. Sem ela, “falhou uma vez com shuffle” é pouco acionável.

`-shuffle` costuma revelar:

- um teste que cria um registro e outro que presume que ele já existe;
- configuração global que não é restaurada;
- servidor ou porta fixa reaproveitada;
- cache em memória compartilhado entre casos;
- mocks com expectativas mantidas fora do subtest;
- dependência acidental do nome ou da ordem alfabética.

Uma estratégia útil no CI é manter o job rápido e determinístico em cada pull request e rodar um job periódico com `-shuffle=on -count=1`. Se ele falhar, publique a seed nos artefatos. Randomização sem possibilidade de reprodução só cria ruído.

## `-race`: detecte acessos concorrentes incompatíveis

O race detector instrumenta o programa e reporta data races observadas durante a execução:

```bash
go test -race ./...
```

Ele é especialmente relevante para caches, maps compartilhados, workers, pools, handlers que alteram estado e qualquer código com goroutines. Porém, há dois limites importantes:

1. o detector só encontra caminhos que os testes realmente executaram;
2. a instrumentação aumenta o tempo e o consumo de memória.

Por isso, repositórios grandes costumam manter `-race` em um job separado. Ao investigar uma falha específica, combine filtros:

```bash
go test -race -run '^TestCacheConcorrente$' -count=20 ./internal/cache
```

Não “corrija” uma race apenas colocando um mutex em volta de tudo. Primeiro identifique qual estado é compartilhado, quem deveria ser seu dono e qual contrato de sincronização faz sentido. O guia de [`sync.Mutex`, `RWMutex` e `WaitGroup`](/blog/sync-mutex-waitgroup-rwmutex-once-go/) e a [cheatsheet de concorrência](/cheatsheet/concorrencia/) ajudam a escolher a primitiva correta. Para mensagens típicas do detector, consulte a página de [data race em Go](/erros/race-condition-data-race/).

## `-timeout`: transforme travamento em falha diagnosticável

O `go test` possui um timeout padrão, mas suítes de CI devem declarar um limite coerente com o projeto:

```bash
go test -timeout=2m ./...
```

Quando o prazo expira, o processo gera informações das goroutines, úteis para localizar deadlocks, leitura de channel sem produtor, servidor que não encerra ou espera externa sem deadline.

Não use um timeout enorme para esconder lentidão. Separe testes rápidos de integração e ponta a ponta. Um pacote de unit tests que precisa de 20 minutos provavelmente mistura responsabilidades ou chama infraestrutura externa sem controle.

Para um teste individual que trabalha com contexto, prefira também um deadline interno:

```go
func TestProcessar(t *testing.T) {
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel()

	if err := Processar(ctx); err != nil {
		t.Fatal(err)
	}
}
```

O timeout global protege a suíte; o contexto documenta e testa o contrato da operação.

## `-json`: saída estruturada para CI e relatórios

Para consumo humano, `-v` é suficiente. Para máquinas, use:

```bash
go test -json ./...
```

A saída contém eventos JSON por linha, com informações como pacote, teste, ação, timestamp, tempo decorrido e texto produzido. Ferramentas de CI podem transformar esses eventos em relatórios, anexar logs ao teste correto e destacar apenas falhas.

Uma execução pode ser salva para processamento posterior:

```bash
go test -json ./... > test-results.jsonl
```

O formato é uma sequência de objetos JSON, não um único array. Portanto, trate o arquivo como **JSON Lines**. Não tente fazer `json.Unmarshal` de todo o conteúdo diretamente em uma slice sem antes ler linha a linha.

Para converter a saída de um binário de teste ou de outro comando compatível, existe também `go tool test2json`. Na maioria dos pipelines comuns, `go test -json` já é a opção mais simples.

### O que guardar quando o CI falha

Um relatório útil inclui:

- pacote e nome completo do teste/subtest;
- commit e versão do Go (`go version`);
- sistema operacional e arquitetura;
- duração;
- seed do `-shuffle`, quando usada;
- número de repetições e flags;
- stack trace ou relatório do race detector;
- logs associados somente ao teste que falhou.

Evite imprimir tokens, strings de conexão ou payloads sensíveis nos logs. Estrutura não elimina risco de segredo vazado; apenas facilita localizar o vazamento.

## Cobertura: `-cover`, `-coverprofile` e `-coverpkg`

Para um resumo:

```bash
go test -cover ./...
```

Para gerar um perfil:

```bash
go test -coverprofile=coverage.out ./...
go tool cover -func=coverage.out
go tool cover -html=coverage.out
```

Quando o fluxo atravessa vários pacotes, amplie a instrumentação:

```bash
go test -coverpkg=./... -coverprofile=coverage.out ./...
```

Cobertura mostra quais statements foram executados, não se as verificações estavam corretas. Uma porcentagem alta com assertions fracas pode oferecer menos proteção que uma suíte menor cobrindo regras críticas, erros e limites. Use a tendência para detectar regressões, não como pontuação isolada da equipe.

## Combinações prontas para problemas reais

### Depurar um teste específico

```bash
go test -v -run '^TestCriarPedido$/^sem_estoque$' -count=1 ./internal/pedido
```

### Caçar um teste instável

```bash
go test -run '^TestWorker$' -count=100 -shuffle=on ./internal/worker
```

Se falhar, repita com a seed impressa e reduza o `-count` apenas depois de conseguir uma reprodução estável.

### Investigar concorrência

```bash
go test -race -run '^TestCache' -count=20 -timeout=3m ./internal/cache
```

### Gerar relatório para CI

```bash
go test -json -count=1 -timeout=5m ./... > test-results.jsonl
```

### Rodar cobertura sem reaproveitar cache

```bash
go test -count=1 -coverpkg=./... -coverprofile=coverage.out ./...
```

### Rodar somente benchmarks

```bash
go test -run='^$' -bench=. -benchmem -count=5 ./...
```

Para interpretar `ns/op`, `B/op`, `allocs/op`, `b.Loop` e perfis, siga o guia de [benchmarks em Go](/blog/benchmarks-go-testing-b-benchmem-pprof/).

## Pipeline recomendado: rápido no PR, profundo em jobs separados

Um pipeline pragmático não precisa colocar todas as flags no mesmo comando.

**Job rápido de pull request:**

```bash
go vet ./...
go test -count=1 -timeout=3m ./...
```

**Job de concorrência:**

```bash
go test -race -count=1 -timeout=10m ./...
```

**Job periódico de isolamento:**

```bash
go test -shuffle=on -count=1 -timeout=10m ./...
```

**Job de cobertura:**

```bash
go test -coverpkg=./... -coverprofile=coverage.out ./...
```

Essa separação deixa o feedback principal rápido e mantém diagnósticos caros visíveis. Para completar o pipeline com lint, vulnerabilidades e integração, veja [TDD e CI/CD com Go](/tutoriais/go-tdd-ci-cd/), [golangci-lint e Staticcheck](/blog/staticcheck-golangci-lint-go-qualidade-ci/) e [govulncheck](/blog/govulncheck-go-vulnerabilidades-dependencias/).

## Erros comuns ao usar flags do go test

- **Usar `-run Nome` sem âncoras e executar mais casos do que imaginava.** Use `^Nome$` quando quiser correspondência exata.
- **Colocar `-count=1` em todo comando local por hábito.** O cache existe para acelerar o ciclo; desative-o quando precisar de uma nova execução.
- **Rodar `-shuffle=on` sem guardar a seed.** Uma falha não reproduzível vira investigação por tentativa e erro.
- **Concluir que `-race` prova ausência de races.** Ele só observa caminhos executados.
- **Aumentar `-timeout` indefinidamente.** Corrija deadlock, I/O sem deadline ou separação inadequada dos testes.
- **Parsear `-json` como um objeto único.** A saída é composta por eventos, um por linha.
- **Repetir um teste flakey até ele passar.** Retry pode reduzir ruído temporariamente, mas não elimina estado compartilhado, relógio instável ou concorrência incorreta.
- **Misturar benchmark com testes unitários caros.** Use `-run='^$'` quando quiser medir apenas benchmarks.

## Checklist de diagnóstico

Quando um teste falhar, siga esta ordem:

1. Rode o pacote com `-v -count=1`.
2. Isole o nome exato com `-run`.
3. Repita com `-count=20` ou mais se houver suspeita de flakiness.
4. Use `-shuffle=on` e preserve a seed se a ordem puder influenciar.
5. Adicione `-race` se existir estado compartilhado ou goroutines.
6. Defina um `-timeout` curto o bastante para obter stack traces rapidamente.
7. No CI, salve `-json` e associe a saída ao teste correto.
8. Corrija isolamento e contrato; não apenas aumente retries e timeouts.

## Perguntas frequentes

### Como rodar apenas um teste específico com go test?

Use `go test -run '^TestNome$' ./caminho/do/pacote`. Para subtests, inclua o caminho separado por barra, como `go test -run 'TestPedido/sem_estoque' ./internal/pedido`.

### Como executar go test sem cache?

Use `go test -count=1 ./...`. Isso força uma execução em vez de reutilizar um resultado bem-sucedido armazenado.

### Para que serve go test -shuffle?

Serve para randomizar a ordem dos testes e revelar dependências ocultas. Use `-shuffle=on`; se falhar, copie a seed exibida e reproduza com `-shuffle=NUMERO`.

### Qual é a diferença entre -v e -json?

`-v` oferece saída detalhada para uma pessoa ler no terminal. `-json` emite eventos estruturados para CI, relatórios e parsers.

### Quando devo usar go test -race?

Use em código concorrente, caches, workers e serviços com estado compartilhado, preferencialmente também em um job separado do CI. Ele aumenta o custo e só encontra races nos caminhos exercitados.

## Próximos passos

- [Go Test: guia completo de testes](/aprenda/testes-go/) — escrita de testes, mocks, HTTP, integração, cobertura e fuzzing;
- [Table-driven tests](/blog/testes-tabela-go-guia-table-driven-tests/) — organize muitos cenários com `t.Run`;
- [Fuzz testing nativo](/blog/fuzzing-go-testes-nativos/) — descubra entradas que quebram parsers e validadores;
- [Testcontainers em Go](/blog/go-testcontainers-testes-integracao-containers/) — teste PostgreSQL, Redis e outros serviços reais;
- [Benchmarks com testing.B](/blog/benchmarks-go-testing-b-benchmem-pprof/) — meça tempo e alocações sem se enganar;
- [Vagas Go no Brasil](/vagas/) — encontre equipes que valorizam testes, CI e serviços confiáveis.

Dominar as flags do `go test` não significa decorar todas as opções. Significa escolher a menor combinação capaz de responder à pergunta atual: **qual caso falhou, ele executou de verdade, depende da ordem, é concorrente e como reproduzo no CI?**
