1.1.1 Commands

Most day-to-day Bazel work reduces to three verbs: bazel build, bazel test, and bazel run. They all start from the same target graph, using the same label language from 0.2.1 Label Anatomy, but they ask Bazel to stop at different points: materialize outputs, execute tests, or launch one runnable target1,2.

bazel build //app:server
bazel test //app:server_test
bazel run //app:server

Later, 2.2.1 Loading, Analysis & Execution breaks that work into loading, analysis, and execution. For now, the operator mental model is simpler: choose the verb by the final side effect you want after Bazel has understood the graph.

The Target Language Is Shared, but Not Symmetric

bazel build and bazel test accept both single labels and target patterns such as //app:all or //... (0.2.3 Target Patterns)1,3. bazel run is narrower: the requested label or pattern still has to resolve to exactly one runnable target2,3.

The commands differ because build and test are often used for repo-wide sweeps, while run launches one specific executable. Treating all three as "the same thing with different nouns" loses the distinction between producing an artifact and executing it4.

bazel build Stops at Artifacts

bazel build asks Bazel to bring the requested targets up to date and then stop once their outputs exist1. For binaries and generated files, those outputs live in Bazel's output tree. In day-to-day work you usually inspect them via bazel-bin (0.1.4 Output Root)4,5.

That makes build the right command when you want compiled or generated results without launching anything yet: produce a binary, compile a library's dependents, or do a broad sweep such as bazel build //... to see whether the repository still builds1,3. It is also the natural verb for targets that are buildable but not runnable, such as libraries1.

bazel test Is Build Plus Supervised Execution

bazel test starts the same way as build: Bazel analyzes the graph and builds the requested test targets before it executes them2,6. Then it runs the resulting test executables under Bazel's test machinery and reports pass/fail2,7.

A Bazel test is a program with a contract. Bazel launches the test binary, applies the testing rules around it, and treats the execution outcome as success or failure without inspecting your assertions directly7. If nothing relevant changed, Bazel can reuse a prior passing result and print PASSED (cached), which is the testing version of normal incrementality8.

Later items add the testing-specific controls: output verbosity in 1.2.7 Test Output & Debugging, wildcard and tag behavior in 1.2.3 Test Tags, and the cache model in 1.2.1 Test Caching.

bazel run Builds One Executable and Launches It

bazel run also builds before it does anything else, but its final step is to execute the target for you2,3. Once the single runnable target is up to date, Bazel starts the program and streams its stdout/stderr to your terminal2.

That makes run useful beyond "start my app" — it is also the standard way to invoke targets whose side effects are the point, from formatters to deploy steps4,9. The runtime details (runfiles, working directory, and the side-effect pattern) are covered in 1.1.2 bazel run & Runfiles.

Choose by outcome. If you only need proof that Bazel can produce the binary, build is the cheaper and less side-effectful choice. Reach for run when the execution itself is the point4,9.

key takeaway

build, test, and run all start from the same Bazel graph and the same label syntax, but they stop at different outcomes. build materializes artifacts, test builds and executes test targets, and run builds and launches one runnable target. Remember that build and test scale naturally to target patterns, while run is for a single executable.

Check your understanding · 3 questions

1.Match each Bazel command to the outcome it produces:

Drag each answer onto the matching prompt, or click an answer and then click a prompt

Answers
bazel build //app:server
bazel test //app:server_test
bazel run //app:server

2.True or false: how does bazel run handle target patterns?

Choose True or False for each sentence

bazel run //... launches every executable target in the repository.
bazel run requires a pattern that resolves to exactly one runnable target.
bazel run can only be used with test targets, not binary targets.
The //... pattern is only valid with bazel query.

3.Which of these Bazel commands accept target patterns like //... that expand to multiple targets?

Select all that apply

0 of 3 answered

Footnotes

  1. Build programs with Bazelbazel build semantics, target patterns, and the loading/analyzing/executing model 1 2 3 4 5

  2. Commands and Optionsbazel test and bazel run behavior, single-target run, and stdout/stderr streaming 1 2 3 4 5 6

  3. Build your first Bazel project — Beginner examples of bazel build //..., bazel test //..., and bazel run //:hello-world 1 2 3 4

  4. Bazel Training 101 (Part 11): The 'build' and 'run' commands — Practical distinction between producing an artifact and executing it 1 2 3 4

  5. Using Bazel with Rust to Build and Deploy an Application — Inspecting built outputs via bazel-bin and contrasting build with run

  6. BazelCon 2019 Day 2: Half-Day Bazel Bootcamp (Part 2) — Walkthrough of bazel test, target labels, and locating bazel-testlogs

  7. Bazel Training 101 (Part 14): How Bazel runs tests — Tests as executables Bazel runs and judges by their outcome 1 2

  8. Bazel and automated tests — Example of bazel test reusing a cached passing result

  9. Running build actionsbazel run as the entry point for side-effectful executable targets such as publishing and deployment 1 2