# UI tests
<!-- toc -->
UI tests are a particular [test suite](compiletest.md#test-suites) of
compiletest.
## Introduction
The tests in [`tests/ui`] are a collection of general-purpose tests which
primarily focus on validating the console output of the compiler, but can be
used for many other purposes. For example, tests can also be configured to [run
the resulting program](#controlling-passfail-expectations) to verify its
behavior.
If you need to work with `#![no_std]` cross-compiling tests, consult the
[`minicore` test auxiliary](./minicore.md) chapter.
## General structure of a test
A test consists of a Rust source file located anywhere in the `tests/ui`
directory, but they should be placed in a suitable sub-directory. For example,
[`tests/ui/hello.rs`] is a basic hello-world test.
Compiletest will use `rustc` to compile the test, and compare the output against
the expected output which is stored in a `.stdout` or `.stderr` file located
next to the test. See [Output comparison](#output-comparison) for more.
Additionally, errors and warnings should be annotated with comments within the
source file. See [Error annotations](#error-annotations) for more.
Compiletest [directives](directives.md) in the form of special comments prefixed
with `//@` control how the test is compiled and what the expected behavior is.
Tests are expected to fail to compile, since most tests are testing compiler
errors. You can change that behavior with a directive, see [Controlling
pass/fail expectations](#controlling-passfail-expectations).
By default, a test is built as an executable binary. If you need a different
crate type, you can use the `#![crate_type]` attribute to set it as needed.
## Output comparison
UI tests store the expected output from the compiler in `.stderr` and `.stdout`
snapshots next to the test. You normally generate these files with the `--bless`
CLI option, and then inspect them manually to verify they contain what you
expect.
The output is normalized to ignore unwanted differences, see the
[Normalization](#normalization) section. If the file is missing, then
compiletest expects the corresponding output to be empty.
There can be multiple stdout/stderr files. The general form is:
```text
*test-name*`.`*revision*`.`*compare_mode*`.`*extension*
```
- *test-name* cannot contain dots. This is so that the general form of test
output filenames have a predictable form we can pattern match on in order to
track stray test output files.
- *revision* is the [revision](#cfg-revisions) name. This is not included when
not using revisions.
- *compare_mode* is the [compare mode](#compare-modes). This will only be
checked when the given compare mode is active. If the file does not exist,
then compiletest will check for a file without the compare mode.
- *extension* is the kind of output being checked:
- `stderr` — compiler stderr
- `stdout` — compiler stdout
- `run.stderr` — stderr when running the test
- `run.stdout` — stdout when running the test
- `64bit.stderr` — compiler stderr with `stderr-per-bitwidth` directive on a
64-bit target
- `32bit.stderr` — compiler stderr with `stderr-per-bitwidth` directive on a
32-bit target
A simple example would be `foo.stderr` next to a `foo.rs` test.
A more complex example would be `foo.my-revision.polonius.stderr`.
There are several [directives](directives.md) which will change how compiletest
will check for output files:
- `stderr-per-bitwidth` — checks separate output files based on the target
pointer width. Consider using the `normalize-stderr` directive instead (see
[Normalization](#normalization)).
- `dont-check-compiler-stderr` — Ignores stderr from the compiler.
- `dont-check-compiler-stdout` — Ignores stdout from the compiler.
UI tests run with `-Zdeduplicate-diagnostics=no` flag which disables rustc's
built-in diagnostic deduplication mechanism. This means you may see some
duplicate messages in the output. This helps illuminate situations where