@adamdangoor
adamtheturtle
VERIFIED FAKES OF
WEB SERVICES
@adamdangoor
adamtheturtle
VERIFIED FAKES OF
WEB SERVICES
VUFORIA WEB
SERVICES
VUFORIA WEB
SERVICES
VUFORIA
WEB
SERVICES
OUR APP DATABASE
def get_match(image):
...
response = requests.request(
method=‘GET',
url=‘https://vws.vuforia.com/match',
data={‘image’: b64encode(image)},
)
return wine_from_db(id=response.json()[‘id’])
INITIAL TEST CASE
DATABASE PHOTO RESULT
def test_match_wine():
add_wine(image=blue_nun, name=“Blue Nun”)
add_wine(image=cristal, name=“Cristal”)
result = get_match(image=blue_nun)
assert result.name == ”Blue Nun”
INITIAL TEST CASE
PROBLEMS
PROBLEMS
๏ FLAKY TESTS
PROBLEMS
๏ FLAKY TESTS
PROBLEMS
๏ FLAKY TESTS
๏ € € €
PROBLEMS
๏ FLAKY TESTS
๏ € € €
๏ SLOW TESTS
๏ RESOURCE LIMITS
INTEGRATION
TESTS
UNIT
TESTS
INTEGRATION
TESTS
UNIT
TESTS
‣ COVER A LOT
OF CODE
PER TEST
‣ COVER
LESS CODE
PER TEST
INTEGRATION
TESTS
UNIT
TESTS
‣ COVER A LOT
OF CODE
PER TEST
‣ CAN BE
SLOW
‣ COVER
LESS CODE
PER TEST
‣ FAST
INTEGRATION
TESTS
UNIT
TESTS
‣ COVER A LOT
OF CODE
PER TEST
‣ CAN BE
SLOW
‣ COVER
LESS CODE
PER TEST
‣ FAST
INTEGRATION
TESTS
UNIT
TESTS
MOCKS
MOCKS
MOCKS
MOCKING REQUESTS
$ pip install requests-mock
with requests_mock.mock() as mock:
mock.get('http://test.com', text='data')
print(requests.get('http://test.com').text)
# prints 'data'
MOCKING REQUESTS
$ pip install requests-mock
with requests_mock.mock() as mock:
mock.get('http://test.com', text='data')
print(requests.get('http://test.com').text)
# prints 'data'
PYTEST FIXTURES
$ pip install pytest
@pytest.fixture()
def mock_vuforia() -> Generator:
with requests_mock.mock() as mock:
mock.get('http://test.com', text='data')
...
yield
@pytest.mark.usefixture('mock_vuforia')
def test_add_target():
...
@pytest.fixture()
def mock_vuforia() -> Generator:
with requests_mock.mock() as mock:
mock.get('http://test.com', text='data')
...
yield
@pytest.mark.usefixture('mock_vuforia')
def test_add_target():
...
PYTEST FIXTURES
$ pip install pytest
REQUESTS-MOCK DYNAMIC
RESPONSES
@pytest.fixture()
def mock_vuforia() -> Generator:
pattern = re.compile(‘http://vws.vuforia.com/targets/w+')
with requests_mock.mock() as mock:
mock.register_uri(
‘POST',
pattern,
text=add_target_to_database,
)
...
yield
REQUESTS-MOCK DYNAMIC
RESPONSES
def add_target_to_database(request, context):
context.headers['Date'] = rfc_1123_date()
return json.dumps({'status': 'added'})
REQUESTS-MOCK DYNAMIC
RESPONSES
def add_target_to_database(request, context):
context.headers['Date'] = rfc_1123_date()
return json.dumps({'status': 'added'})
REQUESTS-MOCK DYNAMIC
RESPONSES
def add_target_to_database(request, context):
context.headers['Date'] = rfc_1123_date()
return json.dumps({'status': 'added'})
@pytest.fixture()
def mock_vuforia() -> Generator:
pattern = re.compile(‘http://vws.vuforia.com/targets/w+')
with requests_mock.mock() as mock:
mock.register_uri(
‘POST',
pattern,
text=add_target_to_database,
)
...
yield
USING THE MOCK IN A TEST
@pytest.mark.usefixtures(‘mock_vuforia’)
def test_match_wine():
add_wine(image=blue_nun, name=“Blue Nun”)
add_wine(image=cristal, name=“Cristal”)
result = get_match(image=blue_nun)
assert result.name == ”Blue Nun”
๏ HUMAN ERROR
PROBLEMS WITH MOCKS
๏ HUMAN ERROR
๏ BECOME OUTDATED
PROBLEMS WITH MOCKS
VWS-PYTHON
COMING SOON TO PYPI
GOALS
๏ PYTHON LIBRARY FOR
VUFORIA
๏ MOCK ANYONE CAN USE
TRAVIS CI
๏ FREE FOR OSS
๏ SUPPORT FOR
SECRETS
๏ FREE FOR OSS
๏ SUPPORT FOR
SECRETS
TRAVIS CI
WRITING A
MOCK
VERIFIED FAKE
[A verified fake] is verified against (a
subset of) the same test suite as the
real implementation, as well as
providing an introspection API that
allows test cases to verify that it did
the right thing. — Glyph
VERIFIED FAKE
[A verified fake] is verified against (a
subset of) the same test suite as the
real implementation, as well as
providing an introspection API that
allows test cases to verify that it did
the right thing. — Glyph
VERIFIED FAKE
[A verified fake] is verified against (a
subset of) the same test suite as the
real implementation, as well as
providing an introspection API that
allows test cases to verify that it did
the right thing. — Glyph
VERIFIED FAKE
[A verified fake] is verified against (a
subset of) the same test suite as the
real implementation, as well as
providing an introspection API that
allows test cases to verify that it did
the right thing. — Glyph
VERIFIED FAKE
[A verified fake] is verified against (a
subset of) the same test suite as the
real implementation, as well as
providing an introspection API that
allows test cases to verify that it did
the right thing. — Glyph
VERIFIED FAKE
[A verified fake] is verified against (a
subset of) the same test suite as the
real implementation, as well as
providing an introspection API that
allows test cases to verify that it did
the right thing. — Glyph
PARAMETRIZING PYTEST
FIXTURES
@pytest.fixture(params=[True, False])
def my_fixture(request):
assert request.param
decorated_test[True]PASSED
decorated_test[False]FAILED
@pytest.mark.usefixtures(‘my_fixture’)
def decorated_test():
pass
PARAMETRIZING PYTEST
FIXTURES
@pytest.fixture(params=[True, False])
def my_fixture(request):
assert request.param
decorated_test[True]PASSED
decorated_test[False]FAILED
@pytest.mark.usefixtures(‘my_fixture’)
def decorated_test():
pass
PARAMETRIZING PYTEST
FIXTURES
@pytest.fixture(
params=[True, False],
ids=['Real Vuforia', 'Mock Vuforia'])
def verify_fake_vuforia(request):
use_real_vuforia = request.param
if use_real_vuforia:
yield
else:
pattern = re.compile(‘http://vws.vuforia.com/targets/w+')
with requests_mock.mock() as mock:
mock.post(pattern, text=add_target_to_database)
...
yield
TEST RESULTS
test_add_target.py::test_existing_target_name[Real Vuforia]PASSED
test_add_target.py::test_existing_target_name[Mock Vuforia]PASSED
TEST RESULTS
test_add_target.py::test_existing_target_name[Real Vuforia]PASSED
test_add_target.py::test_existing_target_name[Mock Vuforia]PASSED
๏ WE TRUST THE
MOCK…SO WE TRUST
THE TESTS WHICH USE
THE MOCK
BENEFITS
๏ WE TRUST THE
MOCK…SO WE TRUST
THE TESTS WHICH USE
THE MOCK
BENEFITS
๏ TESTS TELL US IF THE
MOCK IS OUTDATED
BENEFITS
๏ TESTS TELL US IF THE
MOCK IS OUTDATED
BENEFITS
SCHEDULED TESTS
WITH
TRAVIS CI CRON JOBS
SCHEDULED TESTS
WITH
TRAVIS CI CRON JOBS
SCHEDULED TESTS
WITH
TRAVIS CI CRON JOBS
SCHEDULED TESTS
WITH
TRAVIS CI CRON JOBS
WHEN THE
SERVICE
CHANGES
@pytest.mark.usefixtures(‘verify_fake_vuforia’)
def test_zero_width_valid():
data = {
'name': 'example',
'width': 0,
'image': image_data_encoded,
}
response = add_target_to_vws(data=data)
assert_success(response=response)
test_add_target.py::test_zero_width[Real Vuforia]FAILED
test_add_target.py::test_zero_width[Mock Vuforia]PASSED
TEST RESULTS
test_add_target.py::test_zero_width[Real Vuforia]FAILED
test_add_target.py::test_zero_width[Mock Vuforia]PASSED
TEST RESULTS
test_add_target.py::test_zero_width[Real Vuforia]FAILED
test_add_target.py::test_zero_width[Mock Vuforia]PASSED
TEST RESULTS
test_add_target.py::test_zero_width[Real Vuforia]FAILED
test_add_target.py::test_zero_width[Mock Vuforia]PASSED
TEST RESULTS
test_add_target.py::test_zero_width[Real Vuforia]FAILED
test_add_target.py::test_zero_width[Mock Vuforia]PASSED
TEST RESULTS
test_add_target.py::test_zero_width[Real Vuforia]FAILED
test_add_target.py::test_zero_width[Mock Vuforia]PASSED
TEST RESULTS
test_add_target.py::test_zero_width[Real Vuforia]FAILED
test_add_target.py::test_zero_width[Mock Vuforia]PASSED
TEST RESULTS
test_add_target.py::test_zero_width[Real Vuforia]FAILED
test_add_target.py::test_zero_width[Mock Vuforia]PASSED
TEST RESULTS
test_add_target.py::test_zero_width[Real Vuforia]FAILED
test_add_target.py::test_zero_width[Mock Vuforia]PASSED
TEST RESULTS
TEST RESULTS
test_add_target.py::test_zero_width[Real Vuforia]FAILED
test_add_target.py::test_zero_width[Mock Vuforia]PASSED
test_add_target.py::test_zero_width[Real Vuforia]FAILED
test_add_target.py::test_zero_width[Mock Vuforia]PASSED
TEST RESULTS
TEST RESULTS
test_add_target.py::test_zero_width[Real Vuforia]FAILED
test_add_target.py::test_zero_width[Mock Vuforia]PASSED
test_add_target.py::test_zero_width[Real Vuforia]FAILED
test_add_target.py::test_zero_width[Mock Vuforia]PASSED
TEST RESULTS
SHIPPING A VERIFIED
FAKE ADDS VALUE TO
YOUR PRODUCT
SHIPPING A VERIFIED
FAKE ADDS VALUE TO
YOUR PRODUCT
SHIPPING A VERIFIED
FAKE ADDS VALUE TO
YOUR PRODUCT
SHIPPING A VERIFIED
FAKE ADDS VALUE TO
YOUR PRODUCT
SHIPPING A VERIFIED
FAKE ADDS VALUE TO
YOUR PRODUCT
CROSS-
LANGUAGE
SUPPORT
DOCKER
DOCKER
CHEERS
@adamdangoor
adamtheturtle

Adam Dangoor - Verified Fakes of Web Services