ExUnit uses a wonderful utility of Elixir to provide an elegant way to organize and group tests. This feature is the module attribute.

This has proven invaluable as our systems and test suites we build grow bigger & more complex. It makes testing new features more efficient and fast. Using this we don't have to run every other tests (which could be thousands) in the system.

We'll be writing a test suite for an imaginary mathematical module.

The first attribute is `@tag`

which marks a single test case:

```
defmodule MathTest do
use ExUnit.Case
# ...
@tag :this
test "that we can add two numbers together" do
assert 2 == Math.add(1, 1)
end
# ...
end
```

Even if we have thousands of test cases, we can run only the tagged test with `mix test --only this`

.

*That's all fine and good, but what if I want to run more than one test?* Good question. ExUnit has you covered.

Let's say we wanted to test all associative operations in our module. We organize those tests into groups with `describe`

and annotate them with `@describetag`

:

```
defmodule MathTest do
use ExUnit.Case
describe "associative functions" do
@describetag math: "associative"
test "that addition is associative" do
assert Math.add(1, 2) == Math.add(2, 1)
end
# ...
end
describe "commutative functions" do
@describetag math: "commutative"
test "that multiplication is commutative" do
assert Math.multiply(3, 2) == Math.multiply(2, 3)
end
# ...
end
# ...
end
```

In our test suite, we have described two groups of tests. If we wanted to run only the associative tests, we could do so with `mix test --only math:"associative"`

. Likewise, `mix test --only math:"commutative"`

runs only the tests in the `"commutative functions"`

group.

Notice that there's no space between `math:`

and `"commutative"`

in the test command.

*Ok, that's cool. What if I wanted to run all test groups defined in a file?* Another good question. Again, tags to the rescue!.

To run all tests in a file, we use `@moduletag`

:

```
defmodule MathTest do
use ExUnit.Case
@moduletag :math
describe "associativity" do
@describetag math: "associative"
test "that addition is associative" do
assert Math.add(1, 2) == Math.add(2, 1)
end
# ...
end
describe "commutativity" do
@describetag math: "commutative"
test "that multiplication is commutative" do
assert Math.multiply(3, 2) == Math.multiply(2, 3)
end
# ...
end
@tag :this
test "that we can add two numbers together" do
assert 2 == Math.add(1, 1)
end
# ...
end
```

`mix test --only math`

will run all tests in the `MathTest`

file.

While we've used simple illustrations, `@tag`

, `@describetag`

and `@moduletag`

are Lego blocks that can be combined in various ways.