Hey! Have you ever wondered about tests running inside the IEx shell? For a long time, I was convinced that it’s not really possible. And as it turns out - that’s not really straightforward. You won’t easily find information about that in the documentation.

Table of contents

    But! If you dig deep enough in elixir-lang repository at github, you might find a Mix.Tasks.Test module, which is responsible for the mix test task running.

    Fortunately, there is a very useful function, which we can use for our own purpose:

    def run(args) do

    The arguments it receives are just the same as when you run the mix test causally but written as string values List. e.g

    Mix.Tasks.Test.run(["test/path_to/some_test.exs:666", "--seed", "420"])

    is equivalent to

    $ mix test test/path_to/some_test.exs:666 --seed 420

    Just last one thing that is to remember - if you want to run tests inside IEx, you have to set your MIX_ENV to test for environment.

    $ MIX_ENV=test iex -S mix

    Let's put it together

    $ MIX_ENV=test iex -S mix
    iex(1)> Mix.Tasks.Test.run(["test/path_to/some_test.exs"])
    Finished in 1.0 seconds
    4 tests, 0 failures
    Randomized with seed 69090

    Use case example

    Of course, somebody could ask: Hey, but why would I even do that? I'm pretty sure, that there are lots of use cases. My favorite is to combine it with break!/4.

    Let's check it out:

    $ MIX_ENV=test iex -S mix
    iex(1)> break! SomeModule, :function_used_in_test, 1
    iex(2)> Mix.Tasks.Test.run(["test/path_to/some_test.exs"])
    Request to pry #PID<0.716.0> at SomeModule.function_used_in_test/1 (lib/some_module.ex:309)
    309:   def function_used_in_test(args)
    Allow? [Yn] Y
    pry(1)> args
    ["debugging", "like", "that", "is", "wonderful"]
    pry(2)> continue
    Finished in 1.0 seconds
    4 tests, 0 failures
    Randomized with seed 69090

    That's so cool!

    Oskar Legner
    Oskar Legner Elixir & React Developer

    Read more
    on #curiosum blog