I’m currently in the middle of refactoring some of our API tests and changed our describe blocks from
describe "list contacts" do
end
describe "upsert contacts" do
end
to
describe "GET /contacts" do
end
describe "PUT /contacts" do
end
And suddenly one test is failing with a weird validation error, but what’s even weirder is the fact that when I change for example one of the descriptions to GET /contacts2, everything works again. Therefore the question: Does a describe block some influence ExUnit test cases? For example by setting a not so random seed?
I don’t think so. we can change the description anytime in test cases without any influence on the test.
can you plz showcase your error? @ream88
OR
are you using any @moduletag :external, or any @describetag :endpoint in your test case. Kindly confirm that.
Nope not using this tags. I’m currently suspecting a setup block which creates a current user to work with prior of all tags to be the source of the problem. Because I’m getting a user related validation problem, and also adding some IO.inspect calls to the user creation process logs an already existing user when there should not be any. Looks like this setup block is called twice when using both GET and PUT in my descriptions.
Note: describe blocks cannot be nested. Instead of relying on hierarchy for composition, you should build on top of named setups. For example:
defmodule UserManagementTest do
use ExUnit.Case, async: true
describe "when user is logged in and is an admin" do
setup [:log_user_in, :set_type_to_admin]
test ...
end
describe "when user is logged in and is a manager" do
setup [:log_user_in, :set_type_to_manager]
test ...
end
defp log_user_in(context) do
# ...
end
end
By forbidding hierarchies in favor of named setups, it is straightforward for you to glance at each described block and know exactly the setup steps involved.
Ok, found the problem… it really looks like the describe text influences the seed that :rand uses, and for whatever reason this broke my tests… We use the following function to generate random phone numbers for our user fixtures, and using PUT /contacts and GET /contacts simultaneously influenced it to generate twice the same phone number:
def random_string(charset, length) do
for _ <- 1..length, into: "", do: <<Enum.random(charset)>>
end
Using System.unique_integer/1 fixed my problem not ever having the same phone number twice for different users.