Recently my gut feeling started to point me to the Elixir programming language. I don’t know why, but it just somehow felt right to learn it. And when I had opportunity to make small “pet” project, I jumped stright into coding. Honestly - I was amazed with the experience! I managed to develop this project within few hours without knowing a lot about language itself.
For these who don’t know, Elixir is dynamic functional programming language, so that means OOP skills will not be very useful here. Also you will need to “break” your brain a little bit to adapt to Elixir paradigms if you were coding in OOP style for a long time.
As I enjoy applications covered with tests I was curious what kind of testing possibilites there are in Elixir. By studying more about Elixir I found out that language makes documentation a first-class citizen in the language. You may be wondering now - why I’m talking about documentation now. Well, I’m talking about documentation because you can write Doctests inside the documentation! This way you can show some examples to someone who is using your application/library and also be sure that your examples are working correctly (are covered with tests).
Let’s just jump into example itself (you will need to have Elixir installed on your machine if you will want to repeat these examples. More information about that you can find here):
1 2 3 4 5 6 7 8 9 10 11 # create new project `dtest` $ mix new dtest # change directory and run tests $ cd dtest $ mix test Compiling 1 file (.ex) Generated dtest app . Finished in 0.03 seconds 1 test, 0 failures
After these few commands you have successfuly created new
dtest project and run your first Elixir tests
If you will open
test/dtest_test.exs file now, you will see elementar test example there counting
1 + 1 and assert it to be
2 (this is the one which was shown in output results as
successful and is added by every new project):
1 2 3 4 5 6 7 8 defmodule DtestTest do use ExUnit.Case doctest Dtest test "the truth" do assert 1 + 1 == 2 end end
Now check what’s on LN#3
doctest Dtest. This is the magic line which I was telling you earlier - it runs test cases from documentation if there
are any. To prove this, let’s open
lib/dtest.ex and implement small function with documentation which contains examples.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 defmodule Dtest do @doc """ Approves that DocTests are awesome! ## Examples iex> Dtest.awesome? true """ def awesome? do true end end
And now run
mix test to check the results:
1 2 3 4 5 6 $ mix test ⏎ Compiling 1 file (.ex) .. Finished in 0.06 seconds 2 tests, 0 failures
You can see that now we have
2 successful tests, but we didn’t added test in the
test/dtest_test.exs right? How awesome is that?
To prove that Doctests are run as tests, try changing
Examples section of
awesome/0 function documentation.
Your code should look like this now:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 defmodule Dtest do @doc """ Approves that DocTests are awesome! ## Examples iex> Dtest.awesome? false """ def awesome? do true end end
And rune one more time tests with
mix test command:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 $ mix test Compiling 1 file (.ex) 1) test doc at Dtest.awesome?/0 (1) (DtestTest) test/dtest_test.exs:3 Doctest failed code: Dtest.awesome? === false lhs: true stacktrace: lib/dtest.ex:7: Dtest (module) . Finished in 0.07 seconds 2 tests, 1 failure
And you will get failing test here . Basically failed test is telling us that
Dtest.awesome? === false doesn’t assert.
And on next line
lhs: true it’s telling us that
left hand side we have
true value (function call returned
Don’t know how about you, but I was astonished with Doctests. It probably means that there will be less old/wrong documentations for Elixir functions because of this functionality as tests will just start to break on changes. I really enjoy it and I think I will be using such testing approach in my next projects coding in Elixir! :)
By the way, I highly suggest to check out more about ExUnit.DocTest on hexdocs.pm. You must know few things about aligning to make them work and will find out other different ways how to use DocTest. Happy testing !
Get source code:
git clone firstname.lastname@example.org:janis-vitols/examples.git --branch elixir/testing/simple-doctest-example --single-branch dtest