Знайомство з Erlang [26]

Common тести в erlang з ct

продовження попереднього поста про тести в erlang

Unit тести дозволяють потестити одну функцію,
з Common тестами ж можна запустити додаток перед тестами,
та потестити ввесь додаток, не лише окремі функції.

розглянемо написання common тестів - ці тести пишуться в окремому модулі, в директорії test, назва модуля повинна закінчуватись на _SUITE:

файл my_ct_SUITE.erl

-module(my_ct_SUITE).

-compile([export_all, nowarn_export_all]).

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

all() ->
  [
    %% перелік окремих (включених) тестів
    my1_test,
    my2_test,
    my3_test
  ].


%% виконується перед запуском всіх тестів
init_per_suite(Config) ->
  %inets:start(),
  %ssl:start(),
  %{ok, _} = application:ensure_all_started(my_app),
  Config.


%% виконується перед запуском кожного тесту
%% можна матчити по першому аргументу та написати клозу інструкцій для певного тесту
init_per_testcase(_TestCase, Config) ->
  Config.


%% виконується після кожного тесту
%% можна матчити по першому аргументу та написати клозу інструкцій для певного тесту
end_per_testcase(_TestCase, Config) ->
  Config.


%% виконується після завершення всіх тестів
end_per_suite(Config) ->
  Config.


my1_test(_Config) ->
  %% not implemented yet
  ok.

my2_test(_Config) ->
  %% not implemented yet
  ok.

my3_test(_Config) ->
  %% not implemented yet
  ok.

також можливе групування тестів у послідовність:

all() ->
  [
    %% перелік груп
    {group, group1},
    {group, group2},
    {group, group3}
  ].

groups() ->
  [
    {
      group1,      %% назва групи
      [sequence],  %% інструкція для послідовності тестів
      [
        my1_test,
        my2_test,
        my3_test,
        my4_test
      ]
    },
    {
      group2,
      [sequence],
      [
        my5_test,
        my6_test,
        my7_test
      ]
    },
    {
      group3,
      [sequence],
      [
        my8_test,
        my9_test,
        my10_test
      ]
    }
  ].


%% виконується перед запуском групи тестів
%% можна матчити по першому аргументу та написати клозу інструкцій для певної групи тестів
init_per_group(_GroupName, Config) ->
  Config.


%% виконується після завершення групи тестів
%% можна матчити по першому аргументу та написати клозу інструкцій для певної групи тестів
end_per_group(_GroupName, _Config) ->
  ok.

можливе обмеження часу виконання тестів

suite() ->
  [{timetrap, {minutes, 2}}].

також існують інструкції для паралельного виконання тестів,
для виконання тестів у змішаному порядку, і для виконання тестів по колу,
не зупиняючись, поки якийсь з тестів не впаде з помилкою:

all() ->
  [
    {group, my_test_group}
  ].

groups() ->
  [{my_test_group,
    [parallel, shuffle, repeat_until_any_fail],
    [
      {group, my_group1},
      {group, my_group2},
      {group, my_group3}
    ]},
    {my_group1, [parallel, shuffle], [test1, test1, test1, test1, test1]},
    {my_group2, [parallel, shuffle], [test2, test2, test2, test2, test2]},
    {my_group3, [parallel, shuffle], [test1, test2, test1, test2, test2, test1]}
  ].

ми можемо в ініті зберегти значення до конфігу, та отримати це значення в тестах,
можемо передавати конфіг, записавши щось в нього, наступному тесту в групі тестів,
можемо отримати абсолютний шлях до файла в тестах, щоб далі з цим файлом працювати:

init_per_suite(Config) ->
  {ok, _} = application:ensure_all_started(my_app),
  Value = 1,
  [{key, Value} | Config].


test1(Config) ->
  Value = ?config(key, Config),
  ct:pal("line:~p Value:~p~n", [?LINE, Value]),
  File_Path = proplists:get_value(data_dir, Config) ++ "test.txt",
  ct:pal("line:~p File_Path:~p~n", [?LINE, File_Path]),
  ..
  {save_config, Config}.
  %% OR
  %%{save_config, [{key2, 42} |Config] }.

у прикладі вище test.txt лежить в директорії
test/my_ct_SUITE_data/test.txt
модуль теста називається my_ct_SUITE
при запуску тестів в конфіг автоматично додається параметр data_dir зі шляхом до директорії.

запуск тестів з певної директорії, з певного модуля

$ ct_run -dir ./test -suite x_SUITE y_SUITE
$ ct_run -suite test/setup_SUITE -group installation -case start stop
$ ct_run -suite test/setup_SUITE -case start stop

запуск тестів за допомогою erlang.mk

$ make ct

Посилання

https://www.erlang.org/doc/apps/common_test/basics_chapter.html
https://www.erlang.org/doc/apps/common_test/write_test_chapter.html
https://learnyousomeerlang.com/common-test-for-uncommon-tests
https://eax.me/erlang-testing/
https://www.erlang.org/doc/man/ct.html
https://www.erlang.org/doc/man/ct_run.html
https://erlang.mk/guide/ct.html
https://www.erlang.org/doc/man/ct_suite.html