Erlang: Убегая lists:foreach из “цикла”

Какова цель протестировать?

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

Лично, мое основное использование для тестов кода должно гарантировать, чтобы будущие изменения кода не вызывали проблемы и помочь моим усилиям по отладке, если они делают. Я нахожу что, тестируя закрытые методы так же полностью как открытый интерфейс (если не больше!) furthers та цель.

Рассмотрите: у Вас есть открытый метод A, который называет закрытый метод B. A и B, оба используют метод C. C изменяется (возможно, Вами, возможно, поставщиком), заставляя начинать проваливать его тесты. Не было бы полезно иметь тесты для B также, даже при том, что это является частным, так, чтобы Вы знали, находится ли проблема в употреблении A C, использовании B C или обоих?

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

5
задан ErJab 30 November 2009 в 14:47
поделиться

3 ответа

traverse(Liste) ->
 traverse(Liste, []).

traverse([], Acc) ->
 Acc;    

traverse([1|_], Acc) ->
 Acc;

traverse([H|T], Acc) ->
 % do something useful here maybe?
 traverse(T, Acc).

Конечно, это очень примерный пример.

7
ответ дан 18 December 2019 в 07:54
поделиться

Другой способ сделать это - использовать throw и catch :

catch lists:foreach(
        fun(1) ->
                throw(found_one);
           (X) ->
                io:format("~p~n", [X])
        end,
        [2, 4, 5, 1, 2, 5]).

При запуске в оболочке это выводит:

2
4
5
found_one

EDIT : По многочисленным просьбам, более точная версия, улавливающая только то, что вы хотите поймать:

try lists:foreach(
        fun(1) ->
                throw(found_one);
           (X) ->
                io:format("~p~n", [X])
        end,
        [2, 4, 5, 1, 2, 5])
catch
    throw:found_one ->
        found_one
end.
8
ответ дан 18 December 2019 в 07:54
поделиться

В модуле lists есть много хороших функций:

lists:foreach(fun(E) -> do_something(E) end,
    lists:takewhile(fun(E) -> E =/= 1 end, List)).

или более эффективные, но менее красивые

lists:takewhile(fun(1) -> false;
                   (E) -> do_something(E), true
                end, List)
3
ответ дан 18 December 2019 в 07:54
поделиться
Другие вопросы по тегам:

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