Anko

Anko

Global State in tests

I’m doing evaluation of using elixir for some e2e api tests for a distributed application not written in elixir.

My plan is to use ExUnit to run these tests concurrently with the Req library. I think it will showcase elixir’s strength in parallelism.

The problem i’m facing at the moment is I’d like some global state which contains the bearer tokens for the rest of the tests. I can do a login in a setup_all function, in each test module, but that means we login a bunch more times than is needed. The applicaiton will create a new bearer token each login, and i really want to share one between modules for the same user.

I just wondered if anyone has encountered this type of thing before and how they solved it? Ideally ExUnit.start would have an option of a state, which gets merged with the state from setup/setup_all

Am I thinking about this wrong?

Marked As Solved

Hermanverschooten

Hermanverschooten

Hacky, but you could declare a module in your test_helper.exs that logs in and stores the token in a function. Something like:

defmodule Login do
@token login_me_in()
  def token, do: @token

  def log_me_in do
      Your login code here
  end
end

This would get executed once before all the tests.

You would call it as Login.token()

You could play around with @tag and :included in ExUnit.configuration() to only conditionally do the login, so eg use a tag :external and only really perform the login if it is included, otherwise return a dummy token.

Also Liked

gpopides

gpopides

My solution to this to get the token in test_helper.exs put it in the env and then in test’s setup pick the token from the env for the tests that need it.

Application.put_env(
  :app,
  :token_key,
  get_token()
)
// test
  setup_all do
    token = Application.get_env(:app, :token_key)
Hermanverschooten

Hermanverschooten

@adw632’s solution would work if all your tests that need the token are in the same testfile. setup_all would run just once before all these tests, but as far as I know there is currently no way to set a “before” hook to run once before all the tests, there is one for after all tests after_suite/1.

adw632

adw632

Yes ExUnit is designed to isolate tests and test suites so you don’t get leakage and side effects between tests.

It even randomizes the order to help catch unintended dependencies and side effects to make testing robust.

You could use the test_helper compile time “evil” that @Hermanverschooten showed to create a globally fixed value.

You could also use many of the nicely explained flakey test approaches to undo all the goodness that ExUnit provides and make your tests flakey and evil too.

Such evil can include stashing a Req structure in the Application environment or Ets. So in your setup_all callback you try and get the Req struct and only create and set it if it is doesn’t yet exist.

You will likely introduce a race condition on the create which you thoughly deserve for doing such evil things.

I would just use setup_all to do the authentication once per test suite. How many test suites do you have?

Perhaps you need to think about Mocking?

Where Next?

Popular in Questions Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
Kurisu
For example for a current url like http://localhost:4000/cosmetic/products?_utf8=✓&query=perfume&page=2, I would like to get: ...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lists...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
mgjohns61585
Could someone help me? I’m making my first elixir program, number guessing game. I can’t figure out how to convert the user’s guess from ...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
shijith.k
I am trying to start a new phoenix project with elixir 1.9, but mix phx.new does not work. It says that ** (Mix) The task "phx.new" could...
New

Other popular topics Top

9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 43657 311
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31194 112
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 52774 488
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New

We're in Beta

About us Mission Statement