Automatize o CI/CD em OSS com GitHub Actions: Guia Prático
Testes Automatizados em C# com xUnit e NUnit: Guia Prático
Imagine poder garantir que cada parte do seu código funcione perfeitamente, mesmo após refatorações, adições de novas funcionalidades ou correções de bugs. É aí que entram os testes automatizados com xUnit e📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. NUnit: duas ferramentas poderosas para escrever testes de unidade
🧪 Testes de Unidade para Tratamento de Erros: Previna Falhas Futuras!Descubra como implementar testes de unidade focados em tratamento de erros, evitando surpresas em produção e garantindo sistemas confiáveis e robustos. em C#. Neste artigo, vamos explorar como começar a usar cada framework, mostrar exemplos práticos e aprofundar nos conceitos que fazem seus testes serem profissionais.
Além disso, você aprenderá técnicas avançadas usadas em projetos reais📁 Portfólio .NET: Projetos que Impressionam Recrutadores!Descubra dicas práticas e estratégicas para criar um portfólio .NET que demonstra expertise e atrai recrutadores, com projetos reais e arquitetura limpa., como testes parametrizados, simulação de falhas controladas e integração com pipelines de CI/CD. Vamos além do básico, explorando como escrever testes que validam cenários complexos e garantem a qualidade do seu software.
Tabela de Conteúdo🔗
- Motivação: Por que Criar
📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!Descubra os fundamentos do REST e boas práticas para criar APIs simples, escaláveis e eficientes. Domine métodos HTTP e status codes com exemplos práticos. Testes?
- Visão Geral: xUnit vs
🛠️ Instalação do Visual Studio: Prepare sua Nave para Decolar!Prepare seu ambiente de desenvolvimento com o Visual Studio em uma aventura C#. Este tutorial prático ensina a instalar, configurar e personalizar sua IDE.. NUnit
- Configuração
🚀 Scale Out com Redis: Atenda Milhões de Conexões!Integre o Redis com SignalR no .NET e distribua mensagens entre servidores, alcançando escalabilidade e alta performance em tempo real. e Estrutura de Projeto
- Primeiros Exemplos de Testes com xUnit
- Primeiros Exemplos de Testes com NUnit
- Boas Práticas
🔢 Operadores Aritméticos: Faça Cálculos como uma Calculadora Humana!Aprenda a dominar operadores aritméticos em C# com exemplos práticos, técnicas de cálculo e dicas para evitar erros e maximizar resultados. de Nomenclatura de Testes
- Asserções e Métodos
🧠 Métodos em C#: Como Criar Funções que Não São Só Enfeites!Otimize seu código em C# com métodos inteligentes. Aprenda práticas de reutilização, sobrecarga e escopo para melhorar a clareza e a eficiência. Úteis
- Usando Coleções e
📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. Categorias
- Testando Código Assíncrono
⚡ Async/Await: Programação Assíncrona sem Callbacks!Aprenda a aplicar Async/Await em C# para criar aplicações responsivas, evitar travamentos e melhorar a escalabilidade com exemplos práticos e dicas essenciais.
- Casos de Teste do Mundo Real
- Testes Parametrizados com Theory e
📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. TestCase
- Fixtures: Compartilhando Contexto Entre Testes
- Integração com CI/CD Pipelines
📊 Pipelines: Pré-processe Dados como um Cientista!Aprenda a criar pipelines eficientes com ML.NET, automatizando o pré-processamento de dados e garantindo modelos de Machine Learning precisos e reprodutíveis.
- Práticas Recomendadas
🔢 Operadores Aritméticos: Faça Cálculos como uma Calculadora Humana!Aprenda a dominar operadores aritméticos em C# com exemplos práticos, técnicas de cálculo e dicas para evitar erros e maximizar resultados. por Experts
Motivação: Por que Criar Testes?🔗
Testes de unidade🧪 Testes de Unidade para Tratamento de Erros: Previna Falhas Futuras!Descubra como implementar testes de unidade focados em tratamento de erros, evitando surpresas em produção e garantindo sistemas confiáveis e robustos. trazem confiança ao seu projeto. Quando você sabe que cada pedaço do código está validado, fica muito mais fácil refatorar, adicionar novas funcionalidades ou até integrar com outros sistemas. Testes bem estruturados reduzem o risco de regressões (quando algo que funcionava antes, para de funcionar), além de ajudarem a documentar o comportamento esperado do seu software.
Visão Geral: xUnit vs. NUnit🔗
xUnit e📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. NUnit são dois frameworks populares para
🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)Descubra como automatizar repetições em C# utilizando loops for e while com exemplos práticos que evitam erros e otimizam seu código. Aprenda mais! testes em C#. Ambos oferecem:
- Metodologias semelhantes para criar
📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!Descubra os fundamentos do REST e boas práticas para criar APIs simples, escaláveis e eficientes. Domine métodos HTTP e status codes com exemplos práticos. e organizar testes.
- Suporte para asserções (comparação de valores, verificação de exceções
💥 Try/Catch: Domine Exceções antes que Elas Dominem Você!Descubra como tratar exceções em C# com práticas eficientes utilizando try/catch. Aprenda a gerenciar erros e aumentar a robustez do seu código. etc.).
- Ferramentas para agrupar e executar
🔍 Comandos: Desacople Ações dos Botões!Aprenda a implementar comandos em C# para desacoplar lógica e interface usando MVVM, com exemplos práticos e dicas para melhor testabilidade e manutenção. testes em massa.
A principal diferença está em algumas convenções🤝 GitHub Básico: Versionamento para Iniciantes!Descubra como o GitHub facilita colaboração, versionamento e organização de código com este tutorial prático e essencial para desenvolvedores iniciantes. de nomenclatura e em detalhes de estrutura de testes. De forma geral:
- O xUnit prioriza simplicidade e convenções
🤝 GitHub Básico: Versionamento para Iniciantes!Descubra como o GitHub facilita colaboração, versionamento e organização de código com este tutorial prático e essencial para desenvolvedores iniciantes. (“convention over configuration”), e cria automaticamente instâncias de classe de teste para cada método
🧠 Métodos em C#: Como Criar Funções que Não São Só Enfeites!Otimize seu código em C# com métodos inteligentes. Aprenda práticas de reutilização, sobrecarga e escopo para melhorar a clareza e a eficiência..
- O NUnit é mais antigo, com bastante material de consulta e suporte, e oferece atributos
📜 Atributos Customizados: Metadados que Guiam seu Código!Descubra como atributos customizados potencializam a organização do código, facilitam auditorias e testes, e garantem eficiência. adicionais para personalizar a execução dos testes.
Se você está começando, escolher um ou outro não fará grande diferença. O importante é escrever bons testes, independente do framework.
Configuração e Estrutura de Projeto🔗
Para configurar um projeto de testes, você pode usar o dotnet CLI ou o Visual Studio🛠️ Instalação do Visual Studio: Prepare sua Nave para Decolar!Prepare seu ambiente de desenvolvimento com o Visual Studio em uma aventura C#. Este tutorial prático ensina a instalar, configurar e personalizar sua IDE.. Seguem dois exemplos usando o .NET CLI:
# Criar um novo projeto de teste com xUnit
dotnet new xunit -o MinhaApp.Tests
# Ou criar um novo projeto de teste com NUnit
dotnet new nunit -o MinhaApp.Tests
Depois, você pode adicionar referências🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!Descubra como escolher entre classes e structs em C#. Aprenda sobre alocação de memória, passagem por valor e referência, e performance nesta explicação clara. ao projeto principal (aquele que contém o código que você quer testar) e instalar pacotes adicionais se necessário.
Em termos de estrutura:
- Geralmente criamos um projeto
🤝 GitHub Básico: Versionamento para Iniciantes!Descubra como o GitHub facilita colaboração, versionamento e organização de código com este tutorial prático e essencial para desenvolvedores iniciantes. de teste separado, com o nome terminando em .Tests (ex.: MinhaApp.Tests).
- Dentro do projeto, cada classe de teste costuma estar associada a uma classe do projeto
🤝 GitHub Básico: Versionamento para Iniciantes!Descubra como o GitHub facilita colaboração, versionamento e organização de código com este tutorial prático e essencial para desenvolvedores iniciantes. principal ou a um feature.
Primeiros Exemplos de Testes com xUnit🔗
No xUnit, cada método de teste é marcado com o atributo📜 Atributos Customizados: Metadados que Guiam seu Código!Descubra como atributos customizados potencializam a organização do código, facilitam auditorias e testes, e garantem eficiência.
[Fact]
. Confira um exemplo simples:
using Xunit;
public class CalculadoraTests
{
[Fact]
public void Somar_DeveRetornarResultadoCorreto()
{
// Arrange
var calculadora = new Calculadora();
// Act
var resultado = calculadora.Somar(2, 3);
// Assert
Assert.Equal(5, resultado);
}
}
Repare que criamos um cenário (Arrange), executamos a ação (Act) e📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. verificamos o resultado (Assert). O xUnit executa cada teste de forma isolada, garantindo que não haja interferência entre testes.
Primeiros Exemplos de Testes com NUnit🔗
No NUnit, o atributo📜 Atributos Customizados: Metadados que Guiam seu Código!Descubra como atributos customizados potencializam a organização do código, facilitam auditorias e testes, e garantem eficiência. principal é
[Test]
. O fluxo é parecido, mas📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. mudam alguns nomes:
using NUnit.Framework;
public class CalculadoraTests
{
[Test]
public void Somar_DeveRetornarResultadoCorreto()
{
// Arrange
var calculadora = new Calculadora();
// Act
var resultado = calculadora.Somar(2, 3);
// Assert
Assert.AreEqual(5, resultado);
}
}
O conceito é o mesmo. Você prepara o objeto, executa a ação desejada e📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. verifica os resultados.
Boas Práticas de Nomenclatura de Testes🔗
Independente do framework, dar nomes claros aos métodos🧠 Métodos em C#: Como Criar Funções que Não São Só Enfeites!Otimize seu código em C# com métodos inteligentes. Aprenda práticas de reutilização, sobrecarga e escopo para melhorar a clareza e a eficiência. de teste é fundamental. Exemplos:
Metodo_Condicao_EfeitoEsperado()
Somar_ValoresPositivos_ResultadoCorreto()
Ou ainda:
DadoDoisNumerosQuandoSomarEntaoRetornaSomaCorreta()
O objetivo é que qualquer pessoa que olhe para o método🧠 Métodos em C#: Como Criar Funções que Não São Só Enfeites!Otimize seu código em C# com métodos inteligentes. Aprenda práticas de reutilização, sobrecarga e escopo para melhorar a clareza e a eficiência. de teste entenda facilmente o que está sendo validado.
Asserções e Métodos Úteis🔗
Nos testes, utilizamos métodos🧠 Métodos em C#: Como Criar Funções que Não São Só Enfeites!Otimize seu código em C# com métodos inteligentes. Aprenda práticas de reutilização, sobrecarga e escopo para melhorar a clareza e a eficiência. de asserção para
🔄 Loops em C#: Repita Tarefas sem Enlouquecer (Com for e while!)Descubra como automatizar repetições em C# utilizando loops for e while com exemplos práticos que evitam erros e otimizam seu código. Aprenda mais! verificar se o resultado é o esperado.
Exemplo com xUnit
Assert.Equal(expected, actual)
: Verifica se dois valores🏗️ Classes vs. Structs: Quando Usar Cada Uma (e Não Quebrar a Cabeça)!Descubra como escolher entre classes e structs em C#. Aprenda sobre alocação de memória, passagem por valor e referência, e performance nesta explicação clara. são iguais.
Assert.True(condicao)
: Verifica se a condição é verdadeira.Assert.Throws<TException>(() => ...)
: Verifica se a exceção💥 Try/Catch: Domine Exceções antes que Elas Dominem Você!Descubra como tratar exceções em C# com práticas eficientes utilizando try/catch. Aprenda a gerenciar erros e aumentar a robustez do seu código. certa foi lançada.
Exemplo com NUnit
Assert.AreEqual(expected, actual)
: Similar aoAssert.Equal
do xUnit.Assert.IsTrue(condicao)
: Verifica se a condição é verdadeira.Assert.Throws<TException>(() => ...)
: Também verifica se a exceção💥 Try/Catch: Domine Exceções antes que Elas Dominem Você!Descubra como tratar exceções em C# com práticas eficientes utilizando try/catch. Aprenda a gerenciar erros e aumentar a robustez do seu código. foi lançada.
Usando Coleções e Categorias🔗
- xUnit tem o conceito de Collection Fixtures para compartilhar contexto entre vários testes. Útil se você precisa de um recurso (por exemplo, um arquivo de configuração
🚀 Scale Out com Redis: Atenda Milhões de Conexões!Integre o Redis com SignalR no .NET e distribua mensagens entre servidores, alcançando escalabilidade e alta performance em tempo real.) inicializado apenas uma vez.
- NUnit possui
[SetUp]
e📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades.
[TearDown]
(e📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. suas variações
[OneTimeSetUp]
,[OneTimeTearDown]
) para controlar criação e limpeza de recursos📡 RESTful 101: Princípios que Todo Dev API Precisa Saber!Descubra os fundamentos do REST e boas práticas para criar APIs simples, escaláveis e eficientes. Domine métodos HTTP e status codes com exemplos práticos. entre os testes.
Também é comum usar “categorias” para agrupar🎲 Desafio: Analise Dados de Vendas com LINQ e Coleções!Aprenda a usar coleções e LINQ em C# para analisar vendas, filtrar dados e extrair insights estratégicos que otimizem decisões e impulsionem seu negócio. testes (por exemplo,
[Trait("Categoria", "Unitário")]
no xUnit ou [Category("Unitário")]
no NUnit). Assim, você pode executar🔍 Comandos: Desacople Ações dos Botões!Aprenda a implementar comandos em C# para desacoplar lógica e interface usando MVVM, com exemplos práticos e dicas para melhor testabilidade e manutenção. apenas um conjunto específico quando precisar.
Testando Código Assíncrono🔗
Ambos os frameworks suportam métodos🧠 Métodos em C#: Como Criar Funções que Não São Só Enfeites!Otimize seu código em C# com métodos inteligentes. Aprenda práticas de reutilização, sobrecarga e escopo para melhorar a clareza e a eficiência. assíncronos. Basta retornar
Task
no método🧠 Métodos em C#: Como Criar Funções que Não São Só Enfeites!Otimize seu código em C# com métodos inteligentes. Aprenda práticas de reutilização, sobrecarga e escopo para melhorar a clareza e a eficiência. de teste e fazer o await
⚡ Async/Await: Programação Assíncrona sem Callbacks!Aprenda a aplicar Async/Await em C# para criar aplicações responsivas, evitar travamentos e melhorar a escalabilidade com exemplos práticos e dicas essenciais. normalmente:
// xUnit
[Fact]
public async Task Exemplo_DeveExecutarAcaoAssincrona()
{
await Task.Delay(10);
Assert.True(true);
}
// NUnit
[Test]
public async Task Exemplo_DeveExecutarAcaoAssincrona_NUnit()
{
await Task.Delay(10);
Assert.IsTrue(true);
}
Dessa forma, você mantém a legibilidade do teste sem se preocupar com callbacks ou blocos try-catch extras.
Casos de Teste do Mundo Real🔗
Teste de Exceções
[Fact]
public void Dividir_PorZero_DeveLancarDivideByZeroException()
{
var calc = new Calculadora();
Assert.Throws<DivideByZeroException>(() => calc.Dividir(10, 0));
}
Testes Assíncronos
[Fact]
public async Task BuscarUsuario_QuandoExistir_RetornaObjetoUsuario()
{
var usuarioService = new UsuarioService();
var resultado = await usuarioService.BuscarPorId(1);
Assert.NotNull(resultado);
Assert.IsType<Usuario>(resultado);
}
Testes com Mock Objects
[Fact]
public void ProcessarPagamento_DeveChamarGatewayCorretamente()
{
var mockGateway = new Mock<IPagamentoGateway>();
var processor = new PagamentoProcessor(mockGateway.Object);
processor.Processar(new Pagamento(100.00m));
mockGateway.Verify(g => g.EnviarPagamento(100.00m), Times.Once);
}
Testes Parametrizados com Theory e TestCase🔗
xUnit (Theory + InlineData)
[Theory]
[InlineData(1, 2, 3)]
[InlineData(-1, 1, 0)]
[InlineData(100, 200, 300)]
public void Somar_VariosNumeros_RetornaSomaCorreta(int a, int b, int esperado)
{
var resultado = _calc.Somar(a, b);
Assert.Equal(esperado, resultado);
}
NUnit (TestCase)
[Test]
[TestCase(1, 2, 3)]
[TestCase(-1, 1, 0)]
[TestCase(100, 200, 300)]
public void Somar_VariosNumeros_RetornaSomaCorreta(int a, int b, int esperado)
{
var resultado = _calc.Somar(a, b);
Assert.AreEqual(esperado, resultado);
}
Fixtures: Compartilhando Contexto Entre Testes🔗
xUnit (Class Fixture)
public class DatabaseFixture : IDisposable
{
public BancoDados Banco { get; }
public DatabaseFixture()
{
Banco = new BancoDados();
Banco.Inicializar();
}
public void Dispose()
{
Banco.Fechar();
}
}
public class TestesBancoDados : IClassFixture<DatabaseFixture>
{
private readonly DatabaseFixture _fixture;
public TestesBancoDados(DatabaseFixture fixture)
{
_fixture = fixture;
}
[Fact]
public void TesteConsulta()
{
var resultado = _fixture.Banco.ExecutarConsulta("SELECT...");
Assert.NotNull(resultado);
}
}
Integração com CI/CD Pipelines🔗
Exemplo GitHub Actions
name: .NET Tests
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions
🌍 Projeto: API de E-Commerce com ASP.NET Core e SQL Server!Aprenda a construir uma API robusta para e-commerce com ASP.NET Core, EF Core, JWT e Swagger, validando suas habilidades em um projeto prático real./checkout@v3
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: 8.x
- name: Run tests
run: dotnet test --configuration Release --logger "trx;LogFileName=test-results.trx"
Práticas Recomendadas por Experts🔗
1. Nomes Descritivos:
UsuarioService_AtualizarEmail_QuandoEmailInvalido_DeveRetornarErroDeValidacao
2. Testes Independentes:
Nunca dependa da ordem de execução
3. Regra 1:1:
1 assert por teste (com exceções💥 Try/Catch: Domine Exceções antes que Elas Dominem Você!Descubra como tratar exceções em C# com práticas eficientes utilizando try/catch. Aprenda a gerenciar erros e aumentar a robustez do seu código. justificáveis)
4. Dados de Teste Realistas:
var cpfValido = GeradorCpf.Validar(); // Não usar "111.111.111-11"
5. Avoid Magic Numbers:
const int LimiteIdade = 18; // Em vez de usar 18 diretamente
[Fact]
public void ProcessamentoGrande_DeveConcluirEmMenosDe2Segundos()
{
var stopwatch = Stopwatch.StartNew();
Processador.ExecutarTarefaPesada();
stopwatch.Stop();
Assert.True(stopwatch.ElapsedMilliseconds < 2000);
}
7. Relatório de Cobertura:
dotnet test --collect:"XPlat Code Coverage"
Com xUnit ou NUnit, o segredo é escrever testes claros, organizados e📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. que cubram os cenários
📊 Behavior-Driven Development: Testes que Todo Mundo Entende!Descubra como o BDD transforma testes em linguagens acessíveis. Aprenda a usar SpecFlow em C# para criar testes claros, colaborativos e sem ambiguidades. mais importantes do seu software. Dessa forma, você garante a manutenção de alta qualidade, melhora a confiança no código e ainda ganha tranquilidade ao evoluir seu projeto
🤝 GitHub Básico: Versionamento para Iniciantes!Descubra como o GitHub facilita colaboração, versionamento e organização de código com este tutorial prático e essencial para desenvolvedores iniciantes..
Autor: Marcelo V. Souza - Engenheiro de Sistemas e Entusiasta em IoT e Desenvolvimento de Software, com foco em inovação tecnológica.
Referências🔗
- .NET Documentation: learn.microsoft.com/pt-br/dotnet/
- Awesome .NET: github.com/quozd/awesome-dotnet
- C# Language Specification: learn.microsoft.com/pt-br/dotnet/csharp/language-reference/language-specification/
- GitHub: Microsoft/.NET: github.com/dotnet
- Microsoft Learn: C# e .NET: learn.microsoft.com/pt-br/dotnet/csharp/