I'd like to test some unexported functions using rebar and common_test. What is a clean and efficient way to do this?
My inclination would be to set a macro at compile/test time, and switch on/off export_all in the开发者_运维百科 modules that way, depending on whether it's a production or test build. I want it to be easy--e.g., I don't want to edit a config file before switching from production to test and vice versa. However, I don't see a way to pass arguments to the erl compiler using rebar. Did I miss it?
I know eunit can test unexported functions easily, but I've already got my infrastructure for common_test working well and I don't want to change my workflow right now.
You could just add +export_all
to your erlc
options when you build the modules for your test run. You can do this with {erl_opts, [export_all]}.
in your rebar.config
file. I don't think you can pass extra erlc
arguments to rebar at runtime (e.g. you can't do rebar compile +export_all
) though.
EDIT: Just realised you used common_test
. Please ignore this reply if it doesn't apply!
I have a slightly more advanced way of testing un-exported functions that has the benefit of not exporting them, thus keeping the production code as intact as possible (there might be faults that only occur if some functions are not exported, but is not detected during testing if all functions are exported).
This is how it works using Rebar and EUnit.
In your source file, add these lines:
-ifdef(TEST).
-include("yourmodule_tests.hrl").
-endif.
In your test
folder, add a file called yourmodule_tests.hrl
(in contrast to, for example, yourmodule_tests.erl
in the normal case) and add the following contents:
-include_lib("eunit/include/eunit.hrl").
some_test() ->
?assertEqual(ok, internal_function()).
Add the following configuration to rebar.config
(if you already have erl_opts
, just add the new tuple to that list):
{erl_opts, [{i, "test"}]}.
When you run rebar eunit
Rebar will define the TEST
environment variable and your code will be "test compiled". That is, including your tests into your module and the tests will be able to access internal functions.
If you use anything else than Rebar, just make sure you compile your code with erlc -DTEST ...
when your compiling for tests.
You can add additional compile options that are used by rebar when compiling for eunit. As noted by archaelus, you need the +export_all
option to erlc
. Add the line
{eunit_compile_opts, [export_all]}.
to your rebar.config
file. This is in mentioned in the rebar.config.sample file.
精彩评论