title: What is the idiomatic testing strategy for GenServers in Elixir?
body: <p>I am writing a module to query an online weather API. I decided to implement it as an Application with a supervised <code>GenServer</code>.</p>
  
  <p>Here is the code:</p>
  
  <pre><code>defmodule Weather do
    use GenServer
  
    def start_link() do
      GenServer.start_link(__MODULE__, :ok, name: __MODULE__)
    end
  
    def weather_in(city, country) do
      GenServer.call(__MODULE__, {:weather_in, city, country_code})
    end
  
    def handle_call({:weather_in, city, country}) do
      # response = call remote api
      {:reply, response, nil}
    end
  end
  </code></pre>
  
  <p>In my test I decided to use a <code>setup</code> callback to start the server:</p>
  
  <pre><code>defmodule WeatherTest do
    use ExUnit.Case
  
    setup do
      {:ok, genserver_pid} = Weather.start_link
      {:ok, process: genserver_pid}
    end
  
    test "something" do
      # assert something using Weather.weather_in
    end
  
    test "something else" do
      # assert something else using Weather.weather_in
    end
  end
  </code></pre>
  
  <p>I decided to register the <code>GenServer</code> with a specific name for several reasons:</p>
  
  <ul>
  <li><p>it is unlikely that someone would need multiple instances</p></li>
  <li><p>I can define a public API in my <code>Weather</code> module that abstracts the existence of an underlying <code>GenServer</code>. Users won't have to provide a PID/Name to the <code>weather_in</code> function to communicate with the underlying <code>GenServer</code></p></li>
  <li><p>I can place my <code>GenServer</code> under a supervision tree</p></li>
  </ul>
  
  <p>When I run the tests, as they run concurrently, the <code>setup</code> callback is executed once per test. Therefore there are concurrent attempts to start my server and it fails with <code>{:error, {:already_started, #PID&lt;0.133.0&gt;}}</code>.</p>
  
  <p>I asked on Slack if there is anything I can do about it. Perhaps there is an idiomatic solution that I am not aware of...</p>
  
  <p>To summarise the solutions discussed, when implementing and testing a <code>GenServer</code>, I have the following options:</p>
  
  <ol>
  <li><p>Not registering the server with a specific name to let each test start its own instance of the GenServer.
  Users of the server can start it manually but they must provide it to the public API of the module. The server can also be placed in a supervision tree, even with a name but the public API of the module will still need to know which PID to talk to. Given a name passed as a parameter, I guess they could find the associated PID (I suppose OTP can do that.)</p></li>
  <li><p>Registering the server with a specific name (like I did in my samples). Now there can be only one GenServer instance, tests must run sequentially (<code>async: false</code>) and each test must start <strong>and</strong> terminate the server.</p></li>
  <li><p>Registering the server with a specific name. Tests can run concurrently if they all run against the same unique server instance (Using <code>setup_all</code>, an instance can be started only once for the whole test case). Yet, imho this is a wrong approach to testing as all tests will run against the same server, changing its state and therefore messing with each other.</p></li>
  </ol>
  
  <p>Considering the users may not need to create several instances of this GenServer, I'm tempted to trade the tests concurrency for simplicity and go with solution 2.</p>
  
  <p>[Edit]
  Trying solution 2 but it still fails for the same reason <code>:already_started</code>. I read again the docs about <code>async: false</code> and found out that it prevents the <strong>test case</strong> from running in parallel with other test cases. It doesn't run the tests of my test case in sequence as I thought.
  Help!</p>