# Introdução aos Testes Unitários

Os testes unitários são uma prática essencial no desenvolvimento de software moderno. Eles permitem verificar se pequenos blocos de código, denominados unidades, funcionam conforme esperado. Este artigo apresenta um panorama introdutório sobre testes unitários, destacando sua importância, boas práticas e ferramentas populares.

### O que são Testes Unitários?

Testes unitários são testes automatizados que avaliam a funcionalidade de componentes individuais de um software, como funções ou classes. Eles devem ser escritos para garantir que cada unidade funcione isoladamente, sem dependências externas.

#### Benefícios dos Testes Unitários

1. **Prevenção de Erros**: Identifica falhas logo no início do ciclo de desenvolvimento.
2. **Facilidade de Refatoração**: Permite modificar o código com confiança, garantindo que as funcionalidades continuam operando corretamente.
3. **Documentação Viva**: Os testes funcionam como documentação do comportamento esperado do software.
4. **Maior Qualidade do Código**: Estimula a escrita de código mais modular e desacoplado.

### Boas Práticas para Testes Unitários

* **Testes devem ser isolados**: Evite dependências externas, como acesso a bancos de dados ou APIs.
* **Nomes descritivos**: Os nomes dos testes devem indicar claramente o que está sendo testado.
* **Cobertura equilibrada**: Embora uma alta cobertura seja desejável, qualidade é mais importante que quantidade.
* **Manutenção simples**: Testes devem ser fáceis de entender e modificar.

### Ferramentas Populares para Testes Unitários

Dependendo da linguagem de programação utilizada, há diversas ferramentas disponíveis:

* **JUnit** (Java)
* **pytest** e **unittest** (Python)
* **Jest** (JavaScript)
* **NUnit** (C#)
* **Mocha** e **Chai** (JavaScript)

### Exemplo de Teste Unitário com Python

A seguir, um exemplo de teste unitário usando o framework `unittest` em Python:

```python
import unittest

def soma(a, b):
    return a + b

class TestSoma(unittest.TestCase):
    def test_soma_positivos(self):
        self.assertEqual(soma(2, 3), 5)

    def test_soma_negativos(self):
        self.assertEqual(soma(-1, -1), -2)

if __name__ == "__main__":
    unittest.main()
```

### Exemplo de Teste Unitário com Java

A seguir, um exemplo de teste unitário usando o framework JUnit em Java:

```java
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;

public class CalculadoraTest {

    public int soma(int a, int b) {
        return a + b;
    }

    @Test
    public void testSomaPositivos() {
        CalculadoraTest calc = new CalculadoraTest();
        assertEquals(5, calc.soma(2, 3));
    }

    @Test
    public void testSomaNegativos() {
        CalculadoraTest calc = new CalculadoraTest();
        assertEquals(-2, calc.soma(-1, -1));
    }
}
```

### Como Criar um Plano de Teste Unitário

Um plano de teste unitário é um documento que define a abordagem para testar uma aplicação. Ele pode incluir os seguintes elementos:

#### 1. **Identificação do Módulo a Ser Testado**

* Nome do módulo ou componente.
* Funções e classes envolvidas.

#### 2. **Objetivo do Teste**

* Definir o que se espera verificar com os testes unitários.
* Exemplo: "Garantir que a função `soma(a, b)` retorna a soma correta dos valores de entrada."

#### 3. **Cenários de Teste**

* Definir diferentes entradas e saídas esperadas.

| Cenário                     | Entrada  | Saída Esperada |
| --------------------------- | -------- | -------------- |
| Soma de dois positivos      | `2, 3`   | `5`            |
| Soma de dois negativos      | `-1, -1` | `-2`           |
| Soma de positivo e negativo | `5, -3`  | `2`            |

#### 4. **Ferramentas e Frameworks Utilizados**

* Exemplo: `unittest` para Python e JUnit para Java.

#### 5. **Critérios de Sucesso**

* Definição do que constitui um teste bem-sucedido.
* Exemplo: "Todos os testes devem passar sem falhas."

### Conclusão

Os testes unitários são fundamentais para um desenvolvimento de software confiável e eficiente. Sua implementação requer boas práticas e ferramentas adequadas, mas os benefícios em termos de qualidade e manutenção do código são imensuráveis.

{% embed url="<https://docs.google.com/presentation/d/1NmrpJFVvLstDxq4uRABgJcisY-ZnpNPg/edit?ouid=111020856611809207124&rtpof=true&sd=true&usp=sharing>" %}

### Referências

* Beck, K. (2003). **Test-Driven Development: By Example**. Addison-Wesley.
* Meszaros, G. (2007). **xUnit Test Patterns: Refactoring Test Code**. Addison-Wesley.
* Fowler, M. (2019). **Refactoring: Improving the Design of Existing Code**. Addison-Wesley.
* Repositório GitHub com o Projeto Calculadora em <https://github.com/otavianosilverio/UnitTestJava>
