Testes automatizados
Com o Pororoca, você pode fazer testes automatizados junto com ferramentas de testes do .NET, como o xUnit. Esses testes podem ser executados em uma pipeline ou via linha de comando, enviando requisições a um servidor.
Para criar e rodar esses testes, é necessário ter o .NET SDK em seu computador.
Criando o projeto de testes
Crie um projeto de testes através do Visual Studio ou via linha de comando. Para este último caso, digite os seguintes comandos no seu console:
mkdir MeuTestePororoca
cd ./MeuTestePororoca/
dotnet new xunit
# outras bibliotecas de teste podem ser usadas
Após isso, no projeto de testes criado, o arquivo .csproj precisa ser editado para incluir o pacote NuGet Pororoca.Test.
Se seus testes serão executados em uma máquina Linux e esses testes incluírem HTTP/3, a biblioteca msquic precisa estar instalada. Confira na página de Download a versão apropriada.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- Pororoca.Test v3 usa .net8.0 -->
<TargetFramework>net8.0</TargetFramework>
…
</PropertyGroup>
<ItemGroup>
<!-- A linha abaixo adiciona o pacote Pororoca.Test ao projeto -->
<PackageReference Include="Pororoca.Test" Version="3.7.0" />
<!-- A linha abaixo também é necessária -->
<EnablePreviewFeatures>True</EnablePreviewFeatures>
…
</ItemGroup>
</Project>
Fazendo seu primeiro teste
O código abaixo mostra como usar o Pororoca.Test
em um teste no xUnit. Primeiro, ele carrega uma coleção Pororoca vinda de um arquivo. Em seguida, ele define o ambiente que será usado.
using Xunit;
using System.Net;
using Pororoca.Test;
namespace Pororoca.Test.Tests;
public class MeuTestePororoca
{
private readonly PororocaTest pororocaTest;
public MeuTestePororoca()
{
string caminhoArquivo = @"C:\Testes\MinhaColecao.pororoca_collection.json";
pororocaTest = PororocaTest.LoadCollectionFromFile(caminhoArquivo)
.AndUseTheEnvironment("Local");
}
[Fact]
public async Task Deve_obter_JSON_com_sucesso()
{
var res = await pororocaTest.SendRequestAsync("Get JSON");
Assert.NotNull(res);
Assert.Equal(HttpStatusCode.OK, res.StatusCode);
Assert.Equal("application/json; charset=utf-8", res.ContentType);
Assert.Contains("\"id\": 1", res.GetBodyAsText());
}
}
Há métodos na classe PororocaTest para setar valores de variáveis durante a execução dos testes. Eles podem ser usados para setar um token de autenticação, por exemplo:
pororocaTest.SetCollectionVariable("MeuTokenAutenticacao", "token_auth");
O projeto de testes Pororoca.Test.Tests pode guiar e servir de base - ele mostra como usar o pacote Pororoca.Test
, como carregar o arquivo de coleção e como setar variáveis em testes.
Testes de WebSocket
INFO
A partir da versão 3.7.0, o Pororoca.Test usa um Channel<T> para coletar as mensagens enviadas e recebidas no WebSocket. Nas versões anteriores, usava-se uma ObservableCollection<T>, na propriedade ws.ExchangedMessages
.
Você também pode testar WebSockets com o Pororoca. O código abaixo mostra um exemplo de teste:
using System.Net.WebSockets;
using Pororoca.Infrastructure.Features.WebSockets;
[Fact]
public async Task Conversa_WebSocket_deve_ocorrer_com_sucesso()
{
// conectando
var ws = await this.pororocaTest.ConnectWebSocketAsync("Meu WebSocket");
Assert.Equal(WebSocketConnectorState.Connected, ws.State);
// enviando 1a mensagem
// deve estar antes do foreach se o cliente inicia a conversa
await ws.SendMessageAsync("Olá");
// conversa
int msgCount = 0;
await foreach (var msg in ws.ExchangedMessagesCollector!.ReadAllAsync())
{
msgCount++; // contador
if (msgCount == 1)
{
Assert.Equal(WebSocketMessageDirection.FromClient, msg.Direction);
Assert.Equal(WebSocketMessageType.Text, msg.Type);
Assert.Equal("Olá, tudo bem?", msg.ReadAsUtf8Text());
}
else if (msgCount == 2)
{
Assert.Equal(WebSocketMessageDirection.FromServer, msg.Direction);
Assert.Equal(WebSocketMessageType.Text, msg.Type);
Assert.Equal("Oi, tudo bem, e você?", msg.ReadAsUtf8Text());
await ws.SendMessageAsync("AtéMais"); // enviando 3a mensagem
}
else if (msgCount == 3)
{
Assert.Equal(WebSocketMessageDirection.FromClient, msg.Direction);
Assert.Equal(WebSocketMessageType.Close, msg.Type);
Assert.Equal("Tudo certo. Até mais!", msg.ReadAsUtf8Text());
}
}
// verificando se conexão fechou
Assert.Equal(WebSocketConnectorState.Disconnected, ws.State);
}
O WebSocket pode ser fechado tanto por de uma mensagem de encerramento, que pode partir do cliente ou do servidor, como também por desconexão, através do método await ws.DisconnectAsync()
. O fechamento da conexão fará com que a execução saia do loop do await foreach
.
Testes de repetidoras
A seguir, há um exemplo de teste de repetidora. O channelReader
é um objeto para recebimento dos resultados das repetições, que ocorrem em threads em background. A linha await foreach
é necessária para aguardar o fim de todas as requisições.
[Fact]
public async Task Deve_rodar_repetição_com_sucesso()
{
var channelReader = await this.pororocaTest.StartHttpRepetitionAsync("Minha repetição");
Stopwatch cronometro = new();
cronometro.Start();
await foreach (var resultado in channelReader.ReadAllAsync())
{
// asserções aqui
}
cronometro.Stop();
// cronometro.Elapsed --> tempo total de execução
}
Fica a seu critério como inspecionar os resultados.
Se você quiser rodar e gerar um relatório no final:
using Pororoca.Domain.Feature.Entities.Pororoca.Repetition;
using static Pororoca.Domain.Features.RequestRepeater.HttpRepetitionReporter;
...
[Fact]
public async Task Deve_rodar_repetição_com_sucesso_e_gerar_relatório()
{
var channelReader = await this.pororocaTest.StartHttpRepetitionAsync("Minha repetição");
List<PororocaHttpRepetitionResult> resultados = new();
await foreach (var resultado in channelReader.ReadAllAsync())
{
resultados.Add(resultado);
}
string caminhoArquivoRelatorio = "C:\\Testes\\relatorio.csv";
await WriteReportAsync(resultados, caminhoArquivoRelatorio);
}
Rodando os testes
Você pode rodar os testes no Visual Studio ou executando dotnet test
através da linha de comando.
Por que testes automatizados fora do programa?
Outras ferramentas de inspeção HTTP, como o Postman e o SoapUI, têm suas áreas de testes dentro da GUI (interface visual). No Pororoca, a escolha foi ter testes separados, pelas seguintes razões:
Testes automatizados muitas vezes requerem um setup, como rodar scripts em um banco de dados para pré-adicionar ou pré-remover dados, ou então pegar informações de uma fonte de dados externa, para comparar com as respostas das APIs. Testar dentro da GUI dificulta isso, enquanto que fazer em um código separado facilita.
Você pode escolher livremente quais frameworks de testes e asserção quer usar, como o xUnit e o FluentAssertions.
Tendo seus testes em um projeto dotnet, eles já ficam preparados para rodar em uma esteira automatizada (CI/CD), basta uma etapa
dotnet test
para executá-los.