-
Notifications
You must be signed in to change notification settings - Fork 387
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #712 from kevin1024/integrate-vcrpy-unittest
Integrate vcrpy-unittest (alternative to #709)
- Loading branch information
Showing
5 changed files
with
303 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,195 @@ | ||
import os | ||
from unittest import TextTestRunner, defaultTestLoader | ||
from unittest.mock import MagicMock | ||
from urllib.request import urlopen | ||
|
||
from vcr.unittest import VCRTestCase | ||
|
||
|
||
def test_defaults(): | ||
class MyTest(VCRTestCase): | ||
def test_foo(self): | ||
pass | ||
|
||
test = run_testcase(MyTest)[0][0] | ||
expected_path = os.path.join(os.path.dirname(__file__), "cassettes") | ||
expected_name = "MyTest.test_foo.yaml" | ||
assert os.path.dirname(test.cassette._path) == expected_path | ||
assert os.path.basename(test.cassette._path) == expected_name | ||
|
||
|
||
def test_disabled(): | ||
# Baseline vcr_enabled = True | ||
class MyTest(VCRTestCase): | ||
def test_foo(self): | ||
pass | ||
|
||
test = run_testcase(MyTest)[0][0] | ||
assert hasattr(test, "cassette") | ||
|
||
# Test vcr_enabled = False | ||
class MyTest(VCRTestCase): | ||
vcr_enabled = False | ||
|
||
def test_foo(self): | ||
pass | ||
|
||
test = run_testcase(MyTest)[0][0] | ||
assert not hasattr(test, "cassette") | ||
|
||
|
||
def test_cassette_library_dir(): | ||
class MyTest(VCRTestCase): | ||
def test_foo(self): | ||
pass | ||
|
||
def _get_cassette_library_dir(self): | ||
return "/testing" | ||
|
||
test = run_testcase(MyTest)[0][0] | ||
assert test.cassette._path.startswith("/testing/") | ||
|
||
|
||
def test_cassette_name(): | ||
class MyTest(VCRTestCase): | ||
def test_foo(self): | ||
pass | ||
|
||
def _get_cassette_name(self): | ||
return "my-custom-name" | ||
|
||
test = run_testcase(MyTest)[0][0] | ||
assert os.path.basename(test.cassette._path) == "my-custom-name" | ||
|
||
|
||
def test_vcr_kwargs_overridden(): | ||
class MyTest(VCRTestCase): | ||
def test_foo(self): | ||
pass | ||
|
||
def _get_vcr_kwargs(self): | ||
kwargs = super()._get_vcr_kwargs() | ||
kwargs["record_mode"] = "new_episodes" | ||
return kwargs | ||
|
||
test = run_testcase(MyTest)[0][0] | ||
assert test.cassette.record_mode == "new_episodes" | ||
|
||
|
||
def test_vcr_kwargs_passed(): | ||
class MyTest(VCRTestCase): | ||
def test_foo(self): | ||
pass | ||
|
||
def _get_vcr_kwargs(self): | ||
return super()._get_vcr_kwargs( | ||
record_mode="new_episodes", | ||
) | ||
|
||
test = run_testcase(MyTest)[0][0] | ||
assert test.cassette.record_mode == "new_episodes" | ||
|
||
|
||
def test_vcr_kwargs_cassette_dir(): | ||
# Test that _get_cassette_library_dir applies if cassette_library_dir | ||
# is absent from vcr kwargs. | ||
class MyTest(VCRTestCase): | ||
def test_foo(self): | ||
pass | ||
|
||
def _get_vcr_kwargs(self): | ||
return dict( | ||
record_mode="new_episodes", | ||
) | ||
|
||
_get_cassette_library_dir = MagicMock(return_value="/testing") | ||
|
||
test = run_testcase(MyTest)[0][0] | ||
assert test.cassette._path.startswith("/testing/") | ||
assert test._get_cassette_library_dir.call_count == 1 | ||
|
||
# Test that _get_cassette_library_dir is ignored if cassette_library_dir | ||
# is present in vcr kwargs. | ||
class MyTest(VCRTestCase): | ||
def test_foo(self): | ||
pass | ||
|
||
def _get_vcr_kwargs(self): | ||
return dict( | ||
cassette_library_dir="/testing", | ||
) | ||
|
||
_get_cassette_library_dir = MagicMock(return_value="/ignored") | ||
|
||
test = run_testcase(MyTest)[0][0] | ||
assert test.cassette._path.startswith("/testing/") | ||
assert test._get_cassette_library_dir.call_count == 0 | ||
|
||
|
||
def test_get_vcr_with_matcher(tmpdir): | ||
cassette_dir = tmpdir.mkdir("cassettes") | ||
assert len(cassette_dir.listdir()) == 0 | ||
|
||
mock_matcher = MagicMock(return_value=True, __name__="MockMatcher") | ||
|
||
class MyTest(VCRTestCase): | ||
def test_foo(self): | ||
self.response = urlopen("http://example.com").read() | ||
|
||
def _get_vcr(self): | ||
myvcr = super()._get_vcr() | ||
myvcr.register_matcher("mymatcher", mock_matcher) | ||
myvcr.match_on = ["mymatcher"] | ||
return myvcr | ||
|
||
def _get_cassette_library_dir(self): | ||
return str(cassette_dir) | ||
|
||
# First run to fill cassette. | ||
test = run_testcase(MyTest)[0][0] | ||
assert len(test.cassette.requests) == 1 | ||
assert not mock_matcher.called # nothing in cassette | ||
|
||
# Second run to call matcher. | ||
test = run_testcase(MyTest)[0][0] | ||
assert len(test.cassette.requests) == 1 | ||
assert mock_matcher.called | ||
assert ( | ||
repr(mock_matcher.mock_calls[0]) | ||
== "call(<Request (GET) http://example.com>, <Request (GET) http://example.com>)" | ||
) | ||
|
||
|
||
def test_testcase_playback(tmpdir): | ||
cassette_dir = tmpdir.mkdir("cassettes") | ||
assert len(cassette_dir.listdir()) == 0 | ||
|
||
# First test actually reads from the web. | ||
|
||
class MyTest(VCRTestCase): | ||
def test_foo(self): | ||
self.response = urlopen("http://example.com").read() | ||
|
||
def _get_cassette_library_dir(self): | ||
return str(cassette_dir) | ||
|
||
test = run_testcase(MyTest)[0][0] | ||
assert b"illustrative examples" in test.response | ||
assert len(test.cassette.requests) == 1 | ||
assert test.cassette.play_count == 0 | ||
|
||
# Second test reads from cassette. | ||
|
||
test2 = run_testcase(MyTest)[0][0] | ||
assert test.cassette is not test2.cassette | ||
assert b"illustrative examples" in test.response | ||
assert len(test2.cassette.requests) == 1 | ||
assert test2.cassette.play_count == 1 | ||
|
||
|
||
def run_testcase(testcase_class): | ||
"""Run all the tests in a TestCase and return them.""" | ||
suite = defaultTestLoader.loadTestsFromTestCase(testcase_class) | ||
tests = list(suite._tests) | ||
result = TextTestRunner().run(suite) | ||
return tests, result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import inspect | ||
import os | ||
import unittest | ||
|
||
from .config import VCR | ||
|
||
|
||
class VCRMixin: | ||
"""A TestCase mixin that provides VCR integration.""" | ||
|
||
vcr_enabled = True | ||
|
||
def setUp(self): | ||
super().setUp() | ||
if self.vcr_enabled: | ||
kwargs = self._get_vcr_kwargs() | ||
myvcr = self._get_vcr(**kwargs) | ||
cm = myvcr.use_cassette(self._get_cassette_name()) | ||
self.cassette = cm.__enter__() | ||
self.addCleanup(cm.__exit__, None, None, None) | ||
|
||
def _get_vcr(self, **kwargs): | ||
if "cassette_library_dir" not in kwargs: | ||
kwargs["cassette_library_dir"] = self._get_cassette_library_dir() | ||
return VCR(**kwargs) | ||
|
||
def _get_vcr_kwargs(self, **kwargs): | ||
return kwargs | ||
|
||
def _get_cassette_library_dir(self): | ||
testdir = os.path.dirname(inspect.getfile(self.__class__)) | ||
return os.path.join(testdir, "cassettes") | ||
|
||
def _get_cassette_name(self): | ||
return "{0}.{1}.yaml".format(self.__class__.__name__, self._testMethodName) | ||
|
||
|
||
class VCRTestCase(VCRMixin, unittest.TestCase): | ||
pass |