Getting Started With EUnit

Posted by on September 26, 2008

Up to this point, my experience with Erlang professionally has mostly been with ejabberd. I’ve created many ejabberd modules and have had to modify ejabberd core for certain projects (sometimes heavily). Now that my current client work at CitrusByte is over, I’ve been notified I will be working on a fairly customized Erlang/OTP application. Without going into too much detail, I have just began seriously looking at EUnit.

In the past I have unit tested my Erlang source files by manually creating a test method and running it via a bash script. This works, but it is a bit hard to manage and you don’t get a lot of things for free; I just used pattern matching for the unit tests. Now that I’m starting a new project, I decided to start right with a proper unit testing framework. For those of you not familiar with the practice of “unit testing,” this article is not for you and you should google around, there are thousands of resources available.

Getting EUnit

For some reason I assumed Erlang would come shipped with EUnit, and spent a good 10 minutes “debugging” why my unit tests weren’t available! Of course I was wrong, I had to go grab EUnit myself. You can grab it by checking it out of the EUnit trunk via SubVersion. I know there is a ZIP file also available on process-one’s website but the code is pretty outdated so I recommend checking out the trunk.

Go into the download eunit/ directory and type make to compile all the Erlang source files. After doing this, make sure to copy your eunit/ directory to the Erlang lib directory, which can be found by running code:lib_dir().

Basics of EUnit

There are quite a few resources for EUnit which I’ll link at the end of this article. So as not to totally reinvent the wheel I’m only going to cover a few topics here and will trust that you have the drive to read the other articles which are fantastic for getting off the ground.

EUnit is minimally invasive to your code. By this I mean the only real change you need to make to your source files to get it up and running is to include a header file. Here is an example of the preprocessor command I use:

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

 

This header file does do a small amount of magic. That is, it automatically exports a test/0 method from the module if it doesn’t exist already. This test method automatically calls any methods ending in _test or _test_ (a subtle but important difference).

The *_test methods are expected to return anything on success, or throw an exception on failure. Erlang actually has a great testing construct baked into the language: pattern matching. This is what 90% of your tests will use. The following is an example test:

reverse_test() ->
  [3, 2, 1] = lists:reverse([1, 2, 3]).

 

This test will pass. If instead I put [3, 1, 2] it would have raised a badmatch exception and the test would have failed. Simple, isn’t it?

Getting More Advanced

This is just the surface of EUnit, but luckily, the rest of it isn’t much harder to understand. Unfortunately, EUnit doesn’t have mocks/stubs, which many Ruby programmers may miss (as we are all spoiled with our RSpec). I’m not going to cover any more of EUnit in this article since there are a handful of articles who do this already, and I don’t want to steal their thunder.

But one last thing I really liked…

Hiding Your Tests In Production Systems

Its great that EUnit automagically exports your test methods and runs them and all that but after the tests pass and the green icon shows, nobody really wants these in a running system. Unsurprisingly, EUnit developers already thought of this and offer an easy way out: Simply define NOTEST before you include the EUnit header file. If this is defined, nothing will happen.

I put NOTEST in all my files right away. Don’t worry, to run the tests you don’t have to manually remove this line. When you compile your Erlang source files for testing, add the -DTEST flag to the compiler, which will define the TEST macro. This overrides NOTEST. :) An example erlc command:

erlc -DTEST module.erl

 

The Resources

The following is a list of valuable resources I found picking up Erlang. All gain my stamp of approval (if that means anything to you).

As a final note or disclaimer: I haven’t used EUnit a great amount yet in a professional environment so this is a very high-level overview of EUnit. I’m sure as time goes on and this new project goes on, I will have more to say. :)

Trackbacks

Use this link to trackback from your own site.

Comments

Leave a response

  1. [...] Getting Started With EUnit | spawn_link (tags: erlang unit test testing) This was written by andy. Posted on Tuesday, September 30, 2008, at 1:30 am. Filed under Delicious. Bookmark the permalink. Follow comments here with the RSS feed. Post a comment or leave a trackback. [...]

  2. [...] Getting Started with EUnit (Mitchell Hashimoto) [...]

  3. Chris Oct 23, 2008 20:56

    Off-Topic: Mitch, Could you please provide your modified zenburn.vim (or whatever you modified besides your zenburn.vim to colorize function names)? :-)

    P.S.: Nice articles, thank you very much!

  4. Mitchell Oct 23, 2008 21:09

    Chris,

    This is actually pretty lame but I use the Zenburn theme for emacs along with htmlize to just htmlize my buffers and then paste them here. I couldn’t find a good syntax highlighter with rules to highlight Erlang and was too busy to write one up myself.

    Mitchell

  5. JP Oct 28, 2008 08:53

    Hi,

    great introduction to eunit.
    I personaly use extremeforge which is a zero button testing env. for erlang. great stuff, no assert : it uses pattern matching for assertions.
    see http://www.extremeforge.net/

    ps : keep on writing articles on erlang, you’re doing a great job (see your articles about OTP : awesome!)

  6. John Bender Dec 25, 2008 23:38

    @Chris

    I just use gist.github.com for my blog, though I’m not sure what the expiration on those puppies is.

    @Mitchell

    Please post as often as you can, you’re site is a favorite of mine after reading the OTP intro.

    Cheers!

  7. Witold Baryluk Feb 20, 2009 11:23

    Wow, unit testing is simpler than I was thinking :) How about some more example of unit testing, for example of gen_servers?

Comments

Comments: