minicurso testando restful web services

70
Charles Kilesse @chkile Testando RESTful Web Services

Upload: charles-kilesse

Post on 12-Apr-2017

510 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Minicurso Testando RESTful Web Services

Charles Kilesse@chkile

Testando RESTful Web Services

Page 2: Minicurso Testando RESTful Web Services
Page 3: Minicurso Testando RESTful Web Services

• REST e RESTful web services

• URI

• Métodos

• Estrutura de mensagem HTTP

• Códigos de resposta

• Testes exploratórios com Postman

• Testes automatizados com Python

• Boas práticas em automação

• Autenticação

Agenda

Page 4: Minicurso Testando RESTful Web Services

O que é REST?

Page 5: Minicurso Testando RESTful Web Services

REST“Representational state transfer”

Estilo arquitetural da World Wide Web

Trata de papéis e interações

Comunicação tipicamente por HTTP

Page 6: Minicurso Testando RESTful Web Services

RESTCliente/Servidor

Sem estado

Interface uniforme

Page 7: Minicurso Testando RESTful Web Services

Tá, mas… ondeentram as APIs?

Page 8: Minicurso Testando RESTful Web Services

RESTful Web ServicesUniform Resource Identifier (URI)

Métodos (ou verbos) HTTP

Media type (JSON, XML…)

Sem estado

Page 9: Minicurso Testando RESTful Web Services

URIhttp://chaordic.com.br/

http://chaordic.com.br:80/

http://user:[email protected]/

http://chaordic.com.br/caminho/recurso

Page 10: Minicurso Testando RESTful Web Services

URIhttp://chaordic.com.br/?chave=valor

http://chaordic.com.br/?c=v&c2=v2

http://chaordic.com.br/#fragmento

Page 11: Minicurso Testando RESTful Web Services

Verbos (métodos) HTTP

GET POST PUT DELETE

OPTIONS

HEADCONNECT TRACE

http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

Page 12: Minicurso Testando RESTful Web Services

Verbos (métodos) HTTP

GET POST PUT DELETE

OPTIONS

HEADCONNECT TRACE

http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

este curso

Page 13: Minicurso Testando RESTful Web Services

- Solicita uma representação do recurso especificado.

- Apenas recupera dados!

verbo

GET

Page 14: Minicurso Testando RESTful Web Services

- Envia uma entidade a ser processada.

- Dados da entidade e informações adicionais devem ser enviados no corpo da requisição.

verbo

POST

Page 15: Minicurso Testando RESTful Web Services

- Envia uma entidade a ser armazenada sob uma determinada URI.

- Substitui a entidade, se já existir. Se não existir, cria uma na URI especificada.

verbo

PUT

Page 16: Minicurso Testando RESTful Web Services

- O recurso especificado se fode é deletado.

verbo

DELETE

Page 17: Minicurso Testando RESTful Web Services

Verbos (métodos) HTTP

GET POST PUT DELETE

seguroidempotente

idempotente

idempotente

Page 18: Minicurso Testando RESTful Web Services

VERBO URI

CABEÇALHOS

CORPO

Page 19: Minicurso Testando RESTful Web Services

Mãos à obra!

Page 20: Minicurso Testando RESTful Web Services

http://www.google.com/chrome/https://www.getpostman.com/

Page 21: Minicurso Testando RESTful Web Services

GET http://dummyimage.com/600x400

Page 22: Minicurso Testando RESTful Web Services
Page 23: Minicurso Testando RESTful Web Services

GET http://dummyimage.com/600x400/ff0000/fff

Page 24: Minicurso Testando RESTful Web Services

GET http://dummyimage.com/600x400/ff0000/fff&text=October

Test

Page 25: Minicurso Testando RESTful Web Services

GET http://dummyimage.com/640x400/%%%

Page 26: Minicurso Testando RESTful Web Services

WTF!?

Page 27: Minicurso Testando RESTful Web Services
Page 28: Minicurso Testando RESTful Web Services

HTTP Status CodesInformação: 1xx

Sucesso: 2xxRedirecionamento: 3xx

Erro do Cliente: 4xxErro do Servidor: 5xx

http://www.cheatography.com/kstep/cheat-sheets/http-status-codes/

Page 29: Minicurso Testando RESTful Web Services

GET http://jsonplaceholder.typicode.com/posts/1

Page 30: Minicurso Testando RESTful Web Services

POST http://jsonplaceholder.typicode.com/posts

Content-Type: application/json

{ "title": "Titulo 1", "body": "Body 1", "userID": 1}

Page 31: Minicurso Testando RESTful Web Services
Page 32: Minicurso Testando RESTful Web Services

PUT http://jsonplaceholder.typicode.com/posts/1

Content-Type: application/json

{ "id": 1, "title": "Titulo 1", "body": "Body 1", "userID": 1}

Page 33: Minicurso Testando RESTful Web Services
Page 34: Minicurso Testando RESTful Web Services

DELETE http://jsonplaceholder.typicode.com/posts/1

Page 35: Minicurso Testando RESTful Web Services

#partiuautomação

Page 36: Minicurso Testando RESTful Web Services

https://www.jetbrains.com/pycharm/http://www.python-requests.org/

https://www.python.org/

Page 37: Minicurso Testando RESTful Web Services

import unittestimport requests

class TestCases(unittest.TestCase): pass

if __name__ == "__main__": unittest.main()

Page 38: Minicurso Testando RESTful Web Services

class TestCases(unittest.TestCase): def test_get_200(self): msg="Test not implemented." self.fail(msg)

Page 39: Minicurso Testando RESTful Web Services

def test_get_200(self): uri = "http://apps.testinsane.com/rte/status/200" r = requests.get(uri)

msg = "Incorrect status code: %d" % r.status_code self.assertEqual(r.status_code, 200, msg)

Page 40: Minicurso Testando RESTful Web Services

def test_get_401(self): uri = "http://apps.testinsane.com/rte/status/401" r = requests.get(uri)

msg = "Incorrect status code: %d" % r.status_code self.assertEqual(r.status_code, 401, msg)

Page 41: Minicurso Testando RESTful Web Services

POST

Enviar um payload

Header “content-type”

Validar conteúdo da resposta

Page 42: Minicurso Testando RESTful Web Services

import json

Page 43: Minicurso Testando RESTful Web Services

uri = "http://apps.testinsane.com/rte/status/200"

Page 44: Minicurso Testando RESTful Web Services

headers = { "content-type": "application/json"}

Page 45: Minicurso Testando RESTful Web Services

payload = { "id": "1", "name": "OctoberTest"}

Page 46: Minicurso Testando RESTful Web Services

r = requests.post(uri, data=json.dumps(payload), headers=headers)

Page 47: Minicurso Testando RESTful Web Services

r_payload = r.json()

Page 48: Minicurso Testando RESTful Web Services

msg = "Incorrect status code: %d" % r.status_codeself.assertEqual(r.status_code, 200, msg)

msg = "Incorrect id: %s" % r_payload.get("id")self.assertEqual(r_payload.get("id"), payload.get("id"), msg)

msg = "Incorrect name: %s" % r_payload.get("name")self.assertEqual(r_payload.get("name"), "payload.get("name")", msg)

Page 49: Minicurso Testando RESTful Web Services

def test_post_200(self): uri = "http://apps.testinsane.com/rte/status/200" headers = { "content-type": "application/json" } payload = { "id": "1", "name": "OctoberTest" } r = requests.post(uri, data=json.dumps(payload), headers=headers) r_payload = r.json()

msg = "Incorrect status code: %d" % r.status_code self.assertEqual(r.status_code, 200, msg)

msg = "Incorrect id: %s" % r_payload.get("id") self.assertEqual(r_payload.get("id"), payload.get("id"), msg)

msg = "Incorrect name: %s" % r_payload.get("name") self.assertEqual(r_payload.get("name"), "payload.get("name")", msg)

