Что лучшим способом является к модульному тесту параллельный код Erlang?

Основываясь на том, что я искал, я думаю, что это лучшие ответы, которые я обнаружил Android 6.0 несколько разрешений

17
задан madlep 20 December 2008 в 12:27
поделиться

5 ответов

Вопрос немного неопределенен ("Erlang, параллельно, протестируйте его с Erlang!"), но я попытаюсь уточнить немного.

Тестирование код Erlang может расположиться от прямо простой (правильный вход производит правильный вывод) к установке сложных тестовых обвязок, которые проверяют, что Ваш компонент ведет себя способ, которым это должно. То, что является лучшим для Вашей данной ситуации, зависит полностью от требований, которые Вы имеете и сумма черного квадрата / тестирование методом "белого ящика", которое Вы хотите сделать.

Часть красоты Erlang является способностью сделать параллелизм прозрачным. Рассмотрите следующий пример (функция, которая параллелизирует суммирование списка списков):

deep_sum(ListOfLists) ->
     Parent = self(),
     [spawn(fun() -> Parent ! lists:sum(List) end) || List <- ListOfLists],
     lists:sum([receive Sum -> Sum end || _ <- ListOfLists]).

Вы обычно тестировали бы это с очень простым тестовым сценарием EUnit:

deep_sum_test() ->
     ?assertEqual(0,  deep_sum([0,  0,  0,  0])),
     ?assertEqual(40, deep_sum([10, 10, 10, 10]).

Теперь, скажем, у нас есть немного более явный API к этой функциональности: пул процесса как аргумент:

deep_sum(Pool, ListOfLists) ->
     distribute_lists(Pool, ListOfLists),
     lists:sum([receive Sum -> Sum end || _ <- ListOfLists]).

distribute_lists(Pool, ListOfLists) -> distribute_lists(Pool, Pool, ListOfLists).

distribute_lists([P|Pool], All, [L|ListOfLists]) ->
     P ! {self(), L},
     distribute_lists(Pool, All, ListOfLists);
distribute_lists([], All, ListOfLists) ->
     distribute_lists(All, All, ListOfLists);
distribute_lists(_Pool, _All, []) ->
     ok.

При тестировании этого, мы должны иметь дело с фальсифицированием этого пула процесса:

deep_sum_test() ->
     Pool = [spawn_link(fun() -> fake_pool(1) end) || _ <- lists:seq(1, 3)],
     ?assertEqual(4, deep_sum(Pool, [lists:seq(1, 3) || _ <- list:seq(1, 4)]),
     ?assertEqual(7, deep_sum(Pool, [lists:seq(1, 3) || _ <- list:seq(1, 7)]),
     [P ! stop || P <- Pool].

fake_pool(CannedResponse) ->
     receive
         {From, _L} -> From ! CannedResponse;
         stop -> ok
     end,
     fake_pool(CannedResponse).

, Как Вы видите, тестируя программы параллелизма в Erlang, может принять различные формы. Это чрезвычайно простые примеры, но с Erlang создал в примитивах параллелизма, очень легко создать вид тестовой обвязки, которую Вы хотите, абстрагируя на правильных уровнях.

я обычно нахожу, что TDD является ортогональным к тому, тестируете ли Вы параллельный код или нет, таким образом, сказал, что тестирование методов может использоваться для нормального поблочного тестирования также.

5
ответ дан 30 November 2019 в 14:12
поделиться

Одним инструментом, который я знаю, которых можно использовать для тестирования программ Erlang согласно параллельным сценариям, является QuickCheck: http://www.quviq.com/

можно определить ожидаемые свойства использования поведения, и инструмент может осуществить программу Erlang по диапазону исходных данных и время, чтобы гарантировать, что свойства удовлетворены.

, К сожалению, это - коммерческий инструмент

, Также взглянули на проект ProTest: http://www.protest-project.eu

Обновление: проект ProTest выпустил обзор, "Результаты для: инструменты тестирования Erlang рассматривают для проекта ProTest"

2
ответ дан 30 November 2019 в 14:12
поделиться

Поскольку ошибки в параллельном коде проявляются в зависимости от порядка, различные части выполняются, я думаю, что лучше не полагаться на тестирование для раскрытия ошибок в параллельной части кода. Такие ошибки очень легко подсунуть через и чрезвычайно трудный расположиться. Посмотрите, например, как запирающая на два поворота техника, которая широко цитировалась и использовалась в качестве эффективного метода для реализации ленивой инициализации в многопоточной среде, , как позже находили, была повреждена . Намного лучше использовать соответствующие абстракции и методы для создания параллельных частей кода корректными "дизайном".

1
ответ дан 30 November 2019 в 14:12
поделиться

Добавляя к тому, что заявил Diomidis, единственный реальный способ завоевать некоторое доверие с Вашим параллельным кодом состоит в том, чтобы запустить расширенные тесты при постоянно переменных условиях; и даже тогда, это - только доказательство, что это не перестало работать при тех условиях .

0
ответ дан 30 November 2019 в 14:12
поделиться

Вы могли изолировать часть, которую требуется протестировать с насмешками при помощи этого: http://github.com/charpi/erl_mock/tree/master

у меня нет опыта с erl_mock все же.

-1
ответ дан 30 November 2019 в 14:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: