このあいだ 1.9 がリリースされたと思っていたのに、もう 1.10 がリリースされました。
1.9 では、Elixir 単体でリリースを構築できるようになったり、config を一新したりと大きな変化がありましたが、それとくらべると今回あまり派手さを感じません。
それは Elixir が成熟期にさしかかっているということなのかもしれません。
そんな中でありがたい改善がありました。
リリースノートにも「小さいながら重要な改善」と書かれている ExUnit の改善です。
Other enhancements
ExUnit, our test framework, ships two small but important improvements:
ExUnit.CaptureIO
can now be used by tests that run concurrently and we have added “pattern-matching diffing”. To understand the last feature, take this code:
elixir assert %{"status" => 200, "body" => %{"key" => "foo"}} = json_payload
Now imagine that
json_payload
is a large JSON blob and the"key"
inside the"body"
did not have value of"foo"
.
一見それほど重要な改善には感じないのですが、データベースの操作をテストするときにとても役に立ちました。
データベースの操作のばあい、たとえば insert_at
や updted_at
の値は直接はコントロールできません。
このため完全一致を評価する Kernel.==/2
を使うことはできず Kernel.SpecialForms.=/2
のパタンマッチングを利用することになります。
{:ok, user} = Accounts.create_user(%{username: "fizz buzz"}) assert %User{username: "Fizz Buzz"} = Accounts.get_user!(user.id)
1.9 まではマッチングに失敗すると、下記のようにマッチしなかった右辺の値が出力されるだけでした。
match (=) failed code: assert %User{username: "Fizz Buss"} = Accounts.get_user!(user.id()) right: %MyApp.Accounts.User{__meta__: #Ecto.Schema.Metadata<:loaded, "users">, id: 104, inserted_at: ~N[2020-01-29 11:47:37], updated_at: ~N[2020-01-29 11:47:37], username: "fizz buzz"} stacktrace: test/my_app/accounts_test.exs:30: (test)
これが 1.10 の改善によって左右のマッチしなかった要素が出力されるようになりました。
match (=) failed code: assert %User{username: "Fizz Buzz"} = Accounts.get_user!(user.id) left: %MyApp.Accounts.User{username: "Foo Bar"} right: %MyApp.Accounts.User{username: "fizz buzz", __meta__: #Ecto.Schema.Metadata<:loaded, "users">, id: 85, inserted_at: ~N[2020-01-29 11:19:39], updated_at: ~N[2020-01-29 11:19:39]} stacktrace: test/my_app/accounts_test.exs:30: (test)
しかもその部分がハイライトされます。
これまではパタンマッチングでの評価は他の方法が使えないときの苦肉の策のような雰囲気を感じていたのですが、これで心置きなく(?)利用していくことができそうです。