BDD — Testando o comportamento do sistema (Parte 2)

Raphael Amoedo
Grupo OLX Tech
Published in
6 min readFeb 9, 2018

Vimos no post passado os conceitos do BDD e seus benefícios. Agora vamos para a prática: implementar um teste de sistema utilizando a ferramenta Behave.

Pré-Requisitos:

¹ — Vale a pena ressaltar que a pasta onde está o Driver necessita estar no PATH.

Vamos começar:

Primeiramente, vamos rodar o projeto. É um projeto simples utilizado para testes, exemplos e aprendizados: https://github.com/ralphavalon/java-sample-project/tree/system_test

Com Docker:

docker run -e JAVA_OPTS='-Dspring.mvc.locale=pt_BR' -p 8081:8081 ralphavalon/javasampleproject:system_test

Sem Docker:

  • (Necessita Java e Maven) Executar o comando na pasta do projeto:
mvn clean package && java -Dspring.mvc.locale=pt_BR -jar target/JavaSampleProject.jar

Se tudo foi feito com sucesso, ao acessar http://localhost:8081 no navegador, o projeto deve estar acessível:

Entendendo o Behave:

  • Antes de utilizar o Behave, vamos rapidamente entender a estrutura que ele é utilizado. Vamos utilizar uma pasta de nome features, mas que pode ser qualquer outro nome. Então devemos respeitar a seguinte estrutura:

features/
features/steps/
features/environment.py — (opcional)

  • A pasta features que definimos vai ter os arquivos de extensão .feature, que são os arquivos com os testes a serem executados
  • A pasta steps é onde o behave identifica os arquivos com a interpretação dos passos para código Python
  • O arquivo environment.py define código a ser rodado antes e depois de certos eventos relacionados aos testes.
  • As informações no behave são compartilhadas através da variável context utilizada nos métodos do framework

Adicionando o Behave:

Vamos adicionar o arquivo features/user.feature e adicionar um teste simples:

Funcionalidade: testando apenas o títuloCenário: deve possuir o título correto
Dado que visito a pagina "http://localhost:8081/"
Então deveria ter o titulo "Ralph Avalon - Java Sample Project"

Precisamos abrir o Browser antes de cada teste e fechar ao terminar. Para que isso seja feito para cada teste, vamos adicionar o arquivo features/environment.py com as opções before_all e after_all:

from splinter import Browserdef before_all(context):
context.browser = Browser('chrome')
def after_all(context):
context.browser.quit()

Vamos adicionar então o arquivo features/steps/user_steps.py :

from behave import then, when, given@given('que visito a pagina "{url}"')
def visit_page(context, url):
context.browser.visit(url)
@then('deveria ter o titulo "{text}"')
def should_have_title(context, text):
assert context.browser.title == text

Vamos executar o behave na linha de comando:

behave --lang=pt

Resultado do comando behave

Preenchendo os campos:

Até agora fizemos um teste simples. Não testa nada do fluxo principal da aplicação. Primeiro queríamos configurar e executar para saber se estava tudo ok. Agora vamos aos testes reais.

A aplicação só tem duas páginas: criação de usuário e página de sucesso. Precisamos preencher os campos de texto, selecionar o gênero e clicar no botão. Existem várias formas de pegar o campo para preencher: CSS, id, tags, etc. Vamos utilizar o XPath.

Para que fique extensível a usuários não-técnicos, vamos pegar os campos através das Labels do HTML.

Temos a seguinte estrutura para input texts:

<div class="form-group">
<label>Email</label>
<input type="text" class="form-control" name="email" placeholder="exemplo@email.com"/>
</div>

Existem várias formas de pegar essa estrutura, porém vamos utilizar a seguinte forma:

@when('preencho o campo "{field}" com o valor "{value}"')
def fill_field(context, field, value):
input_field = context.browser.find_by_xpath('//label[text()="%s"]/following-sibling::input' % field).first
input_field.fill(value)

Agora, vamos alterar nosso arquivo user.feature :

Funcionalidade: fluxo de criação de usuárioCenário: deveria criar um usuário
Dado que visito a pagina "http://localhost:8081/"
Então deveria ter o titulo "Ralph Avalon - Java Sample Project"
Quando preencho o campo "Nome" com o valor "Raphael Amoedo"
E preencho o campo "Cidade" com o valor "Rio de Janeiro"
E preencho o campo "Email" com o valor "meuemail@email.com"
E preencho o campo "Senha" com o valor "abc123"
E preencho o campo "Data de Nascimento" com o valor "18/04/1992"

Ao executar, vemos que ele preenche os campos e o teste passa, porém, ainda não estamos testando algo.

O teste preenche os campos como definimos

Escolhendo uma das opções:

Temos um input radio que já vem marcado por padrão como Masculino, mas por garantia (e por aprendizado, caso queira selecionar outra opção), vamos clicar na opção desejada.

Temos a seguinte estrutura para input radio:

<div class=”radio”>
<input type=”radio” name=”gender” id=”gender-male” value=”MALE”/>
<span>Masculino</span>
</div>

Então, podemos adicionar o seguinte código para que possamos selecionar através do texto:

@when('marco a opcao com o texto "{text}"')
def mark_option(context, text):
radio = context.browser.find_by_xpath('//input[@type="radio"]/following-sibling::span[text()="%s"]' % text).first
radio.click()

Com isso, já podemos adicionar ao nosso test.feature o passo:

E marco a opcao com o texto "Masculino"

Clicando no botão e validando o resultado:

Queremos também clicar no botão e verificar se o resultado é o que esperamos, afinal, precisamos testar se a aplicação se comporta como queremos. Para isso, vamos adicionar os passos:

@when('clico no botao com o texto "{text}"')
def click_button(context, text):
button = context.browser.find_by_xpath('//button/span[text()="%s"]' % text).first
button.click()
@then('o texto "{text}" esta presente')
def is_text_present(context, text):
assert context.browser.is_text_present(text)

Vamos adicionar esses passos ao nosso test.feature:

Funcionalidade: fluxo de criação de usuárioCenário: deveria criar um usuário
Dado que visito a pagina "http://localhost:8081/"
Então deveria ter o titulo "Ralph Avalon - Java Sample Project"
Quando preencho o campo "Nome" com o valor "Raphael Amoedo"
E preencho o campo "Cidade" com o valor "Rio de Janeiro"
E preencho o campo "Email" com o valor "meuemail@email.com"
E preencho o campo "Senha" com o valor "abc123"
E preencho o campo "Data de Nascimento" com o valor "18/04/1992"
E marco a opcao com o texto "Masculino"
E clico no botao com o texto "Salvar"
Então o texto "Usuario Raphael Amoedo adicionado com sucesso" esta presente

Ao executar:

Veremos que o usuário foi criado e o teste foi um sucesso

E se eu quiser rodar o mesmo teste com parâmetros diferentes?

Ótima pergunta. Utilizando o behave é possível utilizar o conceito de Scenario Outline (Esquema do Cenário):

  • Cenário vira Esquema do Cenário
  • Criamos uma tabela de Exemplos no formato acima, sendo o nome das colunas iguais as variáveis a serem utilizadas
  • Onde queremos utilizar a variável devemos colocar entre os sinais: <>
  • No exemplo acima, o teste será rodado duas vezes, cada um com a combinação diferente, conforme definido.

Considerações finais

É isso, pessoal, espero que tenham gostado. Fizemos apenas o caso de sucesso, mas a ideia é deixar em aberto para que possam testar os casos de erro e brincarem com a aplicação e com os testes.

Extras:

--

--

Raphael Amoedo
Grupo OLX Tech

a.k.a. Ralph Avalon — https://github.com/ralphavalon — Developer at OLX — Passions: Best programming practices, Clean Code, Java, Python, DevOps, Docker, etc.