diff --git a/tests/integration/test_config.py b/tests/integration/test_config.py index c6da8e8..1755385 100644 --- a/tests/integration/test_config.py +++ b/tests/integration/test_config.py @@ -60,3 +60,23 @@ def test_missing_matcher(): with pytest.raises(KeyError): with my_vcr.use_cassette("test.yaml", match_on=["notawesome"]): pass + + +def test_dont_record_on_exception(tmpdir): + my_vcr = vcr.VCR(record_on_exception=False) + + @my_vcr.use_cassette(str(tmpdir.join('dontsave.yml'))) + def some_test(): + assert 'Not in content' in urlopen('http://httpbin.org/get') + + with pytest.raises(AssertionError): + some_test() + + assert not os.path.exists(str(tmpdir.join('dontsave.yml'))) + + # Make sure context decorator has the same behavior + with pytest.raises(AssertionError): + with my_vcr.use_cassette(str(tmpdir.join('dontsave2.yml'))): + assert 'Not in content' in urlopen('http://httpbin.org/get').read() + + assert not os.path.exists(str(tmpdir.join('dontsave2.yml'))) diff --git a/vcr/cassette.py b/vcr/cassette.py index 901b7fb..2fe1a63 100644 --- a/vcr/cassette.py +++ b/vcr/cassette.py @@ -45,7 +45,9 @@ class CassetteContextDecorator: this class as a context manager in ``__exit__``. """ - _non_cassette_arguments = ("path_transformer", "func_path_generator") + _non_cassette_arguments = ( + "path_transformer", "func_path_generator", "record_on_exception", + ) @classmethod def from_args(cls, cassette_class, **kwargs): @@ -87,8 +89,13 @@ class CassetteContextDecorator: self.__finish = self._patch_generator(self.cls.load(**cassette_kwargs)) return next(self.__finish) - def __exit__(self, *args): - next(self.__finish, None) + def __exit__(self, *exc_info): + exception_was_raised = any(exc_info) + record_on_exception = self._args_getter().get( + 'record_on_exception', True + ) + if record_on_exception or not exception_was_raised: + next(self.__finish, None) self.__finish = None @wrapt.decorator diff --git a/vcr/config.py b/vcr/config.py index 45412e3..a991c95 100644 --- a/vcr/config.py +++ b/vcr/config.py @@ -49,6 +49,7 @@ class VCR: cassette_library_dir=None, func_path_generator=None, decode_compressed_response=False, + record_on_exception=True, ): self.serializer = serializer self.match_on = match_on @@ -80,6 +81,7 @@ class VCR: self.path_transformer = path_transformer self.func_path_generator = func_path_generator self.decode_compressed_response = decode_compressed_response + self.record_on_exception = record_on_exception self._custom_patches = tuple(custom_patches) def _get_serializer(self, serializer_name): @@ -123,6 +125,7 @@ class VCR: func_path_generator = kwargs.get("func_path_generator", self.func_path_generator) cassette_library_dir = kwargs.get("cassette_library_dir", self.cassette_library_dir) additional_matchers = kwargs.get("additional_matchers", ()) + record_on_exception = kwargs.get("record_on_exception", self.record_on_exception) if cassette_library_dir: @@ -149,6 +152,7 @@ class VCR: "path_transformer": path_transformer, "func_path_generator": func_path_generator, "allow_playback_repeats": kwargs.get("allow_playback_repeats", False), + "record_on_exception": record_on_exception, } path = kwargs.get("path") if path: