Testing HTTP in Elixir with ExVCR

Studying Elixir, I decided to write a client for an existing API and I wanted to do it in the correct way™: writing a complete test coverage.
My choice was to use HTTPoison (since I like Poison for JSON parsing) and ExVCR to write the API tests.

So, what is ExVCR? If you come from the Rails land, it’s the Elixir version of VCR, it:
“Record and replay HTTP interactions library for elixir. It’s inspired by Ruby’s VCR, and trying to provide similar functionalities.”
It allows you to make API calls and record those on “cassettes”, allowing you to replay the recordings at every test run, decoupling the test phase from the API server and permitting offline tests.

To start using it, we have to add in config/mix.exs the correct dependency:

Since we chose HTTPoison that uses Hackney as HTTP client, we have to specify the correct adapter, so our test file will look like:

The API we are writing the client for requires a login through basic_auth and if successful yields a cookie you can use for all the subsequent communications, until it expires.
Our first test is then:

Having everything (tests and cassettes included) under source control, we don’t want to put any sensitive data inside the repo. So we have username and password in ENV variables.

In fixtures/vcr_cassettes/api_client we find a login.json where our request and the response have been recorded. If we look into it we have:

We can see that the cassette has recorded the username and password we sent and the Cookie we got as response. Wanting to put everything in git we want to avoid these information to be written on disk. ExVCR gave you the opportunity to filter parameters based on a regular expression or simply censor request and/or response headers.

The whole list available was the following:

filter_request_header(header, value)

Unfortunately, using hackney, basic_auth data were placed in the option part of the request and no function to filter data in the option were given. So I wrote a patch to add this missing functionality and I added filter_request_options to the bunch. I then submitted a Pull Request that was merged to the benefit of everyone.

With this new little tool available, we can now go in config/test.exs and we can write:

If we run mix test again (remember to delete the cassette beforehand, otherwise ExVCR will use the saved one without contacting the API server), our newly censored cassette will be:

Now we can write all the tests we want without the fear to put sensitive data in our repos. I hope that this new functionality albeit small is going to be helpful to someone else too.

Leave a Reply