Skip to main content
CockroachDB has a comprehensive test suite covering unit tests, integration tests, logic tests, and end-to-end tests. The ./dev test command provides a unified interface for running tests.

Running Tests

Basic Test Commands

Use the ./dev test command to run tests:
# Run all tests in a package
./dev test pkg/sql
When filtering tests with -f, always include the -v flag. This warns you if your filter didn’t match anything. Look for testing: warning: no tests to run in the output.

Common Test Scenarios

# Run tests in a specific package (faster than full package)
./dev test pkg/util/log -f=TestFormat -v

# Run tests in multiple packages
./dev test pkg/util/log pkg/util/timeutil
Some packages have slow tests (SQL tests can take 10+ minutes):
# Be patient - SQL tests are comprehensive
./dev test pkg/sql

# Use filters to run subset
./dev test pkg/sql -f=TestLogic/local/select -v
The KV and SQL packages have particularly comprehensive test suites. Use filters to run specific tests during development.
Logic tests are SQL correctness tests:
# Run all logic tests
./dev test pkg/sql/logictest

# Run specific logic test file
./dev test pkg/sql/logictest -f=TestLogic/local/select
Detect race conditions and flaky tests:
# Run test 100 times looking for failures
./dev test pkg/kv --count=100 -f=TestRangefeed

# Use stress tool for more control
stress ./dev test pkg/kv -f=TestRangefeed --count=1

Test Options

View all available options:
./dev test --help

Verbose Output

./dev test pkg/sql -v
Shows detailed test output including test names and logs.

Short Mode

./dev test pkg/sql --short
Skips slow tests (those marked with testing.Short()).

Race Detector

./dev test pkg/kv --race
Enables Go’s race detector (much slower but catches concurrency bugs).

Test Coverage

./dev test pkg/util/log --cover
Generates test coverage reports.

Test Infrastructure

Test Types

CockroachDB uses several types of tests:
1

Unit Tests

Standard Go tests in *_test.go files:
func TestFeature(t *testing.T) {
    // Test implementation
}
Located alongside the code they test.
2

Logic Tests

SQL correctness tests in pkg/sql/logictest/testdata/:
  • Test SQL semantics and correctness
  • Compare output against expected results
  • Run in various configurations (local, distributed, multi-region)
3

Data-Driven Tests

Tests using the datadriven framework:
  • Test data in testdata/ directories
  • Allows easy addition of test cases
  • Common in SQL optimizer and KV tests
4

Roachtests

Large-scale integration tests in pkg/cmd/roachtest/:
  • Run on real clusters
  • Test distributed scenarios
  • Performance and correctness at scale
  • Typically run in CI, not locally

Test Utilities

CockroachDB provides testing utilities in pkg/testutils/:
import (
    "github.com/cockroachdb/cockroach/pkg/testutils"
    "github.com/cockroachdb/cockroach/pkg/testutils/sqlutils"
    "github.com/cockroachdb/cockroach/pkg/testutils/serverutils"
)

Test Server

Create lightweight test clusters:
s, sqlDB, _ := serverutils.StartServer(t, base.TestServerArgs{})
defer s.Stopper().Stop(ctx)

SQL Utilities

Execute SQL in tests:
sqlutils.MakeSQLRunner(sqlDB).Exec(t, "CREATE TABLE t (id INT)")

Assertions

Common test assertions:
testutils.SucceedsSoon(t, func() error {
    // Check condition
})

Cleanup

Automatic cleanup:
tempDir := testutils.TempDir(t)
// Automatically cleaned up

Code Generation

Many CockroachDB components rely on generated code:

What Gets Generated?

Protocol Buffers

.proto files → .pb.go filesUsed for serialization and RPC.

SQL Parser

Grammar files → Parser codeGenerates the SQL parser.

SQL Optimizer

Optgen rules → Optimizer codeGenerates optimizer transformations.

Stringer

Type definitions → String methodsGenerates String() methods for enums.

Generating Code

Use ./dev generate to regenerate code:
# Generate all code (SLOW - can take 10+ minutes)
./dev generate

# Generate only Go code
./dev generate go

# Generate only protocol buffers (relatively fast)
./dev generate protobuf

# Update BUILD.bazel files when dependencies change
./dev generate bazel
Code generation is slow. Only regenerate what you actually need../dev test and ./dev build automatically generate dependencies but don’t lift them into the worktree. If you need to see generated code, run ./dev generate explicitly.

When to Regenerate

Regenerate code when you modify:
  • .proto files (protobuf definitions)
  • sql.y or sql.bnf (SQL grammar)
  • *.opt files (optimizer rules)
  • Go dependencies (run ./dev generate bazel)
  • Stringer annotations

Writing Effective Tests

Best Practices

1

Test at the Right Level

  • Use unit tests for logic and edge cases
  • Use integration tests for component interaction
  • Use logic tests for SQL correctness
  • Use roachtests for distributed scenarios
2

Make Tests Deterministic

Avoid flaky tests:
// Bad: timing-dependent
time.Sleep(100 * time.Millisecond)

// Good: condition-based
testutils.SucceedsSoon(t, func() error {
    if !conditionMet() {
        return errors.New("condition not met")
    }
    return nil
})
3

Use Testdata Files

For complex test cases, use data-driven tests:
testdata/
  my_feature
  another_case
Easier to add cases and review changes.
4

Clean Up Resources

Always clean up:
s := serverutils.StartServer(t, base.TestServerArgs{})
defer s.Stopper().Stop(ctx)
5

Test Error Cases

Don’t just test the happy path:
// Test error conditions
_, err := fn(invalidInput)
require.Error(t, err)
require.Contains(t, err.Error(), "expected error message")

SQL Logic Tests

When adding SQL features, add logic tests:
# testdata/logic_test/my_feature

statement ok
CREATE TABLE t (id INT PRIMARY KEY, name STRING)

query IT rowsort
SELECT * FROM t
----

statement ok
INSERT INTO t VALUES (1, 'alice'), (2, 'bob')

query IT rowsort
SELECT * FROM t
----
1  alice
2  bob

Continuous Integration

CI Test Runs

When you open a PR, several CI checks run:
  • Unit Tests: All package tests
  • Logic Tests: SQL correctness tests
  • Roachtests: Distributed integration tests (subset)
  • Linters: Code style and quality checks
  • Build Tests: Ensure code builds on all platforms

Handling CI Failures

If tests fail in CI:
  1. Reproduce locally: ./dev test pkg/failing/test -f=TestName -v
  2. Fix the issue
  3. Verify fix: ./dev test pkg/failing/test --count=10
  4. Push the fix
If a test fails intermittently:
  1. Report it by opening an issue
  2. Tag with A-flaky-test
  3. Include CI logs and failure details
  4. Consider adding stress testing
Fix formatting and style issues:
# Format your code
crlfmt -w -tab 2 your_file.go

# Regenerate if needed
./dev generate bazel

Debugging Tests

Common Debugging Techniques

# See detailed test output
./dev test pkg/kv -f=TestRangefeed -v

Next Steps

Building from Source

Learn how to build CockroachDB

Code Structure

Understand the codebase organization

Contributing Guide

Read the full contribution guidelines

Test Engineering

Advanced testing documentation on wiki

Build docs developers (and LLMs) love