Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 96 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,123 @@
#### Selecione sua Língua | Select your Language
<a href='#nome-do-video'><img src="images/pt-br.png" alt="Português" width="50" /></a>
<a href='#video-name'><img src="images/en.jpg" alt="English" width="50" /></a>
<a href='#automação-de-testes-de-api-usando-bdd'><img src="images/pt-br.png" alt="Português" width="50" /></a>
<a href='#api-test-automation-using-bdd'><img src="images/en.jpg" alt="English" width="50" /></a>


# Nome do Video
# Automação de Testes de API usando BDD

## Repositório

### Branches
* Master (contém o código do último vídeo) - `pt-master`
* Vídeo 1 - ``
* Master (contém o código do último vídeo) - `main`
* Vídeo 1 - `01-basic-gradle-project`
* Vídeo 2 - `02-first-feature`
* Vídeo 3 - `03-first-implementation`
* Vídeo 4 - `04-docstring`
* Vídeo 5 - `05-rest-assured-setup`
* Vídeo 6 - `06-specification-by-example-scenario`
* Vídeo 7 - `07-cucumber-runner`
* Vídeo 8 - `08-creating-clients`
* Vídeo 9 - `09-cucumber-hooks`
* Vídeo 10 - `10-deleting-user-with-hooks`
* Vídeo 11 - `11-mapping-more-complex-jsons`
* Vídeo 12 - `12-deserialization`
* Vídeo 13 - `13-understanding-restassured-syntax`
* Vídeo 14 - `14-using-restassured-assertions`
* Vídeo 15 - `15-prepping-the-scenario`
* Vídeo 16 - `16-scenario-outline`
* Vídeo 17 - `17-asserting-with-groovy-collection`
* Vídeo 18 - `18-creating-builder-from-scratch`
* Vídeo 19 - `19-last-scenario`

### Requisitos:
*
* Java 14
* Gradle 6.7
* Docker


### Comandos
*
### Executar os Testes Localmente
* Subir a loja Swagger Pet Store - `docker run --name petstore -d -p 12345:8080 swaggerapi/petstore3:unstable`
* Rodar os testes - `./gradlew test`
* Relatório do Cucumber - `app/build/reports/feature.html`

## Vídeo

* [Vídeo Completo]()

1. [Criação do Projeto e suas dependências](https://youtu.be/YTKIVemoibA)
1. [Criando Primerio Cenário](https://youtu.be/dmSimWz21RQ)
1. [Codando o Primeiro Cenário](https://youtu.be/qJyYvdAYZzY)
1. [Devo usar DocString?](https://youtu.be/FVssrtDRs_o)
1. [Rest Assured config](https://youtu.be/Ca_z5m_GtpI)
1. [Especificação por exemplo na prática](https://youtu.be/yZA65qXKxoQ)
1. [criando o Executável](https://youtu.be/jSWksLZ9Z7M)
1. [Mapeando a API](https://youtu.be/ltgVZ8Pbjcc)
1. [Criando Ganchos](https://youtu.be/TWkmPkelLd4)
1. [Limpando os Dados](https://youtu.be/TWkmPkelLd4)
1. [Json mais complexos](https://youtu.be/ORZwGUocE4E)
1. [Desserialização](https://youtu.be/JJtHzUfo8us)
1. [Sintaxe antiga do RestAssured](https://youtu.be/b-yLVlV8zrs)
1. [Assertivas no RestAssured](https://youtu.be/hKuIhFwAhr0)
1. [Preparando o cenário](https://youtu.be/CMXwL-w4pMg)
1. [Esquema de Cenário](https://youtu.be/oK_mxMqArHw)
1. [Assertivas com Coleções Groovy](https://youtu.be/Eox-7q2gT0g)
1. [Criando builders do zero](https://youtu.be/vhbtYHOMIhE)
1. [Último cenário Parte 1](https://youtu.be/kSHU_D1Pio4)

---

# Video Name
# API Test Automation using BDD

## Repository

### Branches
* Master (has the code from the last video) - `en-master`
* Video 1 - ``
* Master (has the code from the last video) - `main`
* Video 1 - `01-basic-gradle-project`
* Video 2 - `02-first-feature`
* Video 3 - `03-first-implementation`
* Video 4 - `04-docstring`
* Video 5 - `05-rest-assured-setup`
* Video 6 - `06-specification-by-example-scenario`
* Video 7 - `07-cucumber-runner`
* Video 8 - `08-creating-clients`
* Video 9 - `09-cucumber-hooks`
* Video 10 - `10-deleting-user-with-hooks`
* Video 11 - `11-mapping-more-complex-jsons`
* Video 12 - `12-deserialization`
* Video 13 - `13-understanding-restassured-syntax`
* Video 14 - `14-using-restassured-assertions`
* Video 15 - `15-prepping-the-scenario`
* Video 16 - `16-scenario-outline`
* Video 17 - `17-asserting-with-groovy-collection`
* Video 18 - `18-creating-builder-from-scratch`
* Video 19 - `19-last-scenario`

### Requirements:
*
* Java 14
* Gradle 6.7
* Docker

### Commands
*
### Executing the tests locally
* Start Swagger Pet Store - `docker run --name petstore -d -p 12345:8080 swaggerapi/petstore3:unstable`
* Run the tests - `./gradlew test`
* Cucumber Report - `app/build/reports/feature.html`

## Video

* [Full Video]()

1. [Creating the Project and its dependencies](https://youtu.be/0i72N1Fz_y0)
1. [Creating the First Scenario](https://youtu.be/A3uiR4quZr4)
1. [Implementing the First Scenario](https://youtu.be/uFoq-XtbBa0)
1. [Should I use DocString?](https://youtu.be/M-S55a6ei1M)
1. [Rest Assured Config](https://youtu.be/3jHMpmZfylY)
1. [Hands on Specification by Example](https://youtu.be/wkePKVTevYM)
1. [Runner Class](https://youtu.be/oqElg0mpfwY)
1. [Mapping the API](https://youtu.be/-_B2fFxfFdY)
1. [Creating Hooks](https://youtu.be/Kg611Jv_ib8)
1. [Cleaning the Data](https://youtu.be/IkH6gk2gNNQ)
1. [More complex jsons](https://youtu.be/YLuGI-j61MY)
1. [Deserialization](https://youtu.be/dKdenUAI6iA)
1. [RestAssured Old Syntax](https://youtu.be/1QUjfMs74bA)
1. [RestAssured assertions](https://youtu.be/3R74ESRKm7o)
1. [Preparing the scenario](https://youtu.be/kEuTzrOjdhY)
1. [Scenario Outline](https://youtu.be/ADRZoO5bUZw)
1. [Assertions with Groovy Collections](https://youtu.be/Hzv0Rj3wOBY)
1. [Creating builder from scratch](https://youtu.be/NDPm0ybVj2Q)
1. [Last scenario Part 1](https://youtu.be/F7rbSW5x4x4)
103 changes: 103 additions & 0 deletions app/src/test/java/bdd/automation/api/steps/PetStepDefinitions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package bdd.automation.api.steps;

import bdd.automation.api.support.api.PetApi;
import bdd.automation.api.support.domain.Pet;
import io.cucumber.java.en.And;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import io.cucumber.java.pt.*;
import io.restassured.response.Response;
import org.apache.http.HttpStatus;

import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;

public class PetStepDefinitions {

private PetApi petApi;
private List<Pet> actualPets;
private Response actualPetsResponse;

public PetStepDefinitions() {
petApi = new PetApi();
}

@Given("that I have pets {word}")
@Dado("que eu possua animais {word}")
public void thatIHavePetsAvailable(String status) {}

@When("I search for all pets {word}")
@Quando("eu pesquiso por todos os animais {word}")
public void iSearchForAllPetsAvailable(String status) {
actualPets = petApi.getPetsByStatus(status);
}

@Then("I receive a list of pets available")
@Entao("eu recebo a lista de animais available")
public void iReceiveAListOfPetsAvailable() {
assertThat(actualPets, is(not(empty())));
}

@And("I receive another list of pets {word}")
@E("eu recebo uma outra lista de animais {word}")
public void iReceiveAnotherListOfPetsAvailable(String status) {
Response actualPetsResponse = petApi.getPetsResponseByStatus(status);

actualPets = actualPetsResponse.body().jsonPath().getList("", Pet.class);

actualPetsResponse.
then().
statusCode(HttpStatus.SC_OK).
body(
"size()", is(actualPets.size()),
"findAll { it.status == '"+status+"' }.size()", is(actualPets.size())
);

}

@Então("eu recebo a lista com {} animal/animais")
@Then("I receive a list of {} pet(s)")
public void iReceiveAListOfPets(int petsQuantity) {
assertThat(actualPets.size(), is(petsQuantity));
}

@Dado("que eu não possua animais {word}")
@Given("that I don't have pets {word}")
public void thatIdontHavePets(String status) {
petApi.deletePetsByStatus(status);
}

@When("I do a search for all pets {word}")
@Quando("pesquiso por todos os animais {word}")
public void iDoASearchForAllPetsAvailable(String status) {
actualPetsResponse = petApi.getPetsResponseByStatus(status);
}

@Then("I receive a list of {int} pets {word}")
@Entao("recebo a lista com {int} animais {word}")
public void iReceiveAListOfPetsAvailable(int petsQuantity, String status) {
actualPetsResponse.
then().
statusCode(HttpStatus.SC_OK).
body(
"size()", is(petsQuantity),
"findAll { it.status == '" + status + "' }.size()", is(petsQuantity)
);

}

@And("{int} pets has the name {word}")
@E("{int} animais possuem o nome {word}")
public void petsHasTheNameLion(int petsQuantity, String petName) {
actualPetsResponse.
then().
body(
"findAll { it.name.contains('"+petName+"') }.size()", is(petsQuantity)
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package bdd.automation.api.steps;

import bdd.automation.api.support.api.PetApi;
import bdd.automation.api.support.api.StoreApi;
import bdd.automation.api.support.domain.Order;
import bdd.automation.api.support.domain.Pet;
import bdd.automation.api.support.domain.builders.OrderBuilder;
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import io.cucumber.java.pt.Dado;
import io.cucumber.java.pt.Entao;
import io.cucumber.java.pt.Quando;
import io.restassured.response.Response;

import static org.hamcrest.CoreMatchers.is;

public class StoreStepDefinitions {

PetApi petApi;
StoreApi storeApi;

Pet expectedPet;
Order expectedOrder;

public StoreStepDefinitions() {
petApi = new PetApi();
storeApi = new StoreApi();
}

@Given("I have a pet {word}")
@Dado("que eu possua animal {word}")
public void iHaveAPetAvailable(String status) {
Pet pet = Pet.builder()
.id(333)
.status(status)
.build();

expectedPet = petApi.createPet(pet);
}

@When("I order that pet")
@Quando("faço o pedido desse animal")
public void iOrderThatPet() {
Order order = new OrderBuilder()
.withId(888)
.withPetId(expectedPet.getId())
.build();

expectedOrder = storeApi.createOrder(order);
}


@Then("the order is approved")
@Entao("o pedido é aprovado")
public void theOrderIsApproved() {
Response actualOrderResponse = storeApi.getOrder(expectedOrder.getId());

actualOrderResponse.
then().
body(
"id",is(expectedOrder.getId()),
"petId", is(expectedPet.getId()),
"quantity", is(expectedOrder.getQuantity()),
"status", is("approved")
);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
public class UserStepDefinitions {

private User expectedUser;
private final UserApi userApi;
private UserApi userApi;

public UserStepDefinitions() {
userApi = new UserApi();
Expand Down
58 changes: 58 additions & 0 deletions app/src/test/java/bdd/automation/api/support/api/PetApi.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package bdd.automation.api.support.api;

import bdd.automation.api.support.domain.Pet;
import io.restassured.response.Response;
import org.apache.http.HttpStatus;

import java.util.List;

import static io.restassured.RestAssured.*;

public class PetApi {

private static final String FIND_PETS_BY_STATUS_ENDPOINT = "v3/pet/findByStatus?status={status}";
private static final String PET_ENDPOINT = "v3/pet/{id}";
private static final String CREATE_PET_ENDPOINT = "v3/pet";

public List<Pet> getPetsByStatus(String status) {
return given().
pathParam("status", status).
when().
get(FIND_PETS_BY_STATUS_ENDPOINT).
then().
extract().body().jsonPath().getList("", Pet.class);
}

public Response getPetsResponseByStatus(String status) {
return given().
pathParam("status", status).
when().
get(FIND_PETS_BY_STATUS_ENDPOINT);
}

public void deletePetsByStatus(String status) {
List<Integer> petsId = given().
pathParam("status", status).
when().
get(FIND_PETS_BY_STATUS_ENDPOINT).
thenReturn().
path("id");

if(!petsId.isEmpty()) {
for (Integer id : petsId) {
given().pathParam("id", id).delete(PET_ENDPOINT);
}
}
}

public Pet createPet(Pet pet) {
return given().
body(pet).
when().
post(CREATE_PET_ENDPOINT).
then().
statusCode(HttpStatus.SC_OK).
extract().body().as(Pet.class);
}

}
Loading