# `mix test`
[🔗](https://github.com/elixir-lang/elixir/blob/7ff272706afc522e74121493b7166719985cb099/lib/mix/lib/mix/tasks/test.ex#L5)

Runs the tests for a project.

This task starts the current application, loads up
`test/test_helper.exs` and then, requires all files matching the
`test/**/*_test.exs` pattern in parallel.

A list of files and/or directories can be given after the task
name in order to select the files to run:

    $ mix test test/some/particular/file_test.exs
    $ mix test test/some/particular/dir

Tests in umbrella projects can be run from the root by specifying
the full suite path, including `apps/my_app/test`, in which case
recursive tests for other child apps will be skipped completely:

    # To run all tests for my_app from the umbrella root
    $ mix test apps/my_app/test

    # To run a given test file on my_app from the umbrella root
    $ mix test apps/my_app/test/some/particular/file_test.exs

## Understanding test results

When you run your test suite, it prints results as they run with
a summary at the end, as seen below:

    $ mix test
    Running ExUnit with seed: 646219, max_cases: 16
    ...

      1) test greets the world (FooTest)
         test/foo_test.exs:5
         Assertion with == failed
         code:  assert Foo.hello() == :world!
         left:  :world
         right: :world!
         stacktrace:
           test/foo_test.exs:6: (test)

    ........

    Finished in 0.05 seconds (0.00s async, 0.05s sync)
    1 doctest, 11 tests, 1 failure

For each test, the test suite will print a dot. Failed tests
are printed immediately in the format described in the next
section.

After all tests run, we print the suite summary. The first
line contains the total time spent on the suite, followed
by how much time was spent on async tests (defined with
`use ExUnit.Case, async: true`) vs sync ones:

    Finished in 0.05 seconds (0.00s async, 0.05s sync)

Developers want to minimize the time spent on sync tests
whenever possible, as sync tests run serially and async
tests run concurrently.

Finally, how many tests we have run, how many of them
failed, how many were invalid, and so on.

### Understanding test failures

First, it contains the failure counter, followed by the test
name and the module the test was defined:

    1) test greets the world (FooTest)

The next line contains the exact location of the test in the
`FILE:LINE` format:

    test/foo_test.exs:5

If you want to re-run only this test, all you need to do is to
copy the line above and paste it in front of `mix test`:

    $ mix test test/foo_test.exs:5

Then we show the error message, code snippet, and general information
about the failed test:

    Assertion with == failed
    code:  assert Foo.hello() == :world!
    left:  :world
    right: :world!

If your terminal supports coloring (see the  "Coloring" section below),
a diff is typically shown between `left` and `right` sides. Finally,
we print the stacktrace of the failure:

    stacktrace:
      test/foo_test.exs:6: (test)

