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
110 changes: 92 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,45 +1,119 @@
#### 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`

### 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)

---

# 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`

### 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)
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,30 @@
package bdd.automation.api.steps;

import bdd.automation.api.support.domain.Store;
import bdd.automation.api.support.domain.builders.StoreBuilder;
import io.cucumber.java.en.Given;

public class StoreStepDefinitions {
@Given("something..")
public void something() {
Store store1 = new StoreBuilder().build();

Store store2 = new StoreBuilder()
.withId(9)
.withPetId(99)
.withQuantity(100)
.withStatus("complete")
.withShipDate("11/01/2021")
.build();

Store store3 = new StoreBuilder()
.withPetId(88)
.withQuantity(50)
.withStatus("incomplete")
.build();

Store store4 = new StoreBuilder().build();

System.out.println("asdasd");
}
}
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
47 changes: 47 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,47 @@
package bdd.automation.api.support.api;

import bdd.automation.api.support.domain.Pet;
import io.restassured.response.Response;

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}";

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);
}
}

}

}
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
package bdd.automation.api.support.api;

import bdd.automation.api.support.domain.User;
import lombok.Data;
import org.apache.http.HttpStatus;

import java.util.Arrays;
import java.util.List;

import static io.restassured.RestAssured.given;


@Data
public class UserApi {

private static final String CREATE_USER_ENDPOINT = "/v3/user";
private static final String USER_ENDPOINT = "/v3/user/{name}";

private String name;

public void createUser(User user) {
given().
body(user).
Expand Down
39 changes: 39 additions & 0 deletions app/src/test/java/bdd/automation/api/support/domain/Pet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package bdd.automation.api.support.domain;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Arrays;
import java.util.List;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class Pet {
@Builder.Default
private int id = 2;
@Builder.Default
private String name = "Panthro";
@Builder.Default
private Category category = new Category();
@Builder.Default
private String status = "available";
@Builder.Default
private List<String> photoUrls = Arrays.asList("url1", "url2");

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public static class Category {
@Builder.Default
private int id = 2;
@Builder.Default
private String name = "Cats";
}
}
Loading