Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a python alternative to Ruby's VCR library?

Tags:

I'd like to use the awesome "record/playback" mechanism of Ruby's VCR library or Betamax for the JVM. Is there a Python library that works the same way? If not, how do you test your REST client calls without worrying about the test being slow and flaky?

like image 491
David Ackerman Avatar asked Jun 03 '12 19:06

David Ackerman


2 Answers

There is a Python port of VCR called VCR.py developed in the last years.

If you already know how to use VCR and are comfortable with it, you might also consider running a local ruby proxy server (using something like rack) with VCR loaded into it. Then you can test code in any language...just make sure the HTTP requests are being proxied through your local server. This is one of the main uses of VCR's rack middleware. I've used this to test non-ruby code before and it worked great.

like image 183
Myron Marston Avatar answered Sep 17 '22 17:09

Myron Marston


Both betamax and VCR.py have been suggested in other answers. I wanted to point out one difference which might dictate which one you are able to use.

Betamax expects you to pass a pre-created requests.Session object when setting it up for the test. This means that the session object must originate from inside the test, and not in the code under test. From the documentation:

with Betamax(self.session) as vcr:
    vcr.use_cassette('user')
    resp = self.session.get('https://api.github.com/user',
                            auth=('user', 'pass'))
    assert resp.json()['login'] is not None

In my case, the session object is created inside the code I need to test. In this case betamax was thus out of question.

VCR.py on the other hand patches Python's HTTP stack at a lower level, so this works perfectly:

import requests
import vcr

def my_func():
    session = requests.Session()
    response = session.get('https://stackoverflow.com/')
    print(response.text[:200])

def test_my_func():
    with vcr.use_cassette('/tmp/cassette.yaml'):
        my_func()
like image 45
akaihola Avatar answered Sep 18 '22 17:09

akaihola