mmag

ハマったことメモなど

mix test に --stale オプションが追加された

昨日は途中で寝ながらエントリを書きました。

さて、このプルリクで入った機能について書きます。

github.com

mix test--staleというオプションが追加されたよ、というものです。

--stale

--staleオプションを付けると、前回のテスト以降に変更されたコードが影響するテストだけが走ります。

例えば`UserControllerモジュールの中でUserモジュールを使っていて、両方単体テストが書いてあるとします。

1回mix testで全部テストをしてGreenにした後、Userに変更を加えてmix test --staleすると、Userの変更が影響するテストが走ります。つまりUserControllerUserのテストが両方走ります。

一方、今度はUserControllerを変更したとします。ここでmix test --staleしても、Userモジュールのテストは走りません。UserControllerの動作が変わったというだけで、User単体テストに影響は無いためです。

仕組み

詳細な仕組みはコードを読んでもらうとして、簡単に説明すると、mix testを行うと、各テストファイルとそれが使っているモジュールの対応がmanifestファイルが出力されるようになりました。パスは"_build/test/lib/#{app_name}/.compile.test_stale"です。 お手元のmixプロジェクトをテストして、iexで

"_build/test/lib/your_app/.compile.test_stale" |> File.read!() |> :erlang.binary_to_term()

とすると、それが読めるはずです。適当に手元で試したもののmanifestを晒しておくと、こんな感じでした。

Erlang/OTP 18 [erts-7.1] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]

Interactive Elixir (1.3.0-dev) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> "_build/test/lib/my_app/.compile.test_stale" |> File.read!() |> :erlang.binary_to_term()
[:v1,
 {:source, "test/my_app_test.exs",
  [:erlang, :elixir_module, :elixir_def, String.Chars, Path, MyAppTest, MyApp,
   Module, Kernel, ExUnit.TestCase, ExUnit.DocTest, ExUnit.Case,
   ExUnit.Callbacks, ExUnit.Assertions, Enum, Access], [], []},
 {:source, "test/hello_test.exs",
  [:erlang, :elixir_module, :elixir_def, String.Chars, MyApp.HelloTest, Module,
   Kernel, ExUnit.TestCase, ExUnit.DocTest, ExUnit.Case, ExUnit.Callbacks,
   ExUnit.Assertions, Enum, Access], [MyApp.Hello], []},
 {:source, "test/greeting_test.exs",
  [:erlang, :elixir_module, :elixir_def, String.Chars, MyApp.GreetingTest,
   Module, Kernel, ExUnit.TestCase, ExUnit.DocTest, ExUnit.Case,
   ExUnit.Callbacks, ExUnit.Assertions, Enum, Access], [MyApp.Greeting], []}]

テーマはFB matteをベースにしてます。作者さんに感謝を込めて。