SlideShare uma empresa Scribd logo
1 de 40
Globalcode – Open4education
Garantindo a qualidade da sua API
REST com Behave
Alex S. Garzão
Projetista de Software
Yuri Z. Pinheiro
Analista de Qualidade
ZAP Imóveis
www.linkedin.com/in/alexgarzao/ www.linkedin.com/in/yurizp
Globalcode – Open4education
Agenda
• Nosso contexto
• Projeto, desafios, problemas e soluções
• O que é BDD
• O que é Behave
• Nossa proposta
• Demonstração
• Resultados
• Lições aprendidas
• Próximos passos
Globalcode – Open4education
Vamos nos conhecer
• Testes automatizados. Quem aqui utiliza?
• BDD. Quem conhece? Quem utiliza?
• Behave. Quem conhece? Quem utiliza?
Globalcode – Open4education
Nosso contexto no ZAP
• Desenvolvemos API RESTful
• Python
• Django
• MySQL
Globalcode – Open4education
Primeiros desafios
• Regras de negócio instáveis
• Definição do escopo em andamento
• Entendimento do projeto não era claro
• Novas tecnologias na empresa
Globalcode – Open4education
O que isso ocasionou?
• Baixa qualidade de código (Bugs a rodo)
• Retrabalho do time
• Time desmotivado
Globalcode – Open4education
Qual a solução?
• Testes, obviamente
• Começamos com testes manuais
• Mas isso não escala
• Tester virou gargalo da equipe
• Vamos automatizar :-)
Globalcode – Open4education
Em busca de soluções
● Aplicação em Python
○ É possível, mas partiríamos do zero :-/
● Curl
○ Fácil para testes pontuais
● Postman
○ Legal, mas a automação dele é trabalhosa
● Robot framework
○ Técnico demais
● Lettuce
○ Legal, mas foi descontinuado
● Behave
Globalcode – Open4education
O que é o BDD?
• Técnica de desenvolvimento ágil
• Encoraja interação entre técnicos e “não técnicos”
• Foco no negócio, e não nos detalhes técnicos
• Exemplos descrevem o comportamento da
aplicação
• São executáveis (documentação viva)
• São testes regressivos
Globalcode – Open4education
Fluxo com BDD
Fonte: http://www.qualister.com.br/blog/o-que-e-atdd---acceptance-test-driven-development
Globalcode – Open4education
O que é o Behave?
• Utilizado para a prática de automação de testes
• Open source
• Suporte para BDD em Python
• Permite a escrita de cenários de teste
• Linguagem próxima a “natural”
Globalcode – Open4education
Exemplo Behave - Calcular fatorial
Funcionalidade: Calcular o fatorial
Cenário: Fatorial de 0
Dado eu tenho o número 0
Quando eu calculo este fatorial
Então eu vejo o número 1
Cenário: Fatorial de 2
Dado eu tenho o número 2
Quando eu calculo este fatorial
Então eu vejo o número 2
Cenário: Fatorial de 4
Dado eu tenho o número 4
Quando eu calculo este fatorial
Então eu vejo o número 24
Globalcode – Open4education
Funcionalidade: Calcular o fatorial
Cenário: Fatorial de 0
Dado eu tenho o número 0
Quando eu calculo este fatorial
Então eu vejo o número 1
@given(u'eu tenho o número {number}')
def step_impl(context, number):
context.number = int(number)
@when(u'eu calculo este fatorial')
def step_impl(context):
context.number = factorial(context.number)
@then(u'eu vejo o número {expected}')
def step_impl(context, expected):
expected = int(expected)
assert context.number == expected
Globalcode – Open4education
• Métodos de uma API Rest
• Exemplo: Rota para cadastro de imóveis
• Endpoint: https://api.meusite.com/imoveis
• JSON: {
proprietario: "fulano de tal",
endereco: "Rua A, 520",
valor: 450000
}
O que queríamos testar?
Globalcode – Open4education
Oh shit!
• Behave é uma ferramenta genérica
• Não entende API RESTful
• HTTP? JSON? GET/POST/PUT/DELETE?
• Endpoint? Request? HTTP status code?
Globalcode – Open4education
Nossa proposta...
• Ferramenta open source
• Utilizando o Behave
• Permite a escrita de testes automatizados
• Entende o que é uma API RESTful
• Cenários de testes são executáveis
• Escritos em português
Globalcode – Open4education
Tentativa 1 - O início de tudo...
Globalcode – Open4education
Esquema do Cenário: Como usuário tento cadastrar imóveis
Dado que eu quero cadastrar um imóvel
E o proprietário é <nome> e o endereço é <endereço> e o
valor é <valor>
Quando eu tento cadastrar o imóvel
Então eu recebo o código 200
Exemplos: Dados válidos para imóveis
| nome | endereço | valor |
| Proprietário 01 | Rua A POA RS | 1000.00 |
| Proprietário 02 | Rua B POA RS | 2000.00 |
• Step confuso de entender
• Steps muito específicos
• Reutilização engessada
• A cada novo step, uma nova implementação
Globalcode – Open4education
Tentativa 2
Globalcode – Open4education
Esquema do Cenário: Como usuário tento cadastrar imóveis
Dado que eu quero cadastrar um imóvel
E o proprietário é <nome>
E o endereço é <endereço>
E o valor é <valor>
Quando eu tento cadastrar o imóvel
Então eu recebo o código 200
Exemplos: Dados válidos para imóveis
| nome | endereço | valor |
| Proprietário 01 | Rua A POA RS | 1000.00 |
| Proprietário 02 | Rua B POA RS | 2000.00 |
• Maior reutilização :-)
• Melhor legibilidade
• A cada novo step uma nova implementação :-(
Globalcode – Open4education
Hoje - Steps genéricos
Globalcode – Open4education
Esquema do Cenário: Como usuário quero cadastrar imóveis
Dado que eu quero cadastrar um imóvel
E o campo nome do proprietário é <nome>
E o campo endereço do imóvel é <endereço>
E o campo valor do imóvel é <valor>
Quando eu tento cadastrar o imóvel
Então eu recebo o status que indica imóvel criado
Exemplos: Dados válidos para imóveis
| nome | endereço | valor |
| Proprietário 01 | Rua A POA RS | 1000.00 |
| Proprietário 02 | Rua B POA RS | 2000.00 |
• Não temos mais steps específicos por campo
• Utilizamos alias (apelidos) para campos, códigos de status,
endpoints, ...
Globalcode – Open4education
Como são definidos os “alias”?
Globalcode – Open4education
Esquema do Cenário: Mapeando os campos do JSON
Dado que eu quero mapear os campos do JSON
E o campo <alias> é <tipo> e corresponde a <campo>
Quando eu tento mapear os campos
Então nenhuma falha ocorre
Exemplos: Campos do método de imóveis
| alias | tipo | campo |
| nome do proprietário | string | proprietario |
| endereço do imóvel | string | endereco |
| valor do imóvel | number | valor |
• É fácil criar novos campos
• Fazer manutenção (trocar tipo, nome no JSON, …)
• Independência na criação de cenários
• Técnicos e não técnicos
Globalcode – Open4education
E listas?
Globalcode – Open4education
Cenário: Como usuário quero listar meus imóveis
Dado que eu quero listar os meus imóveis
Quando eu busco a lista de imóveis
Então eu recebo o status que indica requisição válida
E obtenho a lista de dados abaixo
| nome do proprietário | endereço do imóvel |
| Proprietário 01 | Rua A POA RS |
| Proprietário 02 | Rua B POA RS |
• Validamos tipagem
• Validamos só os campos necessários
• Onde está o valor?
Globalcode – Open4education
E dados não previsíveis?
Globalcode – Open4education
Cenário: Como usuário quero listar meus imóveis
Dado que eu quero listar os meus imóveis
Quando eu busco a lista de imóveis
Então eu recebo o status que indica requisição válida
E obtenho a lista de dados abaixo
| nome do proprietário | data e hora criação |
| Proprietário 01 | <nao nulo> |
| Proprietário 02 | <nao nulo> |
• Temos outros tipos de validações
• <nao vazio>
• <nulo>
• <vazio> ou “”
• Não temos validações complexas
• > 20, < 100, ...
Globalcode – Open4education
Como enviamos nulo e vazio em
requisições?
Globalcode – Open4education
Esquema do Cenário: Como usuário quero cadastrar imóveis
Dado que eu quero cadastrar um imóvel
E o campo nome do proprietário é <nome>
E o campo endereço do imóvel é <endereço>
E o campo valor do imóvel é <valor>
Quando eu tento cadastrar o imóvel
Então eu recebo o status que indica imóvel criado
Exemplos: Dados válidos para imóveis
| nome | endereço | valor |
| Proprietário 01 | Rua A POA RS | <nulo> |
| Proprietário 02 | <vazio> | 250000 |
| Proprietário 03 | “ A B C ” | 350000 |
Globalcode – Open4education
E quando precisamos de dados
variáveis?
Globalcode – Open4education
Esquema do Cenário: Como usuário quero cadastrar imóveis
Dado que eu quero cadastrar um imóvel
E o campo nome do proprietário é <nome>
E o campo endereço do imóvel é <endereço>
E o campo valor do imóvel é <valor>
Quando eu tento cadastrar o imóvel
Então eu recebo o status que indica imóvel criado
E guardo o retorno em <variável>
Exemplos: Dados válidos para imóveis
| nome | endereço | valor | variável |
| Proprietário 01 | Rua A POA RS | 150000 | imóvel 01 |
| Proprietário 02 | Rua B POA RS | 250000 | imóvel 02 |
• Permite reutilização de dados não previsíveis em outros
cenários
Globalcode – Open4education
Cenário: Como usuário quero listar meus imóveis
Dado que eu quero listar os meus imóveis
Quando eu busco a lista de imóveis
Então eu recebo o status que indica requisição válida
E obtenho a lista de dados abaixo
| nome do proprietário | endereço do imóvel |
| $imóvel 01.nome do proprietário | Rua A POA RS |
| $imóvel 02.nome do proprietário | Rua B POA RS |
• Variáveis podem ser utilizadas em qualquer step
• Podemos acessar qualquer campo do JSON
Globalcode – Open4education
Demonstração
Globalcode – Open4education
Resultados
• Fomos
• De poucos testes manuais para 90% de cobertura
(testes automatizados)
• Ganho de tempo
• Temos testes sendo executados a todo momento
• Para cada novo bug temos um cenário de teste
• Facilidade em desenvolver novos testes
Globalcode – Open4education
Resultados
• Confiança na qualidade
• Confiança para realizar alterações críticas
• Qualquer pessoa, técnica ou não, consegue
desenvolver novos cenários
Globalcode – Open4education
Lições aprendidas
• Tempo para girar a roda é alto
• Dependência de API’s externas? Mock
• Setup dos dados no início dos testes
• Criar o banco, inserir dados de configuração, ...
• Não usar dados fictícios
• Rodar os testes em homologação
• Em produção é um plus
• Feature deve ser independente
• Cenário independente melhor ainda!
Globalcode – Open4education
Próximos passos
• Pacote instalável via pip
• Disseminar o BDD
• Mande sua sugestão :-)
Globalcode – Open4education
Referências
• Livro BDD in Action:
https://www.manning.com/books/bdd-in-action
• Projeto: https://github.com/alexgarzao/victory
• Behave: http://pythonhosted.org/behave/
Globalcode – Open4education
Perguntas?

Mais conteúdo relacionado

Mais procurados

Integrando sua App ao Mundo via REST/JSON
Integrando sua App ao Mundo via REST/JSONIntegrando sua App ao Mundo via REST/JSON
Integrando sua App ao Mundo via REST/JSONMario Guedes
 
Send Sms with SmsManager Api In Android with Kotlin
Send Sms with SmsManager Api In Android with KotlinSend Sms with SmsManager Api In Android with Kotlin
Send Sms with SmsManager Api In Android with KotlinShahRushika
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous JavascriptGarrett Welson
 
RESTful API Design Best Practices Using ASP.NET Web API
RESTful API Design Best Practices Using ASP.NET Web APIRESTful API Design Best Practices Using ASP.NET Web API
RESTful API Design Best Practices Using ASP.NET Web API💻 Spencer Schneidenbach
 
Go micro framework to build microservices
Go micro framework to build microservicesGo micro framework to build microservices
Go micro framework to build microservicesTechMaster Vietnam
 
React + Redux + TypeScript === ♥
React + Redux + TypeScript === ♥React + Redux + TypeScript === ♥
React + Redux + TypeScript === ♥Remo Jansen
 
Spring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. RESTSpring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. RESTSam Brannen
 
The Art of Discovering Bounded Contexts
The Art of Discovering Bounded ContextsThe Art of Discovering Bounded Contexts
The Art of Discovering Bounded ContextsNick Tune
 
Software architecture for high traffic website
Software architecture for high traffic websiteSoftware architecture for high traffic website
Software architecture for high traffic websiteTung Nguyen Thanh
 
Test your microservices with REST-Assured
Test your microservices with REST-AssuredTest your microservices with REST-Assured
Test your microservices with REST-AssuredMichel Schudel
 
Non blocking io with netty
Non blocking io with nettyNon blocking io with netty
Non blocking io with nettyZauber
 

Mais procurados (20)

Html5 for mobiles
Html5 for mobilesHtml5 for mobiles
Html5 for mobiles
 
Integrando sua App ao Mundo via REST/JSON
Integrando sua App ao Mundo via REST/JSONIntegrando sua App ao Mundo via REST/JSON
Integrando sua App ao Mundo via REST/JSON
 
Send Sms with SmsManager Api In Android with Kotlin
Send Sms with SmsManager Api In Android with KotlinSend Sms with SmsManager Api In Android with Kotlin
Send Sms with SmsManager Api In Android with Kotlin
 
Xampp Ppt
Xampp PptXampp Ppt
Xampp Ppt
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
 
PHP Basic & Variables
PHP Basic & VariablesPHP Basic & Variables
PHP Basic & Variables
 
RESTful API Design Best Practices Using ASP.NET Web API
RESTful API Design Best Practices Using ASP.NET Web APIRESTful API Design Best Practices Using ASP.NET Web API
RESTful API Design Best Practices Using ASP.NET Web API
 
Go micro framework to build microservices
Go micro framework to build microservicesGo micro framework to build microservices
Go micro framework to build microservices
 
React + Redux + TypeScript === ♥
React + Redux + TypeScript === ♥React + Redux + TypeScript === ♥
React + Redux + TypeScript === ♥
 
RESTful Web Services
RESTful Web ServicesRESTful Web Services
RESTful Web Services
 
Spring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. RESTSpring Web Services: SOAP vs. REST
Spring Web Services: SOAP vs. REST
 
Bizweb Microservices Architecture
Bizweb Microservices ArchitectureBizweb Microservices Architecture
Bizweb Microservices Architecture
 
Hexagonal architecture in PHP
Hexagonal architecture in PHPHexagonal architecture in PHP
Hexagonal architecture in PHP
 
The Art of Discovering Bounded Contexts
The Art of Discovering Bounded ContextsThe Art of Discovering Bounded Contexts
The Art of Discovering Bounded Contexts
 
Protocol Buffer.ppt
Protocol Buffer.pptProtocol Buffer.ppt
Protocol Buffer.ppt
 
Maven
MavenMaven
Maven
 
Software architecture for high traffic website
Software architecture for high traffic websiteSoftware architecture for high traffic website
Software architecture for high traffic website
 
Test your microservices with REST-Assured
Test your microservices with REST-AssuredTest your microservices with REST-Assured
Test your microservices with REST-Assured
 
Non blocking io with netty
Non blocking io with nettyNon blocking io with netty
Non blocking io with netty
 
RESTful API - Best Practices
RESTful API - Best PracticesRESTful API - Best Practices
RESTful API - Best Practices
 

Semelhante a Garantindo a qualidade da sua API REST com Behave

TDC2016SP - Trilha Banco de Dados
TDC2016SP - Trilha Banco de DadosTDC2016SP - Trilha Banco de Dados
TDC2016SP - Trilha Banco de Dadostdc-globalcode
 
InfluxDb: como monitorar milhares de dados por segundo em real time
InfluxDb: como monitorar milhares de dados por segundo em real time InfluxDb: como monitorar milhares de dados por segundo em real time
InfluxDb: como monitorar milhares de dados por segundo em real time Umbler
 
Tdc2016 trilha-banco-influx.ppt
Tdc2016 trilha-banco-influx.pptTdc2016 trilha-banco-influx.ppt
Tdc2016 trilha-banco-influx.pptMarcos Artigas
 
fortaleza-gp16-pmo-cognitivo
fortaleza-gp16-pmo-cognitivofortaleza-gp16-pmo-cognitivo
fortaleza-gp16-pmo-cognitivoMarco Coghi
 
[GUTS-RS] GUTS Testing Games - Jogo BDD Warriors
[GUTS-RS] GUTS Testing Games - Jogo BDD Warriors[GUTS-RS] GUTS Testing Games - Jogo BDD Warriors
[GUTS-RS] GUTS Testing Games - Jogo BDD WarriorsGUTS-RS
 
GraphQL e APIs: como manter a qualidade?
GraphQL e APIs: como manter a qualidade?GraphQL e APIs: como manter a qualidade?
GraphQL e APIs: como manter a qualidade?Qaladies
 
Introdução ao Solr e Faceted Search
Introdução ao Solr e Faceted SearchIntrodução ao Solr e Faceted Search
Introdução ao Solr e Faceted SearchMichel Bottan
 
Cross testing mobile com ruby, cucumber e appium
Cross testing mobile com ruby, cucumber e appiumCross testing mobile com ruby, cucumber e appium
Cross testing mobile com ruby, cucumber e appiumMaximiliano Alves
 
QArentena 21: BDD - com Fábio Araújo
QArentena 21: BDD - com Fábio AraújoQArentena 21: BDD - com Fábio Araújo
QArentena 21: BDD - com Fábio AraújoJosé Correia
 
TDC2016SP - O bê-a-bá da fila de processamento para você deixar o ThreadPool ...
TDC2016SP - O bê-a-bá da fila de processamento para você deixar o ThreadPool ...TDC2016SP - O bê-a-bá da fila de processamento para você deixar o ThreadPool ...
TDC2016SP - O bê-a-bá da fila de processamento para você deixar o ThreadPool ...tdc-globalcode
 
Javascript para CSharpers 4 - POO
Javascript para CSharpers 4 - POOJavascript para CSharpers 4 - POO
Javascript para CSharpers 4 - POOWesley Lemos
 
Semana da Mulher na Tecnologia_Introducao ao Bdd
Semana da Mulher na Tecnologia_Introducao ao BddSemana da Mulher na Tecnologia_Introducao ao Bdd
Semana da Mulher na Tecnologia_Introducao ao BddinovacaoDBServer
 
Implementando um Handler de Autenticação Customizado no ASP.NET Core 2.0
Implementando um Handler de Autenticação Customizado no ASP.NET Core 2.0Implementando um Handler de Autenticação Customizado no ASP.NET Core 2.0
Implementando um Handler de Autenticação Customizado no ASP.NET Core 2.0Robson Rocha de Araújo
 
Testes de contrato em um contexto de services e microservices tdc-poa2016
Testes de contrato em um contexto de services e microservices tdc-poa2016Testes de contrato em um contexto de services e microservices tdc-poa2016
Testes de contrato em um contexto de services e microservices tdc-poa2016Bruno Tanoue
 
TDC2016POA | Trilha Ruby - Testes de contrato em um contexto de services e mi...
TDC2016POA | Trilha Ruby - Testes de contrato em um contexto de services e mi...TDC2016POA | Trilha Ruby - Testes de contrato em um contexto de services e mi...
TDC2016POA | Trilha Ruby - Testes de contrato em um contexto de services e mi...tdc-globalcode
 
TDC2016SP - Trilha BigData
TDC2016SP - Trilha BigDataTDC2016SP - Trilha BigData
TDC2016SP - Trilha BigDatatdc-globalcode
 
TDC2016POA | Trilha DevOps - Gestão de ciclo de vida de banco de dados: Já pa...
TDC2016POA | Trilha DevOps - Gestão de ciclo de vida de banco de dados: Já pa...TDC2016POA | Trilha DevOps - Gestão de ciclo de vida de banco de dados: Já pa...
TDC2016POA | Trilha DevOps - Gestão de ciclo de vida de banco de dados: Já pa...tdc-globalcode
 
Utilizando a API do Roslyn, o novo compilador do C#
Utilizando a API do Roslyn, o novo compilador do C#Utilizando a API do Roslyn, o novo compilador do C#
Utilizando a API do Roslyn, o novo compilador do C#Paulo Cesar Ortins Brito
 

Semelhante a Garantindo a qualidade da sua API REST com Behave (20)

TDC2016SP - Trilha Banco de Dados
TDC2016SP - Trilha Banco de DadosTDC2016SP - Trilha Banco de Dados
TDC2016SP - Trilha Banco de Dados
 
InfluxDb: como monitorar milhares de dados por segundo em real time
InfluxDb: como monitorar milhares de dados por segundo em real time InfluxDb: como monitorar milhares de dados por segundo em real time
InfluxDb: como monitorar milhares de dados por segundo em real time
 
Tdc2016 trilha-banco-influx.ppt
Tdc2016 trilha-banco-influx.pptTdc2016 trilha-banco-influx.ppt
Tdc2016 trilha-banco-influx.ppt
 
fortaleza-gp16-pmo-cognitivo
fortaleza-gp16-pmo-cognitivofortaleza-gp16-pmo-cognitivo
fortaleza-gp16-pmo-cognitivo
 
[GUTS-RS] GUTS Testing Games - Jogo BDD Warriors
[GUTS-RS] GUTS Testing Games - Jogo BDD Warriors[GUTS-RS] GUTS Testing Games - Jogo BDD Warriors
[GUTS-RS] GUTS Testing Games - Jogo BDD Warriors
 
GraphQL e APIs: como manter a qualidade?
GraphQL e APIs: como manter a qualidade?GraphQL e APIs: como manter a qualidade?
GraphQL e APIs: como manter a qualidade?
 
Introdução ao Solr e Faceted Search
Introdução ao Solr e Faceted SearchIntrodução ao Solr e Faceted Search
Introdução ao Solr e Faceted Search
 
Cross testing mobile com ruby, cucumber e appium
Cross testing mobile com ruby, cucumber e appiumCross testing mobile com ruby, cucumber e appium
Cross testing mobile com ruby, cucumber e appium
 
QArentena 21: BDD - com Fábio Araújo
QArentena 21: BDD - com Fábio AraújoQArentena 21: BDD - com Fábio Araújo
QArentena 21: BDD - com Fábio Araújo
 
Palestra Fatec
Palestra FatecPalestra Fatec
Palestra Fatec
 
TDC2016SP - O bê-a-bá da fila de processamento para você deixar o ThreadPool ...
TDC2016SP - O bê-a-bá da fila de processamento para você deixar o ThreadPool ...TDC2016SP - O bê-a-bá da fila de processamento para você deixar o ThreadPool ...
TDC2016SP - O bê-a-bá da fila de processamento para você deixar o ThreadPool ...
 
Javascript para CSharpers 4 - POO
Javascript para CSharpers 4 - POOJavascript para CSharpers 4 - POO
Javascript para CSharpers 4 - POO
 
Semana da Mulher na Tecnologia_Introducao ao Bdd
Semana da Mulher na Tecnologia_Introducao ao BddSemana da Mulher na Tecnologia_Introducao ao Bdd
Semana da Mulher na Tecnologia_Introducao ao Bdd
 
Implementando um Handler de Autenticação Customizado no ASP.NET Core 2.0
Implementando um Handler de Autenticação Customizado no ASP.NET Core 2.0Implementando um Handler de Autenticação Customizado no ASP.NET Core 2.0
Implementando um Handler de Autenticação Customizado no ASP.NET Core 2.0
 
Testes de contrato em um contexto de services e microservices tdc-poa2016
Testes de contrato em um contexto de services e microservices tdc-poa2016Testes de contrato em um contexto de services e microservices tdc-poa2016
Testes de contrato em um contexto de services e microservices tdc-poa2016
 
TDC2016POA | Trilha Ruby - Testes de contrato em um contexto de services e mi...
TDC2016POA | Trilha Ruby - Testes de contrato em um contexto de services e mi...TDC2016POA | Trilha Ruby - Testes de contrato em um contexto de services e mi...
TDC2016POA | Trilha Ruby - Testes de contrato em um contexto de services e mi...
 
TDC2016SP - Trilha BigData
TDC2016SP - Trilha BigDataTDC2016SP - Trilha BigData
TDC2016SP - Trilha BigData
 
TDC2016POA | Trilha DevOps - Gestão de ciclo de vida de banco de dados: Já pa...
TDC2016POA | Trilha DevOps - Gestão de ciclo de vida de banco de dados: Já pa...TDC2016POA | Trilha DevOps - Gestão de ciclo de vida de banco de dados: Já pa...
TDC2016POA | Trilha DevOps - Gestão de ciclo de vida de banco de dados: Já pa...
 
Utilizando a API do Roslyn, o novo compilador do C#
Utilizando a API do Roslyn, o novo compilador do C#Utilizando a API do Roslyn, o novo compilador do C#
Utilizando a API do Roslyn, o novo compilador do C#
 
Boas práticas de API Design
Boas práticas de API DesignBoas práticas de API Design
Boas práticas de API Design
 