Page 50: Minicurso Testando RESTful Web Services

E se o host mudar?E se os endpoints mudarem?

Page 51: Minicurso Testando RESTful Web Services

E se a resposta tiver234565639582 chaves?

Page 52: Minicurso Testando RESTful Web Services

MODULARIZAR!

Page 53: Minicurso Testando RESTful Web Services

api_helper.py

import requestsimport json

HOST = "http://apps.testinsane.com/rte%s"

def get(endpoint): uri = HOST % endpoint return requests.get(uri)

def post(endpoint, headers, payload): uri = HOST % endpoint return requests.post(uri, data=json.dumps(payload), headers=headers)

Page 54: Minicurso Testando RESTful Web Services

json_helper.py

import logging

def compare(expected, actual): all_match = True for key, value in expected.iteritems(): if not value==actual.get(key): all_match = False return all_match

* E se o valor de uma chave for uma lista ou objeto?

Page 55: Minicurso Testando RESTful Web Services

import api_helperimport json_helper

class TestCases(unittest.TestCase): def test_get_200(self): r = api_helper.get("/status/200") msg = "Incorrect status code: %d" % r.status_code self.assertEqual(r.status_code, 200, msg)

Page 56: Minicurso Testando RESTful Web Services

msg = "Response payload did not match the request payload."

self.assertTrue(json_helper.compare(payload, r_payload), msg)

Page 57: Minicurso Testando RESTful Web Services

BOAS PRÁTICAS!

Page 58: Minicurso Testando RESTful Web Services

Organizando os testes com o padrão “3 As”

Page 59: Minicurso Testando RESTful Web Services

def test_get_200(self): # Arrange endpoint = "/status/200" # Act r = api_helper.get(endpoint) # Assert msg = "Incorrect status code: %d" % r.status_code self.assertEqual(r.status_code, 200, msg)

Page 60: Minicurso Testando RESTful Web Services

Funcional x Estruturallogin(username, password)

ou

login_as(user)

enter_name(username)

enter_password(password)

click_login()

Page 61: Minicurso Testando RESTful Web Services

Use “lint checkers”!(PEP8: Style Guide for Python Code)

Page 62: Minicurso Testando RESTful Web Services

Código de teste entrega valor e deve ser tratado como “código de produção”

Page 63: Minicurso Testando RESTful Web Services

YAGNI, DRY and KISS whenever you can!

Page 64: Minicurso Testando RESTful Web Services

AUTENTICAÇÃO

Page 65: Minicurso Testando RESTful Web Services

Basic AuthenticationAutenticação simples (cabeçalhos

estáticos)

Encoding em Base64 durante a trasnferência

Não criptografado

Page 66: Minicurso Testando RESTful Web Services

Digest Access Authentication

Aplica hash MD5 nas credenciais

Mais seguro que Basic Auth

Page 67: Minicurso Testando RESTful Web Services

OAuthBaseado na criação de “tokens” de

acesso para clientes terceiros

Aplicativos acessando sua conta do Facebook ou CI SAAS acessando um

repositório no GitHub, por exemplo

Page 68: Minicurso Testando RESTful Web Services

from requests.auth import HTTPBasicAuth

basic_auth = HTTPBasicAuth('user', 'pass')

requests.get('https://api.github.com/user', auth=basic_auth)

from requests.auth import HTTPDigestAuth

digest_auth = HTTPDigestAuth('user', 'pass')

from requests_oauthlib import OAuth1

oauth = OAuth1('YOUR_APP_KEY', 'YOUR_APP_SECRET',

'USER_OAUTH_TOKEN',

'USER_OAUTH_TOKEN_SECRET')

http://docs.python-requests.org/en/latest/user/authentication/

Page 69: Minicurso Testando RESTful Web Services

Links e referênciashttps://github.com/chkile/minicurso-octobertest

http://www.w3.org/Protocols/

http://docs.python-requests.org/en/latest/

https://www.python.org/dev/peps/pep-0008/