11import os
2- import vcr
32import zlib
43import base64
5- import pytest
64import pickle
5+
6+ import vcr
7+ import mock
8+ import pytest
9+ import shutil
710import requests
11+
812from scrapinghub import HubstorageClient
913from scrapinghub .hubstorage .utils import urlpathjoin
1014
@@ -29,7 +33,7 @@ def serialize(self, cassette_dict):
2933 # receives a dict, must return a string
3034 # there can be binary data inside some of the requests,
3135 # so it's impossible to use json for serialization to string
32- compressed = zlib .compress (pickle .dumps (cassette_dict ))
36+ compressed = zlib .compress (pickle .dumps (cassette_dict , protocol = 2 ))
3337 return base64 .b64encode (compressed ).decode ('utf8' )
3438
3539 def deserialize (self , cassette_string ):
@@ -46,12 +50,25 @@ def deserialize(self, cassette_string):
4650def pytest_addoption (parser ):
4751 parser .addoption (
4852 "--update-cassettes" , action = "store_true" , default = False ,
49- help = "make tests with real services instead of vcr cassettes" )
50-
51-
52- def pytest_generate_tests (metafunc ):
53- if metafunc .config .option .update_cassettes :
53+ help = "test with real services rewriting existing vcr cassettes" )
54+ parser .addoption (
55+ "--ignore-cassettes" , action = "store_true" , default = False ,
56+ help = "test with real services skipping existing vcr cassettes" )
57+
58+
59+ def pytest_configure (config ):
60+ if config .option .update_cassettes :
61+ # there's vcr `all` mode to update cassettes but it doesn't delete
62+ # or clear existing records, so its size will always only grow
63+ if os .path .exists (VCR_CASSETES_DIR ):
64+ shutil .rmtree (VCR_CASSETES_DIR )
65+ elif config .option .ignore_cassettes :
66+ # simple hack to just ignore vcr cassettes:
67+ # - all record_mode means recording new interactions + no replay
68+ # - before_record returning None means skipping all the requests
69+ global my_vcr
5470 my_vcr .record_mode = 'all'
71+ my_vcr .before_record_request = lambda request : None
5572
5673
5774@pytest .fixture (scope = 'session' )
@@ -64,12 +81,20 @@ def hsproject(hsclient):
6481 return hsclient .get_project (TEST_PROJECT_ID )
6582
6683
67- # @my_vcr.use_cassette()
84+ @my_vcr .use_cassette ()
6885@pytest .fixture (scope = 'session' )
6986def hsspiderid (hsproject ):
7087 return str (hsproject .ids .spider (TEST_SPIDER_NAME , create = 1 ))
7188
7289
90+ @my_vcr .use_cassette ()
91+ @pytest .fixture (scope = 'session' )
92+ def hscollection (hsproject ):
93+ collection = get_test_collection (hsproject )
94+ clean_collection (collection )
95+ yield collection
96+ clean_collection (collection )
97+
7398
7499@my_vcr .use_cassette ()
75100@pytest .fixture (autouse = True , scope = 'session' )
@@ -83,25 +108,23 @@ def setup_session(hsclient, hsproject, hscollection):
83108
84109
85110@pytest .fixture (autouse = True )
86- def setup_vcrpy_per_test (request , hsproject ):
111+ def setup_vcrpy (request , hsproject ):
87112 # generates names like "test_module/test_function.yaml"
113+ # otherwise it uses current function name (setup_vcrpy) for all tests
114+ # other option is to add vcr decorator to each test separately
88115 cassette_name = '{}/{}.gz' .format (
89116 request .function .__module__ .split ('.' )[- 1 ],
90117 request .function .__name__
91118 )
119+ # we should clean jobs only when working with real services
120+ # doesn't make sense to clean jobs when working with cassettes
121+ if (request .config .option .update_cassettes or
122+ request .config .option .ignore_cassettes ):
123+ remove_all_jobs (hsproject )
92124 with my_vcr .use_cassette (cassette_name ):
93125 yield
94126
95127
96- @my_vcr .use_cassette ()
97- @pytest .fixture (scope = 'session' )
98- def hscollection (hsproject ):
99- collection = get_test_collection (hsproject )
100- clean_collection (collection )
101- yield collection
102- clean_collection (collection )
103-
104-
105128# ----------------------------------------------------------------------------
106129
107130
0 commit comments