Garantindo a qualidade da sua API REST com Behave

  • 1. Globalcode – Open4education Garantindo a qualidade da sua API REST com Behave Alex S. Garzão Projetista de Software Yuri Z. Pinheiro Analista de Qualidade ZAP Imóveis www.linkedin.com/in/alexgarzao/ www.linkedin.com/in/yurizp
  • 2. Globalcode – Open4education Agenda • Nosso contexto • Projeto, desafios, problemas e soluções • O que é BDD • O que é Behave • Nossa proposta • Demonstração • Resultados • Lições aprendidas • Próximos passos
  • 3. Globalcode – Open4education Vamos nos conhecer • Testes automatizados. Quem aqui utiliza? • BDD. Quem conhece? Quem utiliza? • Behave. Quem conhece? Quem utiliza?
  • 4. Globalcode – Open4education Nosso contexto no ZAP • Desenvolvemos API RESTful • Python • Django • MySQL
  • 5. Globalcode – Open4education Primeiros desafios • Regras de negócio instáveis • Definição do escopo em andamento • Entendimento do projeto não era claro • Novas tecnologias na empresa
  • 6. Globalcode – Open4education O que isso ocasionou? • Baixa qualidade de código (Bugs a rodo) • Retrabalho do time • Time desmotivado
  • 7. Globalcode – Open4education Qual a solução? • Testes, obviamente • Começamos com testes manuais • Mas isso não escala • Tester virou gargalo da equipe • Vamos automatizar :-)
  • 8. Globalcode – Open4education Em busca de soluções ● Aplicação em Python ○ É possível, mas partiríamos do zero :-/ ● Curl ○ Fácil para testes pontuais ● Postman ○ Legal, mas a automação dele é trabalhosa ● Robot framework ○ Técnico demais ● Lettuce ○ Legal, mas foi descontinuado ● Behave
  • 9. Globalcode – Open4education O que é o BDD? • Técnica de desenvolvimento ágil • Encoraja interação entre técnicos e “não técnicos” • Foco no negócio, e não nos detalhes técnicos • Exemplos descrevem o comportamento da aplicação • São executáveis (documentação viva) • São testes regressivos
  • 10. Globalcode – Open4education Fluxo com BDD Fonte: http://www.qualister.com.br/blog/o-que-e-atdd---acceptance-test-driven-development
  • 11. Globalcode – Open4education O que é o Behave? • Utilizado para a prática de automação de testes • Open source • Suporte para BDD em Python • Permite a escrita de cenários de teste • Linguagem próxima a “natural”
  • 12. Globalcode – Open4education Exemplo Behave - Calcular fatorial Funcionalidade: Calcular o fatorial Cenário: Fatorial de 0 Dado eu tenho o número 0 Quando eu calculo este fatorial Então eu vejo o número 1 Cenário: Fatorial de 2 Dado eu tenho o número 2 Quando eu calculo este fatorial Então eu vejo o número 2 Cenário: Fatorial de 4 Dado eu tenho o número 4 Quando eu calculo este fatorial Então eu vejo o número 24
  • 13. Globalcode – Open4education Funcionalidade: Calcular o fatorial Cenário: Fatorial de 0 Dado eu tenho o número 0 Quando eu calculo este fatorial Então eu vejo o número 1 @given(u'eu tenho o número {number}') def step_impl(context, number): context.number = int(number) @when(u'eu calculo este fatorial') def step_impl(context): context.number = factorial(context.number) @then(u'eu vejo o número {expected}') def step_impl(context, expected): expected = int(expected) assert context.number == expected
  • 14. Globalcode – Open4education • Métodos de uma API Rest • Exemplo: Rota para cadastro de imóveis • Endpoint: https://api.meusite.com/imoveis • JSON: { proprietario: "fulano de tal", endereco: "Rua A, 520", valor: 450000 } O que queríamos testar?
  • 15. Globalcode – Open4education Oh shit! • Behave é uma ferramenta genérica • Não entende API RESTful • HTTP? JSON? GET/POST/PUT/DELETE? • Endpoint? Request? HTTP status code?
  • 16. Globalcode – Open4education Nossa proposta... • Ferramenta open source • Utilizando o Behave • Permite a escrita de testes automatizados • Entende o que é uma API RESTful • Cenários de testes são executáveis • Escritos em português
  • 17. Globalcode – Open4education Tentativa 1 - O início de tudo...
  • 18. Globalcode – Open4education Esquema do Cenário: Como usuário tento cadastrar imóveis Dado que eu quero cadastrar um imóvel E o proprietário é <nome> e o endereço é <endereço> e o valor é <valor> Quando eu tento cadastrar o imóvel Então eu recebo o código 200 Exemplos: Dados válidos para imóveis | nome | endereço | valor | | Proprietário 01 | Rua A POA RS | 1000.00 | | Proprietário 02 | Rua B POA RS | 2000.00 | • Step confuso de entender • Steps muito específicos • Reutilização engessada • A cada novo step, uma nova implementação
  • 20. Globalcode – Open4education Esquema do Cenário: Como usuário tento cadastrar imóveis Dado que eu quero cadastrar um imóvel E o proprietário é <nome> E o endereço é <endereço> E o valor é <valor> Quando eu tento cadastrar o imóvel Então eu recebo o código 200 Exemplos: Dados válidos para imóveis | nome | endereço | valor | | Proprietário 01 | Rua A POA RS | 1000.00 | | Proprietário 02 | Rua B POA RS | 2000.00 | • Maior reutilização :-) • Melhor legibilidade • A cada novo step uma nova implementação :-(
  • 22. Globalcode – Open4education Esquema do Cenário: Como usuário quero cadastrar imóveis Dado que eu quero cadastrar um imóvel E o campo nome do proprietário é <nome> E o campo endereço do imóvel é <endereço> E o campo valor do imóvel é <valor> Quando eu tento cadastrar o imóvel Então eu recebo o status que indica imóvel criado Exemplos: Dados válidos para imóveis | nome | endereço | valor | | Proprietário 01 | Rua A POA RS | 1000.00 | | Proprietário 02 | Rua B POA RS | 2000.00 | • Não temos mais steps específicos por campo • Utilizamos alias (apelidos) para campos, códigos de status, endpoints, ...
  • 23. Globalcode – Open4education Como são definidos os “alias”?
  • 24. Globalcode – Open4education Esquema do Cenário: Mapeando os campos do JSON Dado que eu quero mapear os campos do JSON E o campo <alias> é <tipo> e corresponde a <campo> Quando eu tento mapear os campos Então nenhuma falha ocorre Exemplos: Campos do método de imóveis | alias | tipo | campo | | nome do proprietário | string | proprietario | | endereço do imóvel | string | endereco | | valor do imóvel | number | valor | • É fácil criar novos campos • Fazer manutenção (trocar tipo, nome no JSON, …) • Independência na criação de cenários • Técnicos e não técnicos
  • 26. Globalcode – Open4education Cenário: Como usuário quero listar meus imóveis Dado que eu quero listar os meus imóveis Quando eu busco a lista de imóveis Então eu recebo o status que indica requisição válida E obtenho a lista de dados abaixo | nome do proprietário | endereço do imóvel | | Proprietário 01 | Rua A POA RS | | Proprietário 02 | Rua B POA RS | • Validamos tipagem • Validamos só os campos necessários • Onde está o valor?
  • 27. Globalcode – Open4education E dados não previsíveis?
  • 28. Globalcode – Open4education Cenário: Como usuário quero listar meus imóveis Dado que eu quero listar os meus imóveis Quando eu busco a lista de imóveis Então eu recebo o status que indica requisição válida E obtenho a lista de dados abaixo | nome do proprietário | data e hora criação | | Proprietário 01 | <nao nulo> | | Proprietário 02 | <nao nulo> | • Temos outros tipos de validações • <nao vazio> • <nulo> • <vazio> ou “” • Não temos validações complexas • > 20, < 100, ...
  • 29. Globalcode – Open4education Como enviamos nulo e vazio em requisições?
  • 30. Globalcode – Open4education Esquema do Cenário: Como usuário quero cadastrar imóveis Dado que eu quero cadastrar um imóvel E o campo nome do proprietário é <nome> E o campo endereço do imóvel é <endereço> E o campo valor do imóvel é <valor> Quando eu tento cadastrar o imóvel Então eu recebo o status que indica imóvel criado Exemplos: Dados válidos para imóveis | nome | endereço | valor | | Proprietário 01 | Rua A POA RS | <nulo> | | Proprietário 02 | <vazio> | 250000 | | Proprietário 03 | “ A B C ” | 350000 |
  • 31. Globalcode – Open4education E quando precisamos de dados variáveis?
  • 32. Globalcode – Open4education Esquema do Cenário: Como usuário quero cadastrar imóveis Dado que eu quero cadastrar um imóvel E o campo nome do proprietário é <nome> E o campo endereço do imóvel é <endereço> E o campo valor do imóvel é <valor> Quando eu tento cadastrar o imóvel Então eu recebo o status que indica imóvel criado E guardo o retorno em <variável> Exemplos: Dados válidos para imóveis | nome | endereço | valor | variável | | Proprietário 01 | Rua A POA RS | 150000 | imóvel 01 | | Proprietário 02 | Rua B POA RS | 250000 | imóvel 02 | • Permite reutilização de dados não previsíveis em outros cenários
  • 33. Globalcode – Open4education Cenário: Como usuário quero listar meus imóveis Dado que eu quero listar os meus imóveis Quando eu busco a lista de imóveis Então eu recebo o status que indica requisição válida E obtenho a lista de dados abaixo | nome do proprietário | endereço do imóvel | | $imóvel 01.nome do proprietário | Rua A POA RS | | $imóvel 02.nome do proprietário | Rua B POA RS | • Variáveis podem ser utilizadas em qualquer step • Podemos acessar qualquer campo do JSON
  • 35. Globalcode – Open4education Resultados • Fomos • De poucos testes manuais para 90% de cobertura (testes automatizados) • Ganho de tempo • Temos testes sendo executados a todo momento • Para cada novo bug temos um cenário de teste • Facilidade em desenvolver novos testes
  • 36. Globalcode – Open4education Resultados • Confiança na qualidade • Confiança para realizar alterações críticas • Qualquer pessoa, técnica ou não, consegue desenvolver novos cenários
  • 37. Globalcode – Open4education Lições aprendidas • Tempo para girar a roda é alto • Dependência de API’s externas? Mock • Setup dos dados no início dos testes • Criar o banco, inserir dados de configuração, ... • Não usar dados fictícios • Rodar os testes em homologação • Em produção é um plus • Feature deve ser independente • Cenário independente melhor ainda!
  • 38. Globalcode – Open4education Próximos passos • Pacote instalável via pip • Disseminar o BDD • Mande sua sugestão :-)
  • 39. Globalcode – Open4education Referências • Livro BDD in Action: https://www.manning.com/books/bdd-in-action • Projeto: https://github.com/alexgarzao/victory • Behave: http://pythonhosted.org/behave/