In writing a split
function that breaks up a sentence into each individual word based upon punctuation i.e. splits on something like the character class [\s,.?!]+
, though for the purposes of this question the implementation is not important, and the list of characters to split on should be considered to be of arbitrary length. This question is specifically about designing good unit tests.
I found myself writing my (ExUnit) tests in this way:
defmodule MyModuleTest do
use ExUnit.Case, async: true
doctest MyModule
test "splits on '?'" do
assert MyModule.split("a" <> "?" <> "a") == ["a", "a"]
assert MyModule.split("a" <> "?" <> "?" <> "a") == ["a", "a"] ## Multiple chars
assert MyModule.split("?" <> "a" <> "?" <> "a" <> "?") == ["a", "a"] ## Padded string
end
test "splits on '!'" do
assert MyModule.split("a" <> "!" <> "a") == ["a", "a"]
assert MyModule.split("a" <> "!" <> "!" <> "a") == ["a", "a"] ## Multiple chars
assert MyModule.split("!" <> "a" <> "!" <> "a" <> "!") == ["a", "a"] ## Padded string
end
test "MyModule.splits on '.'" do
assert MyModule.split("a" <> "." <> "a") == ["a", "a"]
assert MyModule.split("a" <> "." <> "." <> "a") == ["a", "a"] ## Multiple chars
assert MyModule.split("." <> "a" <> "." <> "a" <> ".") == ["a", "a"] ## Padded string
end
# ## etc. etc.
end
Which could of course be DRY'd up by doing something such as the following:
Enum.each ~w(. , ? ! \s), fn char ->
@char char
test "splits on \"#{@char}\"" do
assert MyModule.split("a" <> @char <> "a") == ["a", "a"]
assert MyModule.split("a" <> @char <> @char <> "a") == ["a", "a"] ## Multiple chars
assert MyModule.split(@char <> "a" <> @char <> "a" <> @char) == ["a", "a"] ## Padded string
end
end
However, certain schools of thought posit that when unit testing, tests should be DAMP and not DRY.
- In this case, is the second example an anti-pattern?
- If so, is the first (or another) way a better approach to structuring this test?
EDIT: While feedback on this specific case is appreciated, this question is primarily about software testing patterns. This question was asked in order to obtain information or thoughts concerning whether looping over a list (of arbitrary data or length) in order to generate test cases violates the principle of DAMP unit tests.