D4no0

D4no0

Http client e2e testing

I have a project where we do http requests to public domains.

I am currently using Mox for testing and following their practices by having a callback for the http client and a implementation:

defmodule HttpClient do
  @callback request(atom(), binary(), binary(), keyword(), keyword()) ::
              {:ok, HttpClient.Response.t() | HttpClient.MaybeRedirect.t()}
              | {:error, any()}
end

While it works great for tests with mocked data, I still find that these tests are double edged, as they are fully dependent on the correctness of data and format of it, we already had cases where the tests would pass and the application would fail at runtime.

I was wondering if maybe replacing this kind of mocked tests with a real local http server (similarly to how ecto uses sandbox) that exhibits real properties would be better and make for cleaner and easier to manage tests.

Any thoughts on this or tools you could recommend?

Marked As Solved

hst337

hst337

Bypass

I would recommend Patch for everybody. It is universal and more friendly solution.

This is caused by different data in tests and in reality. You can just copy-paste data from real responses and use it on testing. Or you can even use solutions like ExVCR


Anyway, final decision depends on amount of time you have and what quality of tests you want

Also Liked

hst337

hst337

  • Cassettes can contain outdated data: some services have TTLs for their responses. Or something like your ID in the third-party service can change and responses in cassettes can become stale. A lot of other stuff too
  • They’re not easy to rerecord correctly. Because manual changes to the cassettes have to be reapplied every time you rerecord them
dimitarvp

dimitarvp

I get it that it might not be scalable to manually collect all of the API responses but I have used ExVCR in the past and ended up… manually collecting all the API responses that I needed for tests. The API had slight changes – 3 times in a single year – but it was enough to piss us off because we shipped non-working features in production due to outdated cassettes.

So we rolled up our sleeves and what do you know, something like 70 API responses took 3 people 5-6 work days (and we were not doing only that, it was just an ongoing effort). Not a huge deal, though granted it’s annoying to do.

So I am with @hst337 here – take control of this.

Of course nobody is stopping you scripting this somewhat. I was able to devise a small text file format a while ago (next time I needed something like this) and just have a bash/zsh script loop over the lines inside the file and do curl requests and record the responses. Took me 80% the way there (though it was super specific and was not generalizable).

hst337

hst337

Beware: VCR solutions are hard to maintain

Where Next?

Popular in Questions Top

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
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
RisingFromAshes
I've read in another post that it may be possible with a router helper - but I couldn't find an appropriate one, and tbh, I'm still just ...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
hariharasudhan94
Lets say i have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => "XX...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New

Other popular topics Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
Nvim
Anybody knows a comprehensive comparison of Django and Phoenix, thanks for the help. Where are they similar? Where do they differ the m...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
Lily
In templates/appointment/index.html.eex: <%= for appointment <- @appointments do %> <tr> <td><%= appoi...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
vegabook
I'm brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New

We're in Beta

About us Mission Statement