Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The question is a bit vague ("Erlang is concurrent, test it with Erlang!") but I'll try to elaborate a bit.</p> <p>Testing Erlang code can range from the straightforwardly simple (the right input produces the right output) to setting up complex test harnesses that verify your component behaves the way it should. What is best for your given situation depends totally on the requirements you have and the amount of black box / white box testing you want to do.</p> <p>Part of the beauty of Erlang is the ability to make concurrency transparent. Consider the following example (a function that parallelizes the summation of a list of lists):</p> <pre><code>deep_sum(ListOfLists) -&gt; Parent = self(), [spawn(fun() -&gt; Parent ! lists:sum(List) end) || List &lt;- ListOfLists], lists:sum([receive Sum -&gt; Sum end || _ &lt;- ListOfLists]). </code></pre> <p>You would typically test this with a very simple EUnit test case:</p> <pre><code>deep_sum_test() -&gt; ?assertEqual(0, deep_sum([0, 0, 0, 0])), ?assertEqual(40, deep_sum([10, 10, 10, 10]). </code></pre> <p>Now, let's say we have a bit more explicit API to this functionality: a process pool as argument:</p> <pre><code>deep_sum(Pool, ListOfLists) -&gt; distribute_lists(Pool, ListOfLists), lists:sum([receive Sum -&gt; Sum end || _ &lt;- ListOfLists]). distribute_lists(Pool, ListOfLists) -&gt; distribute_lists(Pool, Pool, ListOfLists). distribute_lists([P|Pool], All, [L|ListOfLists]) -&gt; P ! {self(), L}, distribute_lists(Pool, All, ListOfLists); distribute_lists([], All, ListOfLists) -&gt; distribute_lists(All, All, ListOfLists); distribute_lists(_Pool, _All, []) -&gt; ok. </code></pre> <p>When testing this, we have to deal with faking this process pool:</p> <pre><code>deep_sum_test() -&gt; Pool = [spawn_link(fun() -&gt; fake_pool(1) end) || _ &lt;- lists:seq(1, 3)], ?assertEqual(4, deep_sum(Pool, [lists:seq(1, 3) || _ &lt;- list:seq(1, 4)]), ?assertEqual(7, deep_sum(Pool, [lists:seq(1, 3) || _ &lt;- list:seq(1, 7)]), [P ! stop || P &lt;- Pool]. fake_pool(CannedResponse) -&gt; receive {From, _L} -&gt; From ! CannedResponse; stop -&gt; ok end, fake_pool(CannedResponse). </code></pre> <p>As you can see, testing concurrency programs in Erlang can take different shapes. These are extremely simple examples, but with Erlang's built in concurrency primitives it is very easy to create the kind of test harness you want, abstracting at the right levels.</p> <p>I usually find TDD to be orthogonal to wether you're testing concurrent code or not, so said testing techniques can be used for normal unit testing as well.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload