TDD of Python Microservices. Michał Bultrowicz

Similar documents
Cloud-Native Applications. Copyright 2017 Pivotal Software, Inc. All rights Reserved. Version 1.0

The 12-Factor app and IBM Bluemix IBM Corporation

gcp / gke / k8s microservices

12 Factors to Cloud Success. Rafael Benevides

Heroku. Rimantas Kybartas

Copyright 2016 Pivotal. All rights reserved. Cloud Native Design. Includes 12 Factor Apps

Building Microservices with the 12 Factor App Pattern

DESIGNING APPLICATIONS FOR CONTAINERIZATION AND THE CLOUD THE 12 FACTOR APPLICATION MANIFESTO

Implementing the Twelve-Factor App Methodology for Developing Cloud- Native Applications

Cloud Native Applications. 主讲人 :Capital One 首席工程师 Kevin Hoffman

Developer Experience with. Spencer Gibb, Dave Syer, Spring Cloud

Continuous Testing at Scale

12 (15) Factor App Workshop

Microservice Splitting the Monolith. Software Engineering II Sharif University of Technology MohammadAmin Fazli

Connexion Documentation

Consumer Driven Contract Testing with Pact and Docker. By Harry

Testing Microservices Techniques for Automation

Cloud Computing design patterns blueprints

The Future of the Realtime Web BETTER APIS WITH GRAPHQL. Josh

pistahx type safe, design first, haxe web api by Emmanuel BOTROS YOUSSEF / mebyz

3 Continuous Integration 3. Automated system finding bugs is better than people

Achieving Continuous Delivery - Micro Services. - Vikram Gadang

Using Swagger to tame HTTP/JSON interfaces. John Billings

Java Architectures A New Hope. Eberhard Wolff

The age of orchestration

Docker at Lyft Speeding up development Matthew #dockercon

Lab Exercise Test First using JUnit

PARTLY CLOUDY DESIGN & DEVELOPMENT OF A HYBRID CLOUD SYSTEM

Managing Data at Scale: Microservices and Events. Randy linkedin.com/in/randyshoup

Python Development Workflow

CSE 374 Programming Concepts & Tools. Hal Perkins Fall 2015 Lecture 15 Testing

DISQUS. Continuous Deployment Everything. David

what's in it for me? Ian Truslove :: Boulder Linux User Group ::

Microservices. SWE 432, Fall 2017 Design and Implementation of Software for the Web

Plorma Documentation. Release 0.4. Torsten Irländer

An introduction API testing with SoapUI

Python Unit Testing and CI Workflow. Tim Scott, Python Meetup 11/07/17

IBMi in the IT infrastructure of tomorrow

Deployability. of Python. web applications

A bit more on Testing

Engineering Robust Server Software

Pontoon An Enterprise grade serverless framework using Kubernetes Kumar Gaurav, Director R&D, VMware Mageshwaran R, Staff Engineer R&D, VMware

PyBuilder Documentation

Archan. Release 2.0.1

Testing My Patience. Automated Testing for Python Projects. Adam Lowry Portland Python Users Group

Django, from nightmare to dream

Docker 101 Workshop. Eric Smalling - Solution Architect, Docker

Unit Testing In Python

Welcome to Docker Birthday # Docker Birthday events (list available at Docker.Party) RSVPs 600 mentors Big thanks to our global partners:

STARCOUNTER. Technical Overview

Unit testing basics & more...

cwmon-mysql Release 0.5.0

The Post-Cloud. Where Google, DevOps, and Docker Converge

Real Life Web Development. Joseph Paul Cohen

Implementation of Synchronizers

Unit testing in CakePHP. Making bullet resistant code.

BaasBox. Open Source Backend as a Service. Otto Hylli

Reconstructive API for the DOM

Test Driven Development (TDD), and Working with Legacy Code Using C# Workshop ( 4 days)

Extract API: Build sophisticated data models with the Extract API

Hi! NET Developer Group Braunschweig!

Continuous Delivery for Python Developers PyCon 8, 2017

Armon HASHICORP

CSE 15L Winter Midterm :) Review

By Philip Japikse MVP, MCSD.Net, MCDBA, CSM Principal Consultant Pinnacle Solutions Group

Writing REST APIs with OpenAPI and Swagger Ada

Distributed CI: Scaling Jenkins on Mesos and Marathon. Roger Ignazio Puppet Labs, Inc. MesosCon 2015 Seattle, WA

Documenting APIs with Swagger. TC Camp. Peter Gruenbaum

Backend Development. SWE 432, Fall Web Application Development

Docker for Sysadmins: Linux Windows VMware

CONTAINER CLOUD SERVICE. Managing Containers Easily on Oracle Public Cloud

Serverless Architecture meets Continuous Delivery. Andreas

Credit where Credit is Due. Lecture 29: Test-Driven Development. Test-Driven Development. Goals for this lecture

Test-driven development

Ra Documentation. Release. Brandicted

Test First Software Development

MODERN WEB APPLICATION DEFENSES

Inverting the Pyramid

Principles of Software Construction: Testing: One, Two, Three

monolith to micro-services? event sourcing can help Doug

How to re-invent your IT Architecture. André Christ, Co-CEO LeanIX

Continuous Integration / Continuous Testing

Microservices Architekturen aufbauen, aber wie?

Reactive Programming Models for IoT. Todd L.

TIPS AND TRICKS: DOMINO AND JAVASCRIPT DEVELOPMENT MASTERCLASS

Excel on the Java VM. Generating Fast Code from Spreadsheet Models. Peter Arrenbrecht codewise.ch / Abacus Research AG Submission ID: 30

Software Engineering /48

Understanding and Documenting Web APIs

CISC-124. Casting. // this would fail because we can t assign a double value to an int // variable

SYMFONY2 WEB FRAMEWORK

The one bit everyone forgets: with JUnit. John Stegeman Xchanging

