Better Programming

Advice for programmers.

Follow publication

Your API Tests Must Be Reproducible!

Use VCRPY and Robotframework to make it happen

Eldad Uzman
Better Programming
Published in
3 min readAug 25, 2022

--

Photo by Gabriel Petry on Unsplash | Image height altered

API testing is essential for modern micro-services architecture, but reproducing test execution becomes a harder task as APIs get more complex.
In this article, I’ll introduce an awesome Python library that allows you to easily record your HTTP requests.

Introducing VCRPY

VCRPY uses “cassettes” as a metaphor for a recorded HTTP stream of a specific code block.

The idea is to use either a context-manager or a decorator for the particular block of code we wish to record, and the library in return creates a “cassette” which is a serialized file (by default, it’s a YAML file) containing all HTTP traffic.

First, we need to install our dependencies from pip:

pip install vcrpy==4.2.0 requests==2.28.1

Now, let's use vcrpy library in our code. Here’s an example:

In this simple example above, we used the use_cassette function from the VCR module. It creates a context manager that will generate the file my-cassette.yaml.

In this context, we send two HTTP requests to the postman-echo website using the requests library, after each request, we assert that the foo1 attribute equals to bar1 .

After we run the code, we can find the following in the newly created YAML file:

This gives us all the details of the HTTP traffic in our test script!
When we wish to reproduce the test execution, we can easily do that.

But there’s more to it!

After you’ve created the cassette, every time you rerun the test, vcrpy will intercept the HTTP traffic and replace it with its own mock.

The benefits of vcr.py include:

  1. Easily created mock objects for unit-tests
  2. Easily recorded HTTP traffic, very useful when your test scripts use random data.
  3. Easier to reproduce flaky bugs

There’s even more!

VCRPY is also easy to extend.

For example, you can create your own request serializer:

In this example, our serializer is completely useless. It pretty prints the data to the std output and then returns “hello there,” which will be appended to the cassette.

The result of running this code would be:

{'interactions': [{'request': {'body': None,
'headers': {'Accept': ['*/*'],
'Accept-Encoding': ['gzip, deflate'],
'Connection': ['keep-alive'],
'User-Agent': ['python-requests/2.28.1']},
'method': 'GET',
'uri': 'https://postman-echo.com/get?foo1=bar2&foo2=bar2&foo3=bar3'},
'response': {'body': {'string': '{"args":{"foo1":"bar2","foo2":"bar2","foo3":"bar3"},"headers":{"x-forwarded-proto":"https","x-forwarded-port":"443","host":"postman-echo.com","x-amzn-trace-id":"Root=1-630600d8-7cd8544e36022682693d82e7","user-agent":"python-requests/2.28.1","accept-encoding":"gzip, '
'deflate","accept":"*/*"},"url":"https://postman-echo.com/get?foo1=bar2&foo2=bar2&foo3=bar3"}'},
'headers': {'Connection': ['keep-alive'],
'Content-Length': ['358'],
'Content-Type': ['application/json; '
'charset=utf-8'],
'Date': ['Wed, 24 Aug 2022 '
'10:43:36 GMT'],
'ETag': ['W/"166-/OQmSZQmpVBffJEwyD65r935+QE"'],
'Vary': ['Accept-Encoding'],
'set-cookie': ['sails.sid=s%3AEBHLjc0aS_0cpuyhvKBS_GSU0eRyYgA7.qIcCjTOp8gHXNvykDiUhOOmsKgp848t4Hjfcacue0OI; '
'Path=/; HttpOnly']},
'status': {'code': 200, 'message': 'OK'}}}],
'version': 1}

and the file test.ridicule would look like:

Bonus Section: Integration With the Robotframework

First, let's install robotframework and robotframework-requests from pip:

pip install robotframework==5.0.1 robotframework-requests==0.9.3 

Now, let's create the robot test file, as shown below:

Now, we can use robotframework’s listener interface to integrate our test with VCR. Here’s the code:

So, our listener keeps the name of the current test suite and test case, and once the test chase starts, it will open a VCR context manager and exit the context manager once the test ends.

Let's run the test with the following command:

robot --listener [path/to/listener/file].VcrListener -P . tests

Here’s the test result:

And looking in the vcr_cassettes directory, we can find the corresponding cassette. Here’s what it looks like:

Thanks for reading!

Stay tuned for more.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

Eldad Uzman
Eldad Uzman

Written by Eldad Uzman

Automation and RPA developer, python developer.

No responses yet

Write a response