betamaxpy / betamax

A VCR imitation designed only for python-requests.
https://betamax.readthedocs.io/en/latest/
Other
562 stars 61 forks source link

Betamax injection with pytest-console-scripts #166

Closed kratsg closed 5 years ago

kratsg commented 5 years ago

Let's suppose that we wish to have full coverage of tests. Imagine that we have something like test_institution.py which contains a test like the following:

def test_get():
    session = mypackage.core.Session()
    with betamax.Betamax(session).use_cassette('test_institution.test_get'):
        response = session.get('institutions')
        assert response.status_code == 200 
        assert response.json()

and this test works perfectly, where class mypackage.core.Session(requests.Session) exists and is a Session class for the package that inherits requests.Session so it plays nicely with betamax. This is great.

Now imagine we have test_scripts.py which contains the following

def test_institutions(script_runner):
    command = 'mypackage listinstitutions'
    ret = script_runner.run(*shlex.split(command))
    assert ret.success
    assert ret.stderr == ''

where the commandline.py looks like

@mypackage.command()
def listinstitutions():
    print(json.dumps(core.Session().get('institutions'), indent=2))
    sys.exit(0)

How can we inject betamax into the Session to pick up the saved cassette when the test runs? Is this possible with current betamax? I suspect not.


One idea I had is to use environment variables / command line arguments set as part of testing that enable/disable betamax so that commandline.py manually injects betamax for us. E.G. something like

mypackage listinstitutions --use-cassette="test_institution.test_get"

and then just inject betamax in there correctly. Am I doing my logic wrong? I would like to be able to test/cover the CLI scripts in the package.

sigmavirus24 commented 5 years ago

We don't inherently support this.

You can't monkey-patch every Session ever created today with Betamax, nor is that something I'd really want in the core library. Without understanding your command-line better, you might be able to do --use-cassette, detect that and pass a session into listinstitutions that you use instead of core.Session() which has been Betamax-ified.

Otherwise, you could have a function that returns a session core.make_session() that checks env-vars or whatever else to determine if you're using betamax and does the right things.

kratsg commented 5 years ago

Great, thanks for the response @sigmavirus24 . I suspected as much (un)fortunately.