1.2 Testing Strategy
bazel test //... looks like a simple instruction: run the tests. Bazel must
also select the test targets, decide whether cached results are reusable, apply
each target's resource and timeout policy, and save evidence for failures.
Bazel testing is a contract between target metadata, CLI selection, cached results, execution policy, and saved artifacts. Everyday testing flags decide which test targets belong to the current request, under what constraints they run, and how to inspect the result.
The Testing Contract
The section starts with the feedback loop itself. 1.2.1 Test Caching explains why a second bazel test may say (cached) PASSED instead of launching the test binary again. A test result is reusable build evidence when its declared inputs have not changed.
Then the next articles add the metadata that makes large test suites operable. 1.2.2 Test Sizes & Timeouts separates cost from deadline: size tells Bazel roughly how heavy a test is, while timeout controls how long it may run. 1.2.3 Test Tags adds selection and behavior: ordinary tags create lanes such as unit or integration, while built-in tags like manual, exclusive, and external change Bazel's own treatment of a target. 1.2.4 testonly Attribute solves a different problem: it keeps test support code from leaking into production dependency paths.
The middle of the section is about shape. 1.2.5 Test Sharding handles one oversized test target by splitting its internal cases across multiple runner invocations. 1.2.6 Test Suites does the opposite kind of organization: it gives several existing test targets one stable label for humans and CI to type. If the problem is "one target is too slow," think sharding. If the problem is "this set needs a memorable name," think suite.
The final articles are about evidence and specialized workflows. 1.2.7 Test Output & Debugging teaches where logs, summaries, repeated runs, and undeclared test outputs show up when a target fails or flakes. 1.2.8 Coverage turns the same test execution path toward line-execution evidence instead of only pass/fail. 1.2.9 Golden File Testing (Test-Accept Pattern) keeps verification read-only while putting intentional golden updates behind a separate bazel run path. 1.2.10 Fuzz Testing & Crash Regression turns coverage-guided input discovery into deterministic crash regressions.
These are not separate testing systems. Each test remains a graph target whose metadata gives Bazel additional execution semantics. Labels and patterns from 0.2.3 Target Patterns select the targets, Bazel builds their prerequisites, reuses passing outcomes when allowed, executes the survivors, and writes logs under the output tree from 0.1.4 Output Root. Level 1 is enough to make those daily choices. Affected-target selection and fleet-scale testing wait for 6.7.1 Selecting Affected Targets and H.7.3 Evidence Selection.
Different Problems Need Different Controls
Similar commands can answer different questions.
bazel test //... --test_tag_filters=unit is a selection question. bazel test //pkg:slow_test --nocache_test_results is a freshness question. bazel test //pkg:flaky_test --runs_per_test=50 --test_output=streamed is a debugging question. bazel coverage //pkg:lib_test --combined_report=lcov is an evidence question. All of them use the testing surface, but they are not interchangeable remedies.
The same distinction keeps BUILD metadata honest. Do not use timeout to hide an oversized target that should be sharded. Do not use tags to enforce a production dependency boundary that belongs to testonly. Do not use a suite when what you really need is query-driven target selection. And do not interpret a quiet terminal as missing information until you have checked bazel-testlogs.
Bazel testing is graph execution with test-specific contracts. Diagnose the layer before changing a flag: selection, result reuse, execution policy, dependency boundaries, or saved evidence each has a different control surface.
Sections in this chapter · 9
How Bazel reuses passing test results and when to force or disable test-result caching.
How test size and timeout describe execution budget and local scheduling cost.
Selecting tests with tags and recognizing built-in tags that alter wildcard matching, retries, isolation, or caching.
Using testonly to keep test-only code out of production dependency paths.
Splitting one large test target into runner-supported shards with shard_count and shard environment variables.
Using test_suite as a stable label for groups of existing test targets.
Choosing --test_output and --test_summary, locating bazel-testlogs, and rerunning tests for local evidence.
Running instrumented tests with bazel coverage and finding per-test and merged LCOV outputs.
Comparing deterministic output with checked-in golden data and separating verification from explicit acceptance updates.