Erlang EUnit – continuation 2 – Test Representation

Having passed through basics and some setup / teardown, it’s time to discuss test representation, a very broad subject which invites for misconceptions.

Basics of Representation

As always, the foundation for the discussion is the EUnit manual pages, where it is stated that a test can be defined in many different ways, and to keep the discussion very short, I shall supply some common examples of what is often seen/used.

Simple Test Objects

Each representation form will be shown with examples based on the mylist module defined in the first post. So, each Simple Test Object (STO) can be defined by

Any nullary function (function with zero arguments)

What this implies is that your STO is encapsulated within a functional object and may be executed  by EUnit. More or less you can put yourself in EUnit’s shoes (some very special shoes) and the user gives you a “black box”, which you simply execute. No need to care about other stuff. Just execute it. Examples of STO’s

nullarySTO1() -> ?assertEqual(6,mylist:sum([1,2,3])).            
fun() -> ?assertEqual(6,mylist:sum([1,2,3])) end.
fun nullarySTO1/0

These are fundamental nullary STO’s

A Module Function Tuple

This is just a different way of reaching the nullary function by the module and function name. Here it is implicit that the functionname is a nullary function. This will not work with {mylist_tests, nullarySTO2 } which will be seen below. Why? Because nullarySTO2() RETURNS a nullary functional object.

tupleSTO1() -> { mylist_tests, nullarySTO1 }.

A Linenumber / STO Tuple (generated by _test(Expr) macro)

According do our best friend, (the user’s guide) “LineNumber is a nonnegative integer …. LineNumber should indicate the source line of the test”. Wow, so it’s the linenumber in the sourcecode for where the tests is. For some reason, this can be written by hand, but luckily the _test(Expr) macro does it for us.

tupleSTO2() ->?_test( begin ?assertEqual(6,mylist:sum([1,2,3])) end ).

Test Sets and Test Generator Basics

One last thing on the basics of representation is that EUnit does not make any “type”-difference between a deep list of STO’s and single STO, that is.

TestSet := [ TestSet ] | STO

So, a Test-Set can be a so called deep list of Test-Sets, to any level, or just a single STO. Also, a Test Generator is a function that ends with _test_() and returns a TestSet. End of story. Like this

my_generator1_test_() -> fun nullarySTO1/0.
my_generator2_test_() -> [ fun nullarySTO1/0, tupleSTO2() ]

What we have seen is all valid erlang EUnit. To prove it, let us place it in a grand EUnit file, compile and run. Below follows the example mylists_tests.erl module, with compilation and running as usual.

EUnit Example File


nullarySTO1() ->?assertEqual(6,mylist:sum([1,2,3])).
nullarySTO2() ->fun() ->?assertEqual(6,mylist:sum([1,2,3])) end. 

tupleSTO1() ->{ mylist_tests, nullarySTO1 }.

tupleSTO2() ->?_test( begin ?assertEqual(6,mylist:sum([1,2,3])) end ).

generator_test_() ->   
     fun nullarySTO1/0,

my_generator_test_() ->
    fun nullarySTO1/0.

That is the end of the module, next is the compilation and running.

zentop:EunitBasic3 zenon$ erlc -o ebin/ src/*.erl test/*.erl
zentop:EunitBasic3 zenon$ erl -pa ebin/
Erlang R14B03 (erts-5.8.4)  [64-bit] [smp:8:8] [rq:8] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.8.4  (abort with ^G)
1> eunit:test(mylist,[verbose]).       
======================== EUnit ========================
module 'mylist'
  module 'mylist_tests'
    mylist_tests: generator_test_...ok
    mylist_tests: nullarySTO2...ok
    mylist_tests: nullarySTO1...ok
    mylist_tests:10: tupleSTO2...ok
    mylist_tests: my_generator_test_...ok
    [done in 0.014 s]
  [done in 0.014 s]
  All 5 tests passed.

Great! Now, as we know how to write, set up and clean STO’s and TestSets. The next lesson is on Test Control!

%d bloggers like this: