Mix test startup is slow

I have a rather small Phoenix project and lately I noticed that running mix test became slow. On other tiny projects, tests run about 1 second after executing mix test. Now they only start rolling after about 5 seconds. Sadly I cannot find a way to debug or find out what is causing the delay. I know about the --slow flag, but the tests themselves are not slow. It is the startup time that is bothering me.

Any idea how I should investigate this further? I am on Elixir 1.7.4. I already removed all test files, so after a good 6 seconds the output is ‘There are no tests to run’.

Thank you!

Which OS?

This week someone on Twitter was reporting similar issues on OSX and upgrading and restarting the OS fixed it: https://twitter.com/GermanDZ/status/1063017477926518785

Did not see that tweet. I am on OSX indeed, not the latest version, I am on 10.13.6. I just did a security update and rebooted, but the problem remains, even for a single test. I tried the time command I saw in the Twitter conversation, with an empty tests folder (apart from the test_helper.exs file), and got:

$ time MIX_ENV=test mix run
MIX_ENV=test mix run  1.99s user 0.63s system 40% cpu 6.411 total
$ ls test
test_helper.exs

@josevalim I found the possible culprit. We use quantum to have cron-like scheduling in the app. By using the time command on the dev env I noticed similar startup times of around 5~6 seconds. The setup of quantum uses a genserver as a worker in the main Application file, and I noticed some issues on the board over there regarding timeouts. Removing the worker there brings the test startup down to <1 second!

I will head over to the issue board over there and for now only add the worker to the supervisor when not in test. For the actual application the timeout is not too bad, we only need to start that once.

5 Likes

Hi Jeroen,

I am having the same problem but the workaround of only starting the Quantum scheduler worker in :prod or :dev environments doesn’t fully solve the issue for me as Quantum still starts Swam (which is slow to start). Do you have the same issue or is your workaround better than mine?

Thanks
Zander

It me https://github.com/zanderxyz/veil/issues/17 :wink:

Over here I do not see the swarm starting in test… Was your check sufficient? Care to share?

Sure, here’s my main application file:

defmodule Veil do
  use Application

  def start(_type, _args) do
    import Supervisor.Spec, warn: false
    import Cachex.Spec

    children = []
    opts = [strategy: :one_for_one, name: Veil.Supervisor]
    Supervisor.start_link(add_scheduler(children), opts)
  end

  defp add_scheduler(children) do
    import Supervisor.Spec, only: [worker: 2]

    if Application.get_env(:veil, :environment) != :test do
      [worker(Veil.Scheduler, []) | children]
    else
      children
    end
  end
end

It’s definitely quicker than without this step but I still get some slowdown on mix test, and I see this in the terminal:

14:35:44.251 [info]  [swarm on nonode@nohost] [tracker:init] started

Thanks

Having the same issue as OP, except I’m not using Quantum. I’ve run :fprof as described here, but not getting much:

Looks like a lot of time spent waiting and starting genservers? Would appreciate any guidance on profiling this further, it’s seriously affecting my change->test dev loop.

I’m on Mac OS 12.0.1, elixir 1.11.4, erlang 23.3.

PS: there was a warning about reviving this topic, but no guidance as to whether that’s acceptable or not. I’m pretty sure the topic applies, so just went ahead with it.