kiwicom / pytest-recording

A pytest plugin that allows recording network interactions via VCR.py
MIT License
441 stars 35 forks source link

[BUG] #77

Open MasterSergius opened 3 years ago

MasterSergius commented 3 years ago

Describe the bug Can't write cassette for file uploading. Is it possible to achieve that?

To Reproduce Steps to reproduce the behavior:

  1. Sample piece of code, which I want to cover with integration test

    async def upload_file(filename):
    # some code omitted for simplicity
    data = {'file': open(filename, 'rb')}
    async with aiohttp.ClientSession() as session:
        async with session.post(url, headers=headers, data=data) as response:
            result = await response.read()
            return response.status, result
  2. Test:

    @pytest.mark.vcr()
    async def test_upload_file():
        img = open(f'{test_data_path}/logo.png', 'rb')
        status, result = await client.upload_file(img)
  3. While test is passed, vcr failed to write cassette:

    
    ../venv/lib/python3.8/site-packages/vcr/cassette.py:91: in __exit__
    next(self.__finish, None)
    ../venv/lib/python3.8/site-packages/vcr/cassette.py:69: in _patch_generator
    cassette._save()
    ../venv/lib/python3.8/site-packages/vcr/cassette.py:331: in _save
    self._persister.save_cassette(self._path, self._as_dict(), serializer=self._serializer)
    ../venv/lib/python3.8/site-packages/vcr/persisters/filesystem.py:20: in save_cassette
    data = serialize(cassette_dict, serializer)
    ../venv/lib/python3.8/site-packages/vcr/serialize.py:58: in serialize
    return serializer.serialize(data)
    ../venv/lib/python3.8/site-packages/vcr/serializers/yamlserializer.py:15: in serialize
    return yaml.dump(cassette_dict, Dumper=Dumper)
    ../venv/lib/python3.8/site-packages/yaml/__init__.py:290: in dump
    return dump_all([data], stream, Dumper=Dumper, **kwds)
    ../venv/lib/python3.8/site-packages/yaml/__init__.py:278: in dump_all
    dumper.represent(data)
    ../venv/lib/python3.8/site-packages/yaml/representer.py:27: in represent
    node = self.represent_data(data)
    ../venv/lib/python3.8/site-packages/yaml/representer.py:48: in represent_data
    node = self.yaml_representers[data_types[0]](self, data)
    ../venv/lib/python3.8/site-packages/yaml/representer.py:207: in represent_dict
    return self.represent_mapping('tag:yaml.org,2002:map', data)
    ../venv/lib/python3.8/site-packages/yaml/representer.py:118: in represent_mapping
    node_value = self.represent_data(item_value)
    ../venv/lib/python3.8/site-packages/yaml/representer.py:48: in represent_data
    node = self.yaml_representers[data_types[0]](self, data)
    ../venv/lib/python3.8/site-packages/yaml/representer.py:199: in represent_list
    return self.represent_sequence('tag:yaml.org,2002:seq', data)
    ../venv/lib/python3.8/site-packages/yaml/representer.py:92: in represent_sequence
    node_item = self.represent_data(item)
    ../venv/lib/python3.8/site-packages/yaml/representer.py:48: in represent_data
    node = self.yaml_representers[data_types[0]](self, data)
    ../venv/lib/python3.8/site-packages/yaml/representer.py:207: in represent_dict
    return self.represent_mapping('tag:yaml.org,2002:map', data)
    ../venv/lib/python3.8/site-packages/yaml/representer.py:118: in represent_mapping
    node_value = self.represent_data(item_value)
    ../venv/lib/python3.8/site-packages/yaml/representer.py:48: in represent_data
    node = self.yaml_representers[data_types[0]](self, data)
    ../venv/lib/python3.8/site-packages/yaml/representer.py:207: in represent_dict
    return self.represent_mapping('tag:yaml.org,2002:map', data)
    ../venv/lib/python3.8/site-packages/yaml/representer.py:118: in represent_mapping
    node_value = self.represent_data(item_value)
    ../venv/lib/python3.8/site-packages/yaml/representer.py:48: in represent_data
    node = self.yaml_representers[data_types[0]](self, data)
    ../venv/lib/python3.8/site-packages/yaml/representer.py:207: in represent_dict
    return self.represent_mapping('tag:yaml.org,2002:map', data)
    ../venv/lib/python3.8/site-packages/yaml/representer.py:118: in represent_mapping
    node_value = self.represent_data(item_value)
    ../venv/lib/python3.8/site-packages/yaml/representer.py:52: in represent_data
    node = self.yaml_multi_representers[data_type](self, data)
    _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <yaml.dumper.Dumper object at 0x10cea75b0>, data = <_io.BufferedReader name='tests/integration/data/logo.png'>

def represent_object(self, data):
    # We use __reduce__ API to save the data. data.__reduce__ returns
    # a tuple of length 2-5:
    #   (function, args, state, listitems, dictitems)

    # For reconstructing, we calls function(*args), then set its state,
    # listitems, and dictitems if they are not None.

    # A special case is when function.__name__ == '__newobj__'. In this
    # case we create the object with args[0].__new__(*args).

    # Another special case is when __reduce__ returns a string - we don't
    # support it.

    # We produce a !!python/object, !!python/object/new or
    # !!python/object/apply node.

    cls = type(data)
    if cls in copyreg.dispatch_table:
        reduce = copyreg.dispatch_table[cls](data)
    elif hasattr(data, '__reduce_ex__'):
      reduce = data.__reduce_ex__(2)

E TypeError: cannot pickle '_io.BufferedReader' object

../venv/lib/python3.8/site-packages/yaml/representer.py:317: TypeError



**Expected behavior**
pytest-recording should not fail and provide some mock for IO objects or smth else

**Environment (please complete the following information):**

- OS: MacOS
- Python version: 3.8.2
- pytest-recording version: 0.10.0
- pytest version: 6.1.2

**Additional context**
Add any other context about the problem here.