Power Assert とは
失敗結果の表現力が向上した assert
とでも言えばよいでしょうか。
例えばこんな感じの ExUnit
によるテスト失敗結果が、
1) test Enum.at should return the element at the given index (PowerAssertSampleTest)
test/power_assert_sample_test.exs:5
Assertion with == failed
code: array |> Enum.at(index) == two
lhs: 3
rhs: 2
stacktrace:
test/power_assert_sample_test.exs:7
こんな感じに表示されるようになります。
1) test Enum.at should return the element at the given index (PowerAssertSampleTest)
test/power_assert_sample_test.exs:5
array |> Enum.at(index) == two
| | | |
| 3 2 2
[1, 2, 3, 4, 5, 6]
stacktrace:
test/power_assert_sample_test.exs:7
ぱっと違いが分かりにくいのですが、diff にすると差分が分かりやすいです。
- Assertion with == failed
- code: array |> Enum.at(index) == two
- lhs: 3
- rhs: 2
+ array |> Enum.at(index) == two
+ | | | |
+ | 3 2 2
+ [1, 2, 3, 4, 5, 6]
このような形で途中式の計算結果も合わせて表示してくれる機能です。
通常の assert
は単に失敗していますと表示されるだけですが1、Power Assert はそこに至るまでの経緯が表示されるためテスト結果の間違いを探しやすく、理解の助けになってくれます。
個人的には新しい言語を学ぶときに Power Assert があると言語の習得が早くなるだろうなと考えています。新しい言語を学ぶときには、何でこのコードで動かないのか?という問題に当たることも多く、その際に test を書いて途中経過を知ることができたらきっと理解しやすくなると思われるためです。
Power Assert 自体をもっと詳しく知りたい方は以下の資料を参照してみてください。JavaScript 版 power-assert 作者の t_wada さんによる資料です。
Elixir での Power Assert とは
Power Assert の Elixir 版実装が PowerAssertEx です(以下 Elixir 版について触れるときは PowerAssertEx と記載します)。
Elixir の標準テストフレームワークである ExUnit
をベースとしており、標準の assert
マクロを置き換えることで Power Assert 機能を提供します。
ポリシーとしていつでも元の assert
に戻せるようにすることを目指しています。これは JavaScript 版 power-assert がそういったポリシーを持っており、それが cool だと思ったので真似しています。いつでも戻せるということは採用もしやすいですよね。
使い方
前提条件
Elixir 標準テストフレームワークの ExUnit
に依存しています。ExUnit
を用いたテストであれば、容易に採用することができます。特にテストフレームワークを変えずに使っていれば ExUnit
を使っていると思うので大抵の場合は使えると思います。
インストール
プロジェクトの mix.exs
ファイルに以下を追加して、mix deps.get
コマンドを実行するだけです。
defp deps do
[
{:power_assert, "~> 0.0"}
]
end
PowerAssertEx を有効にする
テストコードで use ExUnit.Case
としている箇所を use PowerAssert
とするだけで有効になります。
defmodule YourAwesomeTest do
- use ExUnit.Case
+ use PowerAssert
end
あるいは ExUnit.CaseTemplate
を使ったテストコードを書いているかもしれません。その場合は using
macro を定義して quote ブロック中に use PowerAssert
を追加してください。
defmodule YourAwesomeTest do
use ExUnit.CaseTemplate
+ using do
+ quote do
+ use PowerAssert
+ end
+ end
end
これで完了です。Happy Testing!
制限
マクロに対するテストで落ちることがある
マクロに対するテストコードで Power Assert
を使うと落ちることがあります。
PowerAssertEx
の AST 変換処理がマクロをしっかり考慮できていないためです。
表示がおかしくなるとかではなく、テストが途中でとまってしまうので、制限と書いています。
これもできればしっかりしたいなと思いつつ出来ていません。一時的に回避する場合は ExUnit
の assert
を使えばよいです。
今後
制限の部分をもう少し緩めの制限にすることができたら 0.1.0 とか出したいなと考えています。ただあまり計画を立てるのは得意ではないので、いつになるやらという感じです。
どちらかというと今の時点のコードでもう少しユーザを増やしていきたいなと考えています。もし良ければ使ってみて、フィードバックなどいただければと思います。あとスターつけてくださいお願いします。
ちなみに今度の Elixir Meetup #1 in Drecom で Power Assert について話してきます。この記事の内容は初心者向けでしたが、このイベントでは inside PowerAssertEx 的なマニアックな話をしたいなと考えています。
参考リンク
- at GitHub
- at hexpm
- power-assert in JavaScript
- power-assert-js
- Power Assert in Ruby
-
Elixir の ExUnit は lhs, rhs の計算結果までは表現してくれるので、Power Assert っぽいところがあり単に失敗していると言うと少し語弊がありますが。 ↩