Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erlang Testing (Non Exported / Private) function of module using common test

I have a module in Erlang which has functions that are not exported by Erlang. How can I test / call these functions using common test framework?

like image 936
Smarth Behl Avatar asked Mar 15 '13 13:03

Smarth Behl


People also ask

What is common test in Erlang?

Common Test is the main tool being used in all testing- and verification activities that are part of Erlang/OTP system development and maintenance. Test cases can be executed individually or in batches. Common Test also features a distributed testing mode with central control and logging.

Can I unit test a function that has not been exported?

When writing unit-tests for JavaScript modules, we often encounter a dilemma wherein the module has some private functions that have not been exported. Testing a function that has been exported is easy since it can be imported in the unit testing framework, and the functionality can be tested.

How to test a non-exported function?

In order to test the non-exported function, it needs to be used in an exported function. ❌ So this won't work on its own. ✅ You need to also call this in an exported function of the same file. # Warning! Vuex with Rewire To my dismay, after I finally got rewire set up and successfully added testing for my non-export functions.

What is the common test framework?

The Common Test framework is a tool that supports implementation and automated execution of test cases to any types of target systems. Common Test is the main tool being used in all testing- and verification activities that are part of Erlang/OTP system development and maintenance. Test cases can be executed individually or in batches.


2 Answers

It's tricky with Common Test, but it's possible to use embedded EUnit test cases to test private functions in a module. You can then test the public interface using Common Test. Rebar will automagically discover embedded test cases when you run rebar test.

Here's an example:

-module(example).

-export([public/1]).

-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
-endif.

%% This function will be tested externally using Common Test
public(Foo) ->
    private(Foo + 42).

%% This function is not reachable to CT, so it will be tested using EUnit.
private(Bar) ->
    Bar * 2.

%%% Tests
-ifdef(TEST).

private_test() ->
    ?assertEqual(10, private(5)),
    ?assertEqual(0, private(0)).

-endif.

On a side note, you might find Meck to your liking if you need to mock away a module (or parts thereof) when testing with EUnit.

For a gentle introduction to EUnit, see the Learn You Some Erlang chapter.

like image 56
Martin Törnwall Avatar answered Oct 13 '22 07:10

Martin Törnwall


It is impossible. You can use -ifdef(TEST). preprocessor condition to export those functions only when compiling for testing.

Depending on your tooling, you might need to explicitly provide that TEST macro while compiling the modules. You can do that by using {d,'TEST'} compiler option or -DTEST compilation flag.

like image 33
Dmitry Belyaev Avatar answered Oct 13 '22 06:10

Dmitry Belyaev