3

I have an Erlang application based on Cowboy and I would like to test it.

Previously I used wooga's library etest_http for this kind of tasks, but I would like to start using common tests since I noticed that this is the way used in cowboy. I have tried to setup a very basic test but I am not able to run it properly.

Can anybody provide me a sample for testing the basic example echo_get and tell me what is the correct way to run the test from the console using the Makefile contained in the example?

user601836
  • 3,215
  • 4
  • 38
  • 48
  • echo_get does not contain any common test suites. Makefile also doesn't have sections to run common test suites. So if you want to test it with ct you have to implement a test suite. To run suites you can use standard erlang utility ct_run or you can try rebar (https://github.com/basho/rebar). – Danil Onishchenko Oct 28 '13 at 04:55
  • I know echo_get does not contain any test. I was asking for examples. – user601836 Oct 28 '13 at 07:26

3 Answers3

3

The example make used only for build echo_get app. So to test echo_get app you can add test suite and call make && rebar -v 1 skip_deps=true ct (rebar should be in PATH) from shell. Also you need etest and etest_http in your Erlang PATH or add it with rebar.config in your application. You can use httpc or curl with os:cmd/1 instead ehttp_test :)

test/my_test_SUITE.erl (full example)

-module(my_test_SUITE).

-compile(export_all).

-include_lib("common_test/include/ct.hrl").

% etest macros
-include_lib ("etest/include/etest.hrl").
% etest_http macros
-include_lib ("etest_http/include/etest_http.hrl").

suite() ->
    [{timetrap,{seconds,30}}].

init_per_suite(Config) ->
    %% start your app or release here
    %% for example start echo_get release
    os:cmd("./_rel/bin/echo_get_example start"),
    Config.

end_per_suite(_Config) ->
    %% stop your app or release here
    %% for example stop echo_get release
    os:cmd("./_rel/bin/echo_get_example stop")
    ok.

init_per_testcase(_TestCase, Config) ->
    Config.

end_per_testcase(_TestCase, _Config) ->
    ok.

all() -> 
    [my_test_case].

my_test_case(_Config) ->
    Response = ?perform_get("http://localhost:8080/?echo=saymyname"),
    ?assert_status(200, Response),
    ?assert_body("saymyname", Response).
    ok.
sysoff
  • 841
  • 7
  • 7
  • For some reasons the release is not not started. I tried to change to path to os:cmd("../../_rel/bin/echo_get_example [start or stop]") but it doesn't work either. By running in a different shell the release and running the tests it works (even the stop command). Any idea? – user601836 Dec 28 '13 at 12:33
  • What does it mean - release is not started? Some shell output or log will be useful to help you. – sysoff Jan 09 '14 at 04:56
  • i mean, all the tests fails because the server is not running. i can solve it by putting a timer:sleep(1000) after the os:cmd/1 command...but i believe this is not the right way.. – user601836 Jan 09 '14 at 10:17
  • It's a matter of taste. In any case there no another way to start application. You can create shell script that starts your application and then starts tests (`./rel/bin/echo_get_example start && rebar skip_deps=true ct`). But it is the same your test case already does. – sysoff Jan 09 '14 at 11:13
1

The following starts the hello_world application and its dependencies, but uses the most recently compiled versions rather than the one in ./_rel; that may or may not be what you want, but it does avoid the timer:sleep(1000)

-module(hello_world_SUITE).
-include_lib("common_test/include/ct.hrl").
-export([all/0, init_per_suite/1, end_per_suite/1]).
-export([http_get_hello_world/1]).

all() ->
    [http_get_hello_world].

init_per_suite(Config) ->
    {ok, App_Start_List} = start([hello_world]),
    inets:start(),
    [{app_start_list, App_Start_List}|Config].

end_per_suite(Config) ->
    inets:stop(),
    stop(?config(app_start_list, Config)),
    Config.

http_get_hello_world(_Config) ->
    {ok, {{_Version, 200, _ReasonPhrase}, _Headers, Body}} =
        httpc:request(get, {"http://localhost:8080", []}, [], []),
    Body = "Hello World!\n".

start(Apps) ->
    {ok, do_start(_To_start = Apps, _Started = [])}.

do_start([], Started) ->
    Started;
do_start([App|Apps], Started) ->
    case application:start(App) of
    ok ->
        do_start(Apps, [App|Started]);
    {error, {not_started, Dep}} ->
        do_start([Dep|[App|Apps]], Started)
    end.

stop(Apps) ->
    _ = [ application:stop(App) || App <- Apps ],
    ok.
0

Use https://github.com/extend/gun

to run the provided example (considering 'gun' in in 'user' folder): ct_run -suite twitter_SUITE.erl -logdir ./results -pa /home/user/gun/deps/*/ebin /home/user/gun/ebin

Henry H.
  • 901
  • 8
  • 11