How do I run a ExUnit unit test inside iex?

1,622 views
Skip to first unread message

mattias w

unread,
Mar 15, 2016, 3:49:38 PM3/15/16
to elixir-lang-talk
Is "mix test" the only way to run the unit tests?

I would like to run them inside the iex, how do I do that? For example, in Clojure, the unit tests are also functions with 0 args.

After loading the testfile into iex, I see there are functions there, but they all want arguments.




Onorio Catenacci

unread,
Mar 15, 2016, 4:02:39 PM3/15/16
to Elixir Lang Talk
Is 

iex -S mix test 

not a workable option for you or am I misunderstanding your question?

--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/04d1c40b-6cf9-4c52-8492-6a6170474df8%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--

Mattias

unread,
Mar 15, 2016, 6:00:31 PM3/15/16
to elixir-l...@googlegroups.com
"iex -S mix test" runs the tests the first time, fine.

So, now while I am still inside iex, how do I rerun one or more of them again? Most likely, I edited and reloaded one code file.

/mattias





--
You received this message because you are subscribed to a topic in the Google Groups "elixir-lang-talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elixir-lang-talk/bANRPVHKJm4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elixir-lang-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/CAP%3DvNq9mp9274GqQuFmV9fMYo369AZJZLM4wzz11qKzU8%3DjgXQ%40mail.gmail.com.

Onorio Catenacci

unread,
Mar 15, 2016, 6:04:43 PM3/15/16
to Elixir Lang Talk
Ok so I partially misunderstood your question.  I'm sure Jose or Eric or one of the folks who's a lot deeper on ExUnit than I am will chime in.

--
Onorio


For more options, visit https://groups.google.com/d/optout.

Ben Wilson

unread,
Mar 15, 2016, 6:15:29 PM3/15/16
to elixir-lang-talk
What are you using the iex part for? You can have mix test run just a particular test file, such that your iteration process is just edit the file, run mix test again.

Josh Adams

unread,
Mar 15, 2016, 6:29:03 PM3/15/16
to elixir-l...@googlegroups.com
My preferred routine for this involves vim-test: https://github.com/janko-m/vim-test

With that, I can just put my cursor on the test I wish to execute and type `,t` (with the mappings outlined here https://github.com/knewter/dotfiles/blob/79bd778681a5e17e406885c77ca3e6709bc6169b/vim/vimrc#L100)

Then if I'm on a non-test file and hit `,t`, it will just re-execute the most recently run test.

It's a pretty great pattern, if you get used to it.  Just my $0.02

On Tue, Mar 15, 2016 at 5:15 PM, Ben Wilson <benwil...@gmail.com> wrote:
What are you using the iex part for? You can have mix test run just a particular test file, such that your iteration process is just edit the file, run mix test again.
--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Josh Adams

Mattias

unread,
Mar 16, 2016, 2:51:10 AM3/16/16
to elixir-l...@googlegroups.com
The beauty of Erlang, and a number of other programming languages with a REPL like Clojure and Ocaml, is that you can develop inside your real application.

In Erlang, I typically build a release with symlinks to the source files (i.e. relx -d), start everything, incl the web server, and develop. I can then connect to the server from the outside, for example a browser, and test the current status.

If I now need to add functionality, I just edit the source files, press Save, and the new code is loaded automatically into the run-time.

I can click on a button on the already logged in web client to verify. If it doesn't work, or if the functionality maybe was a bit more complicated than I expected, I create a number of unit tests until it works.

I run the unit tests within my already running system, and after some tweaking of the code, it works. During this, I can also test directly from the clients, no login or anything, all state is still untouched.

I am trying to understand how to use the tooling for Elixir to work like this.

For me, using "mix test" after each source edit is almost an anti-pattern. Yes, you have to do like that in traditional programming languages, but not if you have the Erlang runtime. "mix test" is perfect for CI.

/mattias

--
You received this message because you are subscribed to a topic in the Google Groups "elixir-lang-talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elixir-lang-talk/bANRPVHKJm4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elixir-lang-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/CAA1-O0ygjKFy_bYOVin2_UMj4J7%3DpxYeP6%3DkmGZh9aKugGgKQA%40mail.gmail.com.

Alex Shneyderman

unread,
Mar 17, 2016, 5:45:52 PM3/17/16
to elixir-lang-talk
There are a few problems to work around here - that makes an option of working with mix.ex_unit combo the way you would like to work with it very unattractive. 

0. You have to run in test env so MIX_ENV=test iex -S mix is your startup command.

1. Mix keeps track of the executed tests forever (until VM dies or you do a manual clear of that state). So starting iex -S mix and executing Mix.Task.run "test' will work the first time around but will assume the "test" task already ran on the second invocation. To clear that state you can do Mix.TasksServer.clear.

2. ExUnit also has state that is assumed to be initialized once (with all the test suites to run) and gets emptied out as you run the tests. Unfortunately, that initialization happens at compile time of the test see ExUnit.Case source

  @doc false
  defmacro __before_compile__(_) do
    quote do
      if @ex_unit_async do
        ExUnit.Server.add_async_case(__MODULE__)
      else
        ExUnit.Server.add_sync_case(__MODULE__)
      end

      def __ex_unit__(:case) do
        %ExUnit.TestCase{name: __MODULE__, tests: @ex_unit_tests}
      end
    end
  end

This pretty much assumes you have to recompile test code to be included for a run or add the module on your own. So if you simply re-run the test nothing is tested. You have to do :code.delete(MyTest) and then run Kernel.ParallelCompiler.files(["test/my_test.exs"]). If all you need is to re-run your test, you can do so with ExUnit.Server.add_sync_case(MyTest) and then do Mix.Task.run "test" (given you cleared Mix.TasksServer)

So this is what did work in my simple elixir projects:

17:38:19 alex@alexmac iextestrun > MIX_ENV=test iex -S mix
Erlang/OTP 18 [erts-7.2.1] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false]

Interactive Elixir (1.2.3) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Mix.Task.run "test"
tests
.

Finished in 0.06 seconds (0.06s on load, 0.00s on tests)
1 test, 0 failures

Randomized with seed 855115
[#Function<2.98623896/1 in Mix.Tasks.Test.run/1>]
iex(2)> Mix.TasksServer.clear
:ok
iex(3)> ExUnit.Server.add_sync_case(MyTest)
:ok
iex(4)> Mix.Task.run "test"
tests
.

Finished in 0.00 seconds
1 test, 0 failures

Randomized with seed 542355
[#Function<2.98623896/1 in Mix.Tasks.Test.run/1>,
 #Function<2.98623896/1 in Mix.Tasks.Test.run/1>]

At the danger of all this information being utterly useless, the simplest thing to do with ex unit tests is to stop and restart your VM :-)

Cheers,
Alex.

Onorio Catenacci

unread,
Mar 18, 2016, 7:45:05 AM3/18/16
to Elixir Lang Talk
>>  For me, using "mix test" after each source edit is almost an anti-pattern. Yes, you have to do like that in traditional       >>  programming languages, but not if you have the Erlang runtime. "mix test" is perfect for CI.

It may strike you as an anti-pattern Mattias but that is the process we're supposed to use to develop software.  The idea is that it's much easier to catch mistakes when we only have one change to check versus having multiple changes to our code base.

I can certainly see an argument against running tests after every source change but I don't think the arguments either way are so persuasive that I'd want to change things. 

As I get more and more familiar with the notion of good unit tests, they strike me as being in one way analogous to version control.  Once upon a time I was asked to work in a shop that didn't have VC--their idea of VC was backup disks.  One time and never again.  I feel the same way about unit tests.  They're not a luxury--they're a necessity.

--
Onorio



For more options, visit https://groups.google.com/d/optout.



--

Mattias

unread,
Mar 18, 2016, 9:48:45 AM3/18/16
to elixir-l...@googlegroups.com
In Erlang edts Emacs mode, the unit tests are run in the background when saving, you do not even have to do anything. The unit tests failures are seens as red markers directly.

Early feedback is always better than later, so this is a better process.

The reason this current processis so common is just that it is the only option in most languages.

/mattias

Onorio Catenacci

unread,
Mar 18, 2016, 9:57:22 AM3/18/16
to Elixir Lang Talk
So maybe you could help Samuel Tonini in adding that feature to Alchemist?  I can certainly see the utility of a feature like that.

--
Onorio


--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Mattias

unread,
Mar 20, 2016, 7:23:31 AM3/20/16
to elixir-l...@googlegroups.com
Yes, I agree, helping Samuel Tonini would be a good idea. Remember, I am new to Elixir, so to me it is not still obvious what the tools support. 

However, it seems strange to me that ExUnit doesn't create plain functions that can be called. For example, Clojure does it that way too.

--
You received this message because you are subscribed to a topic in the Google Groups "elixir-lang-talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elixir-lang-talk/bANRPVHKJm4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elixir-lang-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/CAP%3DvNq-bu6v4yLunkpXGwyv5rsc2BQAmKvPJFydy-e8qWGD09g%40mail.gmail.com.

Louis Pilfold

unread,
Mar 20, 2016, 9:38:54 AM3/20/16
to elixir-lang-talk
Hi all

If you'd like to run your tests each time a file is saved you may like
this little mix task that does so:
https://github.com/lpil/mix-test.watch

Cheers,
Louis
> https://groups.google.com/d/msgid/elixir-lang-talk/CAKewT_NyTyQa-9ghzHBs8Lt3eg%2B-7hyUUrq46HGrMcvZfMM9Dw%40mail.gmail.com.
Reply all
Reply to author
Forward
0 new messages