Test suites Obviously you have to test your code to get it working in the first place You can do ad hoc testing (testing whatever occurs to you at

Broken Promises.

Microservices Beyond the Hype. SATURN San Diego May 3, 2016 Paulo Merson

CADEC 2016 MICROSERVICES AND DOCKER CONTAINERS MAGNUS LARSSON

ANALYZING THE MOST COMMON PERFORMANCE AND MEMORY PROBLEMS IN JAVA. 18 October 2017

Distributed Architectures & Microservices. CS 475, Spring 2018 Concurrent & Distributed Systems

From LLD to SuperDiscovery

CS 162 Operating Systems and Systems Programming Professor: Anthony D. Joseph Spring Lecture 21: Network Protocols (and 2 Phase Commit)

USING DOCKER FOR MXCUBE DEVELOPMENT AT MAX IV

Transcription:

TDD of Python Microservices Michał Bultrowicz

About me Name: Michał Bultrowicz Previous employers: Intel that s the full list Previous occupation: technical team-leader on Trusted Analytics Platform project Current Occupation: N/A Website : https://github.com/butla (...working on a blog...)

Microservices: - services - micro - independent - cooperating

Twelve-Factor App (http://12factor.net/) 1. One codebase tracked in revision control, many deploys 2. Explicitly declare and isolate dependencies 3. Store config in the environment 4. Treat backing services as attached resources 5. Strictly separate build and run stages 6. Execute the app as one or more stateless processes 7. Export services via port binding 8. Scale out via the process model 9. Maximize robustness with fast startup and graceful shutdown 10. Keep development, staging, and production as similar as possible 11. Treat logs as event streams 12. Run admin/management tasks as one-off processes

Word of advice Start with a monolith. Separating out microservices should be natural.

TESTS!

Tests Present in my service (around 85% coverage). Sometimes convoluted. Didn t ensure that the service will even get up.

UNIT tests Present in my service (around 85% coverage). Sometimes convoluted. Didn t ensure that the service will even get up

Tests of the entire application! Run the whole app s process. App doesn t know it s not in production. Run locally, before a commit. High confidence that the app will get up....require external services and data bases...

External services locally? Service mocks (and stubs): WireMock Pretenders (Python) Mountebank

Data bases (and other systems) locally? Normally - a tiresome setup Verified Fakes - rarely seen Docker - just create everything you need

Now some theory

http://martinfowler.com/articles/microservice-testing/#conclusion-test-pyramid

Harry J.W. Percival, Test Driven Development with Python

TDD (the thing I needed!) Pros: Confidence in face of changes. Automation checks everything. Ward off bad design. Requirements: Discipline Tools

Implementation

PyDAS A rewrite of an old, problematic (Java) service. My guinea pig. TDD helped a lot....not perfect, but educating https://github.com/butla/pydas

Pytest Concise Clear composition of fixtures Control of this composition (e.g. for reducing test duration) Helpful error reports

def test_something(our_service, db): db.put(test_db_entry) response = requests.get( our_service.url + '/something', headers={'authorization': TEST_AUTH_HEADER}) assert response.status_code == 200

import pytest, redis @pytest.yield_fixture(scope='function') def db(db_session): yield db_session db_session.flushdb() @pytest.fixture(scope='session') def db_session(redis_port): return redis.redis(port=redis_port, db=0)

import docker, pytest @pytest.yield_fixture(scope='session') def redis_port(): docker_client = docker.client(version='auto') download_image_if_missing(docker_client) container_id, redis_port = start_redis_container(docker_client) yield redis_port docker_client.remove_container(container_id, force=true)

@pytest.fixture(scope='function') def our_service(our_service_session, ext_service_impostor): return our_service

Mountepy Manages a Mountebank instance. Manages service processes. https://github.com/butla/mountepy $ pip install mountepy

import mountepy @pytest.yield_fixture(scope='session') def our_service_session(): service_command = [ WAITRESS_BIN_PATH, '--port', '{port}', '--call', 'data_acquisition.app:get_app'] service = mountepy.httpservice( service_command, env={ 'SOME_CONFIG_VALUE': 'blabla', 'PORT': '{port}', 'PYTHONPATH': PROJECT_ROOT_PATH}) service.start() yield service service.stop()

@pytest.yield_fixture(scope='function') def ext_service_impostor(mountebank): impostor = mountebank.add_imposter_simple( port=ext_serv_stub_port, path=ext_serv_path, method='post') yield impostor impostor.destroy() @pytest.yield_fixture(scope='session') def mountebank(): mb = Mountebank() mb.start() yield mb mb.stop()

Service test(s) ready!

Remarks about service tests Will yield big error logs. Breaking a fixture yields crazy logs. Won t save us from stupidity (e.g. hardcoded localhost)

The danger of other people s commits

Our weapons Test coverage Static analysis (pylint, pyflakes, etc.) Contract tests

.coveragerc (from PyDAS) [report] fail_under = 100 [run] source = data_acquisition parallel = true http://coverage.readthedocs.io/en/coverage-4.0.3/subprocess.html

Static analysis tox.ini (simplified) [testenv] commands = coverage run -m py.test tests/ coverage report -m /bin/bash -c "pylint data_acquisition --rcfile=.pylintrc" https://tox.readthedocs.io

Contract tests: a leash for the interface

swagger: '2.0' info: http://swagger.io/ version: "0.0.1" title: Some interface paths: /person/{id}: get: parameters: Contract is separate from the code! - name: id in: path required: true type: string format: uuid responses: '200': description: Successful response schema: title: Person type: object properties: name: type: string single: type: boolean

Bravado (https://github.com/yelp/bravado) Creates service client from Swagger Verifies Parameters Returned values Returned HTTP codes Configurable (doesn t have to be as strict)

Bravado usage In service tests: instead of requests In unit tests: https://github.com/butla/bravado-falcon Now they all double as contract tests

from bravado.client import SwaggerClient from bravado_falcon import FalconHttpClient import yaml import tests # our tests package def test_contract_unit(swagger_spec): client = SwaggerClient.from_spec( swagger_spec, http_client=falconhttpclient(tests.service.api)) resp_object = client.v1.submitoperation( body={'name': 'make_sandwich', 'repeats': 3}, worker='mom').result() assert resp_object.status == 'whatever' @pytest.fixture() def swagger_spec(): with open('api_spec.yaml') as spec_file: return yaml.load(spec_file)

def test_contract_service(swagger_spec, our_service): client = SwaggerClient.from_spec( swagger_spec, origin_url=our_service.url)) request_options = { 'headers': {'authorization': A_VALID_TOKEN}, } resp_object = client.v1.submitoperation( body={'name': 'make_sandwich', 'repeats': 3}, worker='mom', _request_options=requet_options).result() assert resp_object.status == 'whatever'

Our stuff is taken care of...

???

More about tests / microservices / stuff Building Microservices, O'Reilly Test Driven Development with Python http://martinfowler.com/articles/microservice-testing/ Fast test, slow test (https://youtu.be/raxiirphs9k) Building Service interfaces with OpenAPI / Swagger (EP2016) System Testing with pytest and docker-py (EP2016)