# ExUnit v1.10.3 ExUnit.DocTest View Source

ExUnit.DocTest implements functionality similar to Python's doctest.

It allows us to generate tests from the code examples in a module/function/macro's documentation. To do this, invoke the `doctest/1` macro from within your test case and ensure your code examples are written according to the syntax and guidelines below.

## Syntax

Every new test starts on a new line, with an `iex>` prefix. Multiline expressions can be used by prefixing subsequent lines with either `...>` (recommended) or `iex>`.

The expected result should start at the next line after the `iex>` or `...>` line(s) and is terminated either by a newline, new `iex>` prefix or the end of the string literal.

## Examples

To run doctests include them in an ExUnit case with a `doctest` macro:

    defmodule MyModuleTest do
      use ExUnit.Case, async: true
      doctest MyModule
    end

The `doctest` macro loops through all functions and macros defined in `MyModule`, parsing their documentation in search of code examples.

A very basic example is:

    iex> 1 + 1
    2

Expressions on multiple lines are also supported:

    iex> Enum.map([1, 2, 3], fn x ->
    ...>   x * 2
    ...> end)
    [2, 4, 6]

Multiple results can be checked within the same test:

    iex> a = 1
    1
    iex> a + 1
    2

If you want to keep any two tests separate, add an empty line between them:

    iex> a = 1
    1

    iex> a + 1 # will fail with a "undefined function a/0" error
    2

If you don't want to assert for every result in a doctest, you can omit the result. You can do so between expressions:

    iex> pid = spawn(fn -> :ok end)
    iex> is_pid(pid)
    true

As well as at the end:

    iex> Mod.do_a_call_that_should_not_raise!(...)

This is useful when the result is something variable (like a PID in the example above) or when the result is a complicated data structure and you don't want to show it all, but just parts of it or some of its properties.

Similarly to IEx you can use numbers in your "prompts":

    iex(1)> [1 + 2,
    ...(1)>  3]
    [3, 3]

This is useful in two cases:

- being able to refer to specific numbered scenarios
- copy-pasting examples from an actual IEx session

You can also select or skip functions when calling `doctest`. See the documentation on the `:except` and `:only` options below for more information.

## Opaque types

Some types' internal structures are kept hidden and instead show a user-friendly structure when inspected. The idiom in Elixir is to print those data types in the format `#Name<...>`. Because those values are treated as comments in Elixir code due to the leading `#` sign, they require special care when being used in doctests.

Imagine you have a map that contains a MapSet and is printed as:

    %{users: #MapSet<[:foo, :bar]>}

If you try to match on such an expression, `doctest` will fail to compile. There are two ways to resolve this.

The first is to rely on the fact that doctest can compare internal structures as long as they are at the root. So one could write:

    iex> map = %{users: Enum.into([:foo, :bar], MapSet.new())}
    iex> map.users
    #MapSet<[:foo, :bar]>

Whenever a doctest starts with "#Name<", `doctest` will perform a string comparison. For example, the above test will perform the following match:

    inspect(map.users) == "#MapSet<[:foo, :bar]>"

Alternatively, since doctest results are actually evaluated, you can have the MapSet building expression as the doctest result:

    iex> %{users: Enum.into([:foo, :bar], MapSet.new())}
    %{users: Enum.into([:foo, :bar], MapSet.new())}

The downside of this approach is that the doctest result is not really what users would see in the terminal.

## Exceptions

You can also showcase expressions raising an exception, for example:

    iex(1)> String.to_atom((fn -> 1 end).())
    ** (ArgumentError) argument error

What DocTest will be looking for is a line starting with `** (` and it will parse it accordingly to extract the exception name and message. At this moment, the exception parser would make the parser treat the next line as a start of a completely new expression (if it is prefixed with `iex>`) or a no-op line with documentation. Thus, multiline messages are not supported.

## When not to use doctest

In general, doctests are not recommended when your code examples contain side effects. For example, if a doctest prints to standard output, doctest will not try to capture the output.

Similarly, doctests do not run in any kind of sandbox. So any module defined in a code example is going to linger throughout the whole test suite run.

# Link to this section Summary

## Functions

doctest(module, opts \\ [])

This macro is used to generate ExUnit test cases for doctests.

# Link to this section Functions

Link to this macro

# doctest(module, opts \\ [])

View Source (macro)

This macro is used to generate ExUnit test cases for doctests.

Calling `doctest(Module)` will generate tests for all doctests found in the `module`.

Options can also be given:

- `:except` - generates tests for all functions except those listed (list of `{function, arity}` tuples, and/or `:moduledoc`).

- `:only` - generates tests only for functions listed (list of `{function, arity}` tuples, and/or `:moduledoc`).

- `:import` - when `true`, one can test a function defined in the module without referring to the module name. However, this is not feasible when there is a clash with a module like Kernel. In these cases, `:import` should be set to `false` and a full `Module.function` construct should be used.

## Examples

    doctest MyModule, except: [:moduledoc, trick_fun: 1]

This macro is auto-imported with every `ExUnit.Case`.