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.
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
2.True or false: how does bazel run handle target patterns?
Choose True or False for each sentence
3.Which of these Bazel commands accept target patterns like //... that expand to multiple targets?
Select all that apply
Footnotes
-
Build programs with Bazel —
bazel buildsemantics, target patterns, and the loading/analyzing/executing model ↩1 ↩2 ↩3 ↩4 ↩5 -
Commands and Options —
bazel testandbazel runbehavior, single-targetrun, and stdout/stderr streaming ↩1 ↩2 ↩3 ↩4 ↩5 ↩6 -
Build your first Bazel project — Beginner examples of
bazel build //...,bazel test //..., andbazel run //:hello-world↩1 ↩2 ↩3 ↩4 -
Bazel Training 101 (Part 11): The 'build' and 'run' commands — Practical distinction between producing an artifact and executing it ↩1 ↩2 ↩3 ↩4
-
Using Bazel with Rust to Build and Deploy an Application — Inspecting built outputs via
bazel-binand contrastingbuildwithrun↩ -
BazelCon 2019 Day 2: Half-Day Bazel Bootcamp (Part 2) — Walkthrough of
bazel test, target labels, and locatingbazel-testlogs↩ -
Bazel Training 101 (Part 14): How Bazel runs tests — Tests as executables Bazel runs and judges by their outcome ↩1 ↩2
-
Bazel and automated tests — Example of
bazel testreusing a cached passing result ↩ -
Running build actions —
bazel runas the entry point for side-effectful executable targets such as publishing and deployment ↩1 ↩2