Testing with Power Assert in Elixir projects

## What is Power Assert?

Power Assert informs failed tests with more descriptive expression than normal assert function. It's originally came from Groovy language's Spock test framework as far as I know.

For example the failed result with ExUnit's `assert` macro:

```console:before
  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
```

The result is changed with PowerAssertEx's `assert` macro:

```console:after
  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

```

Here is the difference between ExUnit and PowerAssertEx results:

```diff: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]
```

So Power Assert provides to display each value of each statement like the above. The results is easy to understand than the normal assertion behaviour.
When you learn a new programming language, I think that becomes easy to learn if that language provides power assert function. There is often "Why does my code not work?" when learning a new language. If there is each result of each statement in such case, it is useful to understand a new language.

If you would like to know Power Assert more, please see the following slide. The slide's author is [t_wada](https://twitter.com/t_wada), he is the author of [power-assert](https://github.com/power-assert-js/power-assert) in JavaScript.

[power-assert in JavaScript](http://www.slideshare.net/t_wada/powerassert-in-javascript)

## What is Power Assert in Elixir?

[PowerAssertEx](https://github.com/ma2gedev/power_assert_ex) is Power Assert in Elixir. PowerAssertEx provides Power Assert function by overwriting ExUnit's `assert` macro, for that reason PowerAssertEx is highly dependent on ExUnit. You can easily go back to ExUnit from PowerAssertEx because you do not need to modify all of `assert` macro.

## How to use in your project

### Precondition

- ExUnit

PowerAssertEx is strongly dependent on ExUnit. So you writes test code follow the ExUnit rule. It's easy to start if you already use ExUnit for testing.

### Installation

Add PowerAssertEx dependency to your mix.exs file like the following. And execute `mix deps.get`.

```ex:mix.exs
defp deps do
  [
    {:power_assert, "~> 0.0"}
  ]
end
```

### Enable PowerAssertEx in your test code

You only change `use ExUnit.Case` into `use PowerAssert` to enable PowerAssertEx.

```diff:your_awesome_test.ex
defmodule YourAwesomeTest do
-  use ExUnit.Case
+  use PowerAssert
end
```

Or if you use `ExUnit.CaseTemplate` module, in this case you define `using` macro to return quote block includes `use PowerAssert` in your test module.

```diff:your_awesome_test.ex
defmodule YourAwesomeTest do
  use ExUnit.CaseTemplate
+  using do
+    quote do
+      use PowerAssert
+    end
+  end
end
```

Done! Now you can use `assert` macro with Power Assert function! Happy Testing! :muscle:

### Use with other test frameworks such as ExSpec or ShouldI

These frameworks dependent on ExUnit. So it's also available please see [the readme](https://github.com/ma2gedev/power_assert_ex#how-to-use-other-framework-depending-on-exunit-such-as-exspec-or-shouldi) if you would like to use with [ExSpec](https://github.com/drewolson/ex_spec) or [ShouldI](https://github.com/batate/shouldi).

## Limitation

### Compilation error when test against macro

Currently PowerAssertEx's `assert` macro sometimes failed to compile if test code includes testing against macro. Because PowerAssertEx does not handle correctly to convert abstract syntax tree in such case.
To work around this problem you use ExUnit's `assert` macro instead on that test code.

## Summary

Please try to use PowerAssertEx in your project, it's very easy to start.
Please feel free to give me any [feedback](https://twitter.com/ma2ge).
And also please give me a [star](https://github.com/ma2gedev/power_assert_ex) on GitHub if you like PowerAssertEx. :smile:

## Resources

- PowerAssertEx at GitHub
  - https://github.com/ma2gedev/power_assert_ex
- PowerAssertEx at hexpm
  - https://hex.pm/packages/power_assert
- Power Assert Inside in Elixir
  - https://speakerdeck.com/ma2gedev/power-assert-inside-in-elixir
- Power Assertions - The Groovy programming language - Testing guide
  - http://www.groovy-lang.org/testing.html#_power_assertions
- Power Assert for Java and others
  - https://stokito.wordpress.com/2015/10/05/power-assert-for-java-and-others/
- power-assert in JavaScript
  - http://www.slideshare.net/t_wada/powerassert-in-javascript
- power-assert-js
  - https://github.com/power-assert-js/power-assert
- Power Assert in Ruby
  - https://speakerdeck.com/k_tsj/power-assert-in-ruby
- ExSpec
  - https://github.com/drewolson/ex_spec
- ShouldI
  - https://github.com/batate/shouldi