## Command line options

  * `--all-warnings` (`--no-all-warnings`) - prints all warnings, including previous compilations
    (default is true except on errors)

  * `-b`, `--breakpoints` *(since v1.17.0)* - sets a breakpoint at the beginning
    of every test. The debugger goes line-by-line and can access all variables
    and imports (but not local functions). You can press `n` for the next line
    and `c` for the next test. This automatically sets `--trace`

  * `--color` - enables color in ExUnit formatting results

  * `--cover` - runs coverage tool. See "Coverage" section below

  * `--dry-run` *(since v1.19.0)* - prints which tests would be run based on current options,
    but does not actually run any tests. This combines with all other options
    like `--stale`, `--only`, `--exclude`, and so on.

  * `--exclude` - excludes tests that match the filter. This option may be given
    several times to apply different filters, such as `--exclude ci --exclude slow`.
    A value can also be provided for the filter such as `--exclude async:true` to only
    run the sync tests.

  * `--exit-status` - use an alternate exit status to use when the test suite
    fails (default is 2).

  * `--export-coverage` - the name of the file to export coverage results to.
    Only has an effect when used with `--cover`

  * `--failed` - runs only tests that failed the last time they ran

  * `--force` - forces compilation regardless of modification times

  * `--formatter` - sets the formatter module that will print the results.
    Defaults to ExUnit's built-in CLI formatter

  * `--include` - includes tests that match the filter. This option may be given
    several times to apply different filters, such as `--include ci --include slow`

  * `--listen-on-stdin` - runs tests, and then listens on stdin. It will
    re-run tests once a newline is received. See the "File system watchers"
    section below

  * `--max-cases` - sets the maximum number of tests running asynchronously. Only tests from
    different modules run in parallel. Defaults to twice the number of cores

  * `--max-failures` - the suite stops evaluating tests when this number of test
    failures is reached. It runs all tests if omitted

  * `--max-requires` - sets the maximum number of test files to compile in parallel.
    Setting this to `1` will compile test files sequentially.

  * `-n`, `--name-pattern` *(since v1.19.0)* - only run tests with names that match
    the given regular expression

  * `--no-archives-check` - does not check archives

  * `--no-color` - disables color in the output

  * `--no-compile` - does not compile, even if files require compilation

  * `--no-deps-check` - does not check dependencies

  * `--no-elixir-version-check` - does not check the Elixir version from `mix.exs`

  * `--no-start` - does not start applications after compilation

  * `--only` - runs only tests that match the filter. Such as `--only ci`. A value
    can also be provided for the filter such as `--only async:true` to only
    run the async tests.

  * `--partitions` - sets the amount of partitions to split tests in. It must be
    a number greater than zero. If set to one, it acts a no-op. If more than one,
    then you must also set the `MIX_TEST_PARTITION` environment variable with the
    partition to use in the current test run. See the "Operating system process
    partitioning" section for more information

  * `--preload-modules` - preloads all modules defined in applications

  * `--profile-require time` - profiles the time spent to require test files.
    Used only for debugging. The test suite does not run

  * `--raise` - immediately raises if the test suite fails, instead of continuing
    the execution of other Mix tasks

  * `--repeat-until-failure` *(since v1.17.0)* - sets the number of repetitions for running
    the suite until it fails. This is useful for debugging flaky tests within the same instance
    of the Erlang VM. For example, `--repeat-until-failure 10000` repeats the test suite
    up to 10 000 times until the first failure. This can be combined with `--max-failures 1`
    to immediately stop if one test fails. However, if there is any leftover global state
    after running the tests, re-running the suite may trigger unrelated failures.

  * `--seed` - seeds the random number generator used to randomize the order of tests;
    `--seed 0` disables randomization so the tests in a single file will always be ran
    in the same order they were defined in

  * `--slowest` - prints timing information for the N slowest tests. Includes time spent in
   `ExUnit.Callbacks.setup/1`. Automatically sets `--trace` and `--preload-modules`

  * `--slowest-modules` *(since v1.17.0)* - prints timing information for the N slowest
    modules. Includes time spent in `ExUnit.Callbacks.setup/1`. Automatically sets
    `--trace` and `--preload-modules`

  * `--stale` - runs only tests which reference modules that changed since the
    last time tests were ran with `--stale`. You can read more about this option
    in the "The --stale option" section below

  * `--timeout` - sets the timeout for the tests

  * `--trace` - runs tests with detailed reporting. Automatically sets `--max-cases` to `1`.
    Note that in trace mode test timeouts will be ignored as timeout is set to `:infinity`

  * `--warnings-as-errors` *(since v1.12.0)* - treats compilation warnings (from loading the
    test suite) as errors and returns an exit status of 1 if the test suite would otherwise
    pass. If the test suite fails and also include warnings as errors, the exit
    status returned will be the value of the `--exit-status` option, which
    defaults to `2`, plus one. Therefore in the default case, this will be exit status `3`.

    Note that failures reported by `--warnings-as-errors` cannot be retried with the
    `--failed` flag.

    This option only applies to test files. To treat warnings as errors during compilation and
    during tests, run:
        MIX_ENV=test mix do compile --warnings-as-errors + test --warnings-as-errors

## Configuration

