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. The everyday testing flags decide which test targets Bazel should execute for a change, under what constraints, 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) closes with a pattern that keeps verification read-only while putting intentional golden updates behind a separate bazel run path.
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.5.1 Affected-Target Service Contract and H.7.3 Evidence Selection.
Where Beginners Get Tripped Up
The confusing part is that 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.
Start With The Testing Symptom
For the daily local loop, read 1.2.1 Test Caching, 1.2.2 Test Sizes & Timeouts, 1.2.3 Test Tags, and 1.2.7 Test Output & Debugging first. Those four articles explain most of what you see when bazel test feels too fast, too slow, too quiet, or too broad.
Then read 1.2.4 testonly Attribute when you start organizing shared test helpers or experimental packages. Read 1.2.5 Test Sharding only when one test target has become the bottleneck, and 1.2.6 Test Suites when humans need stable named groups. Treat 1.2.8 Coverage as the first coverage workflow, not as a general testing default. Keep 1.2.9 Golden File Testing (Test-Accept Pattern) for reviewable generated outputs where a separate accept path makes the workflow safer.
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 · 10
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.
Turning coverage-guided input discovery into reproducible crash regressions.