Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the preferred way to implement Data Driven Testing using Elixir/ExUnit?

I'd like to reuse the same code of a test case for several handcrafted combinations of input data and expected outcomes, but without copypasting the code for each set. Frameworks in other languages support it in different ways, for example in Groovy/Spock:

def "maximum of two numbers"(int a, int b, int c) {
        expect:
        Math.max(a, b) == c

        where:
        a | b | c
        1 | 3 | 3
        7 | 4 | 4
        0 | 0 | 0
}

What's the preferred way to do this in ExUnit? Maybe ExUnit is not the best framework to this?

like image 816
MachinesAreUs Avatar asked May 07 '15 16:05

MachinesAreUs


2 Answers

I guess you could do something very simple like:

test "Math.max/2" do
  data = [
    {1, 3, 3},
    {7, 4, 4},
  ]

  for {a, b, c} <- data do
    assert Math.max(b, c) == a
  end
end

Pattern matching allows you to be pretty explicit when doing these thing in my opinion. And you can keep the simplicity of just variables and assertions, all inside ExUnit.

like image 181
whatyouhide Avatar answered Sep 22 '22 02:09

whatyouhide


You can also wrap test definitions with an enumerable. Dave Thomas's Blog provides an extended example.

data = [
  {1, 3, 3},
  {7, 4, 4},
]

for {a,b,c} <- data do
  @a a
  @b b
  @c c
  test "func "<>@a<>", "<>@b<>" equals"<>@c do  
    assert fun(@a,@b) == @c 
  end
end

For a relatively simple test like this, I'm not sure this approach is any better, but for more complex tests this can provide better reporting and you can dynamically create tests at test time by using a function as in the blog entry.

like image 41
Fred the Magic Wonder Dog Avatar answered Sep 23 '22 02:09

Fred the Magic Wonder Dog