# Elixir TDD with ExUnit (interview / toy problem)

This is part one of a series on Elixir Testing.

In this episode we'll use the built-in library ExUnit to TDD our way through building a module to calculate Fibonacci numbers. We'll have two primary functions—`Fibonacci.nth/1` which will return the nth number of Fibonacci sequence, and `Fibonacci.first_n/1` which will return a list of the the first n numbers of the sequence.

Since the goal is to use TDD, we'll stick to a red -> green -> refactor workflow, even when optimizing for performance!

### The end state for our test module:

This is what our tests look like when we're done:

``````defmodule FibonacciTest do
use ExUnit.Case
doctest Fibonacci
@moduletag timeout: 1000

describe "calculate the nth fibonacci number" do
test "the first number is 1" do
assert Fibonacci.nth(1) == 1
end

test "the second number is 1" do
assert Fibonacci.nth(2) == 1
end

test "the third number is 2" do
assert Fibonacci.nth(3) == 2
end

test "the fourth number is 3" do
assert Fibonacci.nth(4) == 3
end

test "the fifth number is 5" do
assert Fibonacci.nth(5) == 5
end

test "the sixth number is 8" do
assert Fibonacci.nth(6) == 8
end

test "shouldn't take too long" do
assert Fibonacci.nth(100) == Fibonacci.nth(99) + Fibonacci.nth(98)
end
end

describe "calculate the first n fibonacci numbers" do
test "doesn't return any for zero" do
assert Fibonacci.first_n(0) == []
end

test "returns the first number for one" do
assert Fibonacci.first_n(1) == 
end

test "two returns the first two numbers" do
assert Fibonacci.first_n(2) == [1, 1]
end

test "6 returns the first 6 numbers" do
assert Fibonacci.first_n(6) == [1, 1, 2, 3, 5, 8]
end

test "10000 isn't too slow" do
first10k = Fibonacci.first_n(10000)
assert Fibonacci.first_n(10001) == first10k ++ [Fibonacci.nth(10001)]
end
end
end``````

### The end state for our Fibonacci module:

``````defmodule Fibonacci do
@moduledoc """
Documentation for Fibonacci.
"""

@doc """
Calculates numbers from the Fibonacci sequence
## Examples
iex> Fibonacci.nth(1)
1
"""

def nth(n), do: nth(n - 1, 0, 1)
def nth(0, _acc1, acc2), do: acc2
def nth(n, acc1, acc2), do: nth(n - 1, acc2, acc1 + acc2)

def first_n(n), do: first_n(n, [])
def first_n(0, acc), do: Enum.reverse(acc)
def first_n(n, []), do: first_n(n - 1, )
def first_n(n, ), do: first_n(n - 1, [1, 1])

def first_n(n, [e1 | [e2 | _tail]] = acc) do
first_n(n - 1, [e1 + e2 | acc])
end
end``````

Next episode: Fixing generated Phoenix tests

Back to index