View Source doctest

A library to test Erlang -moduledoc and -doc attributes.

Requirements

OTP >= 27.

Installation

% rebar.config
{profiles, [
    {test, [
        {deps, [{doctest, "0.4.0"}]}
    ]}
]}.

Usage

You can run tests via shell or via parse_transform.

shell

Take this module:

-module(foo).
-moduledoc """
Module doc tags can also be tested.

```erlang
1> foo:foo() =:= bar.
true
```
""".

-export([foo/0]).

-doc """
```erlang
1> foo:foo().
foo
```
""".
foo() ->
    bar.

Running it via shell:

1> doctest:module(foo).
.F
Failures:

  1) doctest:-parse/4-fun-0-/0:13
     Failure/Error: ?assertEqual(foo, foo:foo())
       expected: foo
            got: bar
     %% eunit_proc.erl:583:in `eunit_proc:run_group/2`
     Output:
     Output:

Finished in 0.013 seconds
2 tests, 1 failures

parse_transform

Take this module:

-module(math).

-export([add/2]).

-ifdef(TEST).
-include_lib("doctest/include/doctest.hrl").
% -doctest <see the options section>.
-endif.

-doc """
Adds two numbers together.

_Example_:
```erlang
1> math:add(0, 1).
1
2> math:add(
.. 1,
.. 1
.. ).
2
```
""".
add(A, B) ->
    A+B.

Note that the code is defined like the Erlang shell, starting with N>, where N is a number, and continues in multiple lines with ... The result is a value without starting with those shell symbols.

Now, by running rebar3 eunit:

Finished in 0.018 seconds
2 tests, 0 failures

By changing the first test to:

1> math:add(1, 1).
1

And running rebar3 eunit again:

Failures:

  1) doctest_parse_transform:-parse/4-fun-0-/0:26
     Failure/Error: ?assertEqual(1, math:add(1, 1))
       expected: 1
            got: 2
     %% eunit_proc.erl:583:in `eunit_proc:run_group/2`
     Output:
     Output:

Finished in 0.010 seconds
2 tests, 1 failures

Options

Options are defined via the -doctest attribute and can be defined multiple times.

Available options

  • boolean(): enable or disable tests.
    -doctest true.
  • [{atom(), arity()}] | all: define the functions to be tested.

    -doctest [add/2].
  • map(): define all or partial options.
    -doctest #{
        enabled => true,
        funs => [add/2]
    }.

Important

Currently, only exported functions can be tested.

TODO

  • [ ] Add option to skip moduledoc test;
  • [ ] Create doctest:module/2, where options are the second argument;
  • [ ] More tests;
  • [ ] Improve docs;

Sponsors

If you like this tool, please consider sponsoring me. I'm thankful for your never-ending support :heart:

I also accept coffees :coffee:

"Buy Me A Coffee"

Contributing

Issues

Feel free to submit an issue on Github.

License

Copyright (c) 2024 William Fank Thomé

doctest is 100% open source and community-driven. All components are available under the Apache 2 License on GitHub.

See LICENSE.md for more information.