- Elixir has an amazing built-in feature that let’s you test code inside the documentation.
- You don’t need to install any tool to write your tests, it’s built-in in the language!
- Elixir has an official dependency that generates a beautiful HTML page for your docs.
One of the first and most impressive characteristics I saw when I started to study Elixir was the powerful yet simple built-in tools to help developers write documentation and tests.
A very special feature is the called
doctest, which is a test that lives inside your documentation. With such tests, you can assure your docs are up-to-date, because whenever you run your tests, the tests inside your documentation will also be verified. Really awesome!
In this article I’ll show you how to write a simple program with unit tests and how to document your code and generate a beautiful HTML documentation page.
You can see the source code here.
Our program should implement the solution for the staircase problem.
The program will receive a positive number
n and should print a staircase right-aligned composed of
# symbols and spaces, with a height and width equals to
input > 6
To create the project, type the following command in your terminal:
mix new staircase
With the structure generated by mix we already can write our program and our test files. Let’s now install the ExDoc library that will generate the HTML documentation page for us.
mix.exs file and add the following line inside the
defp deps do
Now all you need to do is run the command
mix deps.get to install the dependency.
First we’ll write some tests so we’ll be able to easily verify if our solution is actually satisfying our specs.
To do this, go to the already created file inside the
All test files end up with the
.exsextension. The difference between
.exsis that files with the
.exswon’t be compiled, they’re Elixir scripts.
Let’s remove the original test case and add our assertions there:
defmodule StaircaseTest do
Don’t panic! Those tests have some interesting peculiarities and it’ll be a good opportunity to learn them. I know it’s looking a little ugly but I hope after the explanation you’ll be more comfortable with such assertions.
The first piece to note is the
import ExUnit.CaptureIO. This module gives to us the ability to capture the output when a function prints something so we can make an assertion to that output. You can learn more about such module here.
Another interesting part is the
doctest Staircase. This tells that we will run the tests inside the documentation of the module
Staircase together with this suit of tests.
test case, we can see that the
capture_io function, from the
ExUnit.CaptureIO module, receives an anonymous function (
fn -> end). This is how that function works: you should pass an anonymous functions to it so it’ll be called later. Check the documentation linked before to see more ways to use this function.
To finish the explanation of our tests, the string representing the output was written in the line below of our assertion because in that way the spaces before each line wouldn’t mess/broke our assertion and it’s more intuitive to see the final result.
You can see though that Elixir allows us to write strings in multiple lines.
Breaking the specification more granularly, we have to:
- Receive an integer corresponding to the size
nof the staircase
- Generate a string with an arbitrary size containing spaces
- Generate a string with an arbitrary size containing
- Generate a row appending the space string and the char string
- A row should be made of
ncharacters, counting spaces and
- Print such row
A possible solution to accomplish such task could be:
- Create a module
- Create a
mainfunction to receive the input and print each row to the output
- Create a function to generate a string of an arbitrary size composed with an arbitrary char
- Append the string made with spaces and the string made with
- Print the final string
Here is my solution for such task. Such code should be copied to the
staircase.ex file, inside the
defmodule Staircase do
Now that we have our final solution, let’s run our tests to see if it’s working fine.
mix test in your terminal you should see the following message:
> mix test
Great! Now we are almost done. Let’s finish writing some documentation and the most exciting part, the doctests :)
From the Elixir docs:
Elixir treats documentation as a first-class citizen. This means documentation should be easy to write and easy to read.
We can easily confirm this statement. Elixir gives to us the module attributes
@doc so we can write documentation for our modules and functions. You can write in markdown inside your documentation as well.
Let’s see it in practice.
staircase.ex file, below your module definition, let’s add a
defmodule Staircase do
Now let’s describe what our
main function does:
And finally, let’s describe what our
string_gen function does and write some tests inside our documentation!
This last part receives our attention. In order to write code that will be evaluated when you run your tests, you have to put inside your
## Example part exactly in the way it was done here:
- Skip a line
- Add 4 spaces considering the column where
iex>and the function/code that will be tested
- Write what is the expected return of such function in the line below
mix test so you can see we have now 7 tests. Pretty cool!
> mix test
Changing the second assertion to intentionally break the test we can see how helpful and smart ExUnit is.
1) test doc at Staircase.string_gen/2 (2) (StaircaseTest)
It tells exactly what and where the problem is. Amazing stuff, serious.
Our final step is to generate our beautiful documentation page using the ExDoc tool we installed in the beginning of the article.
It’s extremely easy to do so, just run
mix docs and you’re done!
> mix docs
doc/index.html and open the file in your favorite browser to navigate in your docs!
OBS: you can activate the night mode in the end of the page clicking in “Switch to night mode”.
If you want some tips on how to learn Elixir or any other programming language, this article can be helpful.
That’s it! I hope you enjoyed that simple demonstration of the helpful features Elixir brings to us for free.
Until next ;D