These configurations can be set in the `def project` section of your `mix.exs`:

  * `:test_coverage` - a set of options to be passed down to the coverage
    mechanism. See the "Coverage" section for more information

  * `:test_elixirc_options` - the compiler options to used when
    loading/compiling test files. By default it disables the debug chunk,
    docs chunk, and module type inference

  * `:test_paths` - list of paths containing test files. Defaults to
    `["test"]` if the `test` directory exists, otherwise, it defaults to `[]`.
    It is expected that all test paths contain a `test_helper.exs` file

  * `:test_pattern` - a pattern to find potential test files. Defaults to `"*.{ex,exs}"`.

    Once files are found, they are filtered in two ways:

      * Files that match `:test_load_filters` are loaded
      * Files that match `:test_ignore_filters` are ignored
      * All other files emit a warning

    In Elixir versions earlier than 1.19.0, this option defaulted to `*_test.exs`.

  * `:test_load_filters` - a list of files, regular expressions or one-arity
    functions to restrict which files matched by the `:test_pattern` are loaded.
    Defaults to `[&String.ends_with?(&1, "_test.exs")]`. Paths are relative to
    the project root and separated by `/`, even on Windows.

  * `:test_ignore_filters` - a list of files, regular expressions or one-arity
    functions to ignore by the loader. Any file that is not loaded and not
    ignored will emit a warning.

    Mix ignores files ending in `_helper.exs` by default, as well as any file
    included in the project's `:elixirc_paths`.

    For example, to ignore all files in a `test/support/` folder:

        def project do
          [
            ...,
            test_ignore_filters: [&String.starts_with?(&1, "test/support/")]
          ]
        end

    You may choose to disable all warnings by ignoring all files with
    `[fn _ -> true end]`.

    Paths are relative to the project root and separated by `/`, even on Windows.

## Coloring

Coloring is enabled by default on most Unix terminals. They are also
available on Windows consoles from Windows 10, although it must be
explicitly enabled for the current user in the registry by running
the following command:

    $ reg add HKCU\Console /v VirtualTerminalLevel /t REG_DWORD /d 1

After running the command above, you must restart your current console.

## Tags and filters

ExUnit provides tags and filtering functionality that allow developers
to select which tests to run. The most common functionality is to exclude
some particular tests from running by default in your test helper file:

    # Exclude all external tests from running
    ExUnit.configure(exclude: [external: true])

Then, whenever desired, those tests could be included in the run via the
`--include` option:

    $ mix test --include external:true

The example above will run all tests that have the external option set to
`true`. It is also possible to include all examples that have a given tag,
regardless of its value:

    $ mix test --include external

Note that all tests are included by default, so unless they are excluded
first (either in the test helper or via the `--exclude` option) the
`--include` option has no effect. The order in which filters are applied
is also consistent: first all exclusions are computed, then the inclusions.

For convenience, Mix also provides an `--only` option that excludes all tests
and includes only the given ones:

    $ mix test --only external

Which is similar to:

    $ mix test --include external --exclude test

However, when the `--only` option is used and no tests run, the test run fails.

In case a single file is being tested, it is possible to pass one or more specific
line numbers to run only those given tests:

    $ mix test test/some/particular/file_test.exs:12

Which is equivalent to:

    $ mix test --exclude test --include line:12 test/some/particular/file_test.exs

Or:

    $ mix test test/some/particular/file_test.exs:12:24

Which is equivalent to:

    $ mix test --exclude test --include line:12 --include line:24 test/some/particular/file_test.exs

If a given line starts a `describe` block, that line filter includes all tests
within the describe. Otherwise, it runs the closest test on or before the given
line number.

## Coverage

Elixir provides built-in line-based test coverage via the `--cover` flag.
The test coverages shows which lines of code and in which files were executed
during the test run.

### Limitations

Elixir uses Erlang's [`:cover`](`:cover`) for its default test coverage.
Erlang coverage is done by tracking *executable lines of code*. See
`mix test.coverage` for details.

### Configuration

The `:test_coverage` configures the coverage tool and the default tool
accepts the following options:

  * `:tool` - a module specifying the coverage tool to use.
    Defaults to `Mix.Tasks.Test.Coverage`.

  * `:output` - the output directory for cover results.
    Defaults to `"cover"`.

  * `:summary` - at the end of each coverage run, a summary of each
    module is printed, with results in red or green depending on whether
    the percentage is below or above a given threshold. The task will
    exit with status of 1 if the total coverage is below the threshold.
    The `:summary` option allows you to customize the summary generation
    and defaults to `[threshold: 90]`, but it may be set to `false` to
    disable such reports.

  * `:export` - a filename to export results to instead of generating
    the coverage result on the fly. The `.coverdata` extension is
    automatically added to the given file. This option is automatically
    set via the `--export-coverage` option or when using process partitioning.
    See `mix test.coverage` to compile a report from multiple exports.

  * `:ignore_modules` - modules to ignore from generating reports and
    in summaries. It is a list of module names as atoms and regular
    expressions that are matched against the module names.

  * `:local_only` - by default coverage only tracks local calls,
    set this option to false if you plan to run coverage across nodes.

By default, a wrapper around OTP's `cover` is used as the coverage tool.
You can learn more about how it works in the docs for `mix test.coverage`.
Your tool of choice can be given as follows:

    def project() do
      [
        ...
        test_coverage: [tool: CoverModule]
        ...
      ]
    end

`CoverModule` can be any module that exports `start/2`, receiving the
compilation path and the `test_coverage` options as arguments.
It must return either `nil` or an anonymous function of zero arity that
will run after the test suite is done.

## Operating system process partitioning

While ExUnit supports the ability to run tests concurrently within the same
Elixir instance, it is not always possible to run all tests concurrently. For
example, some tests may rely on global resources.

For this reason, `mix test` supports partitioning the test files across
different Elixir instances. This is done by setting the `--partitions` option
to an integer, with the number of partitions, and setting the `MIX_TEST_PARTITION`
environment variable to control which test partition that particular instance
is running. This can also be useful if you want to distribute testing across
multiple machines.

For example, to split a test suite into 4 partitions and run them, you would
use the following commands:

    $ MIX_TEST_PARTITION=1 mix test --partitions 4
    $ MIX_TEST_PARTITION=2 mix test --partitions 4
    $ MIX_TEST_PARTITION=3 mix test --partitions 4
    $ MIX_TEST_PARTITION=4 mix test --partitions 4

The test files are sorted upfront in a round-robin fashion. Note the partition
itself is given as an environment variable so it can be accessed in config files
and test scripts. For example, it can be used to setup a different database instance
per partition in `config/test.exs`.

If partitioning is enabled and `--cover` is used, no cover reports are generated,
as they only contain a subset of the coverage data. Instead, the coverage data
is exported to files such as `cover/MIX_TEST_PARTITION.coverdata`. Once you have
the results of all partitions inside `cover/`, you can run `mix test.coverage` to
get the unified report.

## The --stale option

The `--stale` command line option attempts to run only the test files which
reference modules that have changed since the last time you ran this task with
`--stale`.

The first time this task is run with `--stale`, all tests are run and a manifest
is generated. On subsequent runs, a test file is marked "stale" if any modules it
references (and any modules those modules reference, recursively) were modified
since the last run with `--stale`. A test file is also marked "stale" if it has
been changed since the last run with `--stale`.

The `--stale` option is extremely useful for software iteration, allowing you to
run only the relevant tests as you perform changes to the codebase.

## File-system watchers

You can integrate `mix test` with file system watchers through the command line
via the `--listen-on-stdin` option. For example, you can use [fswatch](https://github.com/emcrisostomo/fswatch)
or similar to emit newlines whenever there is a change, which will cause your test
suite to re-run:

    $ fswatch lib test | mix test --listen-on-stdin

This can be combined with the `--stale` option to re-run only the test files that
have changed as well as the tests that have gone stale due to changes in `lib`.

## Aborting the suite

It is possible to abort the test suite with `Ctrl+\ `, which sends a SIGQUIT
signal to the Erlang VM. ExUnit will intercept this signal to show all tests
that have been aborted and print the results collected so far.

This can be useful in case the suite gets stuck and you don't want to wait
until the timeout times passes (which defaults to 30 seconds).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
