Testing
Learn different types of testing in Elixir.
We'll cover the following...
We already used the ExUnit
framework to write tests for our Issues
tracker application. But that chapter only scratched the surface of Elixir testing. Let’s dig deeper.
Testing the comments
In the Elixir world, a common way to document functions is by showing the function being used in an IEx session.
Let’s look at an example from our Issues
application. The TableFormatter
formatter module defines a number of self-contained functions that we can document.
defmodule Issues.TableFormatter do
import Enum, only: [ each: 2, map: 2, map_join: 3, max: 1 ]
@doc """
The code takes a list of row data, where each row is a map, and a list of headers. It prints a table to standard output of the data from each row identified by each header. That is, each header identifies a column, and those columns are extracted and printed from the rows. We calculate the width of each column to fit the longest element in that column.
"""
def print_table_for_columns(rows, headers) do
with data_by_columns = split_into_columns(rows, headers),
column_widths = widths_of(data_by_columns),
format = format_for(column_widths)
do
puts_one_line_in_columns(headers, format)
IO.puts(separator(column_widths))
puts_in_columns(data_by_columns, format)
end end
@doc """
Given a list of rows where each row contains a keyed list of columns, the code returns a list containing lists of the data in each column. The headers
parameter contains the list of columns to extract.
Run the commands above to execute the code below.
## Example
iex> list = [Enum.into([{"a", "1"},{"b", "2"},{"c", "3"}], %{}),
...> Enum.into([{"a", "4"},{"b", "5"},{"c", "6"}], %{})]
iex> Issues.TableFormatter.split_into_columns(list, [ "a", "b", "c" ])
[ ["1", "4"], ["2", "5"], ["3", "6"] ]
"""
def split_into_columns(rows, headers) do
for header <- headers do
for row <- rows, do: printable(row[header])
end
end
@doc """
the code returns a binary (string) version of our parameter.
## Examples
iex> Issues.TableFormatter.printable("a")
"a"
iex> Issues.TableFormatter.printable(99)
"99"
"""
def printable(str) when is_binary(str), do: str
def printable(str), do: to_string(str)
@doc """
Given a list containing sublists, where each sublist contains the data for a column, the code returns a list containing the maximum width of each column.
## Example
iex> data = [ [ "cat", "wombat", "elk"], ["mongoose", "ant", "gnu"]]
iex> Issues.TableFormatter.widths_of(data)
[ 6, 8 ]
"""
def widths_of(columns) do
for column <- columns, do: column |> map(&String.length/1) |> max
end
@doc """
Given a list containing rows of data, a list containing the header selectors, and a format string, this writes the extracted data under control of the format string.
...