Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A common setup and teardown method for Erlang Eunit test suites

Tags:

erlang

eunit

I am trying to check if all the indexes I have defined in MongoDB are being used by my application and that there are no extra indexes. I have a utility that does that for a single Eunit test suite. However, some of my components have more than one Eunit test suite and I was wondering if there is a way to run common code before any of the test suite is invoked and then run a common teardown code after all the test suites are finished. I am using rebar to invoke the Eunit.

Thanks in advance.

like image 261
Vishal Avatar asked Jan 05 '23 05:01

Vishal


1 Answers

As long the eunit documentation for test representations explains, test sets can be deep lists. Below is an example module showing the use of an outer setup fixture whose tests are generators, each supplying an inner setup fixture. The inner setup fixtures correspond to your existing test suites, each with their own setup and cleanup functions. The outer setup fixture provides the common setup and cleanup for the inner suites.

-module(t).
-compile(export_all).

-include_lib("eunit/include/eunit.hrl").

top_setup() ->
    ?debugMsg("top setup").

top_cleanup(_) ->
    ?debugMsg("top cleanup").

test_t1() ->
    {setup,
     fun() -> ?debugMsg("t1 setup") end,
     fun(_) -> ?debugMsg("t1 cleanup") end,
     [fun() -> ?debugMsg("t1 test 1") end,
      fun() -> ?debugMsg("t1 test 2") end,
      fun() -> ?debugMsg("t1 test 3") end]}.

test_t2() ->
    {setup,
     fun() -> ?debugMsg("t2 setup") end,
     fun(_) -> ?debugMsg("t2 cleanup") end,
     [fun() -> ?debugMsg("t2 test 1") end,
      fun() -> ?debugMsg("t2 test 2") end,
      fun() -> ?debugMsg("t2 test 3") end]}.

t_test_() ->
    {setup,
     fun top_setup/0,
     fun top_cleanup/1,
     [{generator, fun test_t1/0},
      {generator, fun test_t2/0}]}.

Compiling this module and then running it from an Erlang shell produces the expected output:

1> c(t).
{ok,t}
2> eunit:test(t).
/tmp/t.erl:7:<0.291.0>: top setup
/tmp/t.erl:14:<0.293.0>: t1 setup
/tmp/t.erl:16:<0.295.0>: t1 test 1
/tmp/t.erl:17:<0.295.0>: t1 test 2
/tmp/t.erl:18:<0.295.0>: t1 test 3
/tmp/t.erl:15:<0.293.0>: t1 cleanup
/tmp/t.erl:22:<0.293.0>: t2 setup
/tmp/t.erl:24:<0.300.0>: t2 test 1
/tmp/t.erl:25:<0.300.0>: t2 test 2
/tmp/t.erl:26:<0.300.0>: t2 test 3
/tmp/t.erl:23:<0.293.0>: t2 cleanup
/tmp/t.erl:10:<0.291.0>: top cleanup
  All 6 tests passed.
ok

The common setup runs first, then each suite runs bracketed by its own setup and cleanup, and then the common cleanup runs last.

like image 110
Steve Vinoski Avatar answered May 26 '23 20:05

Steve Vinoski