문제

Java에서 코드를 작성할 때 수용하는 것이 매우 도움이됩니다. 구성 그리고 의존성 주입 공동 작업을 조롱하여 순수한 장치 테스트를 가능하고 쉽게 수행 할 수 있도록합니다.

Erlang에서 똑같이하는 것은 덜 간단하고 더러운 코드를 만듭니다.

나는 Erlang을 처음 접했고 Junit, Easymock 및 Java 인터페이스에 중독되어 있기 때문에 그것은 내 잘못 일 것입니다 ...

이 바보 같은 기능이 있다고 가정 해 봅시다.

%% module mymod
handle_announce(Announce) ->
    AnnounceDetails = details_db:fetch_details(Announce),
    AnnounceStats = stats_db:fetch_stats(Announce),
    {AnnounceDetails, AnnounceStats}.

단위 테스트시 mymod, 나는 그것을 증명하고 싶다 details_db 그리고 stats_db 올바른 매개 변수로 호출되며 리턴 값이 올바르게 사용됩니다. 의 능력 details_db 그리고 stats_db 올바른 값을 생성하는 것은 다른 장소에서 테스트됩니다.

문제를 해결하기 위해 내 코드를 이런 식으로 리팩터링 할 수 있습니다.

%% module mymod
handle_announce(Announce, [DetailsDb, StatsDb]) ->
    AnnounceDetails = DetailsDb:fetch_details(Announce),
    AnnounceStats = StatsDb:fetch_stats(Announce),
    {AnnounceDetails, AnnounceStats}.

이런 식으로 테스트하십시오 (기본적으로 통화를 테스트 모듈에 직접 스터브합니다) :

%% module mymod_test
handle_announce_test() ->
    R = mymod:handle_announce({announce, a_value}, [?MODULE, ?MODULE, ?MODULE]),
    ?assertEqual({details,stats}, R).

fetch_details({announce, a_value}) ->
    details.

fetch_stats({announce, a_value}) ->
    stats.

작동하지만 응용 프로그램 코드가 더러워지고 항상 그 추악한 모듈 목록을 가지고 다니야합니다.

나는 두 개의 모의 라이브러리를 시도했다 (Erlymock 그리고 (이것은 다른 하나입니다)하지만 나는 만족하지 않았다.

Erlang 코드를 어떻게 테스트합니까?

감사!

도움이 되었습니까?

해결책

여기서 고려해야 할 두 가지가 있습니다 ...

모든 코드를 두 가지 유형의 두 가지 유형으로 분리해야합니다. 모듈:

  • 순수한 기능 모듈 (일명 부작용 자유 모듈)
  • 부작용이있는 모듈

(이에 대해 읽고 가장 일반적인 부작용 인 차이점과 샘플 코드에있는 차이점이 데이터베이스에 쓰는 것임을 이해해야합니다).

순수한 기능인 모듈은 테스트하기 위해 사소합니다. 내보내는 각 함수 (정의 별)는 동일한 값을 넣을 때 항상 동일한 값을 반환합니다. Eunit/Assert Richard Carlsson과 Mickael Remond가 쓴 프레임 워크. Bish-Bash-Bosh, Job 's a good'un ...

핵심은 코드의 약 90%가 순수한 기능 모듈에 있어야한다는 것입니다. 문제를 극적으로 축소시킵니다. (당신은 이것이 당신의 문제를 '해결'하는 것이 아니라 단지 '그것을 줄이는'것일 뿐이라고 생각할 수도 있습니다. 그리고 당신은 대부분 옳을 것입니다 ...)

이 분리를 달성 한 후에는 부작용으로 모듈을 단위 테스트하는 가장 좋은 방법입니다. 표준 테스트 프레임 워크.

우리가하는 방식은 Mock -Objects를 사용하는 것이 아니라 Init_per_Suite 또는 Init_per_test 함수에 데이터베이스를로드 한 다음 모듈을 직접 실행하는 것입니다.

가장 좋은 방법은 단위 테스트가 유지하기 어려운 고통이기 때문에 가능한 빨리 시스템 테스트로 바로 이동하는 것입니다. 따라서 시스템 테스트 왕복으로 이동하기에 충분한 단위 테스트가 더 이상 (더 나은 삭제를 더 잘 삭제하지 않습니다. DB 단위는 가능한 빨리 테스트합니다).

다른 팁

나는 Guthrie가 말하는 것을 두 번째합니다. 당신은 당신의 논리를 얼마나 순수한 기능으로 끌어낼 수 있는지에 놀랄 것입니다.

최근에 새로운 매개 변수화 된 모듈로 묶는 것 중 하나는 종속성 주입에 매개 변수화 된 모듈을 사용하는 것입니다. 매개 변수 목록 및 프로세스 사전의 문제를 피합니다. 최근 버전의 Erlang을 사용할 수 있다면 적합 할 수 있습니다.

Gordon은 주요 목표는 작은 부작용 자유 함수를 테스트하는 것입니다.

그러나 ... 음, 통합을 테스트 할 수 있으므로 어떻게 할 수 있는지 보여줍니다.

주입

매개 변수화 된 종속성을 전달할 목록을 피하십시오. 레코드, 프로세스 사전, 매개 변수화 된 모듈을 사용하십시오. 코드는 덜 못 생겼습니다.

이음새

의존성 이음새로 가변 모듈에 초점을 맞추지 말고 프로세스가 이음새가되도록하십시오. 등록 된 프로세스 이름을 하드 코딩하는 것은 종속성을 주입 할 수있는 기회가 손실됩니다.

나는 단지 질문에 직접 묻는 질문에 대답하고 있으며 저자가 이것을 전혀 해야하는지 판단하려고하지 않습니다.

사용 메이크 다음과 같이 예제에 대한 단위 테스트를 작성할 수 있습니다.

handle_announce_test() ->
    %% Given
    meck:new([details_db, stats_db]),
    meck:expect(details_db, fetch_details, ["Announce"], "AnnounceDetails"),
    meck:expect(stats_db, fetch_stats, ["Announce"], "AnnounceStats"),
    %% When
    Result = handle_announce("Announce"),
    %% Then
    ?assertMatch({"AnnounceDetails", "AnnounceStats"}, Result),
    %% Cleanup
    meck:unload().

나는 문자열을 사용하여 실제로 전달되는 것이 아니라 가짜 가치라는 점을 강조합니다. 구문 하이라이트 덕분에 테스트 코드에서 쉽게 찾을 수 있습니다.

솔직히 말해서 나는 전직 자바 개발자입니다. 모키토 최근에 Erlang으로 전환했으며 현재 위에서 언급 한 프로젝트에 기여했습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top