PostgreSqlBuilder, MsSqlBuilder, etc.).📌 Material de chegada: 1 dependência possuída (BD/broker do projeto) + 1 dependência consumida (API externa) + 1 dúvida concreta. Esses 3 itens alimentam o daily de abertura.
Pirâmide, contrato como observável, mapa SOA (possuído × consumido), código .NET para Testcontainers e WireMock.Net.
Implementar 1 teste de integração no projeto: 1 dependência possuída (Testcontainers) ou consumida (WireMock). Entrega via MR com RF + RNF.
🎯 Saída do dia: link do Merge Request postado na plataforma da disciplina. Vale nota ponderada — fechar antes do fim dos 90 min.
1 classe, 0 dependências reais. Mocks substituem tudo. Roda em milissegundos.
Pergunta: "Esta peça faz o que prometeu?"
Várias peças + dependências reais ou semi-reais (BD em container, HTTP em cassete). Roda em segundos.
Pergunta: "Estas peças combinam direito?"
Tudo de pé, navegador real, ambiente real. Mede o caminho do usuário. Minutos por suite.
Pergunta: "O usuário consegue chegar lá?"
📌 Foco do dia: a faixa amarela. Em SOA, é onde mais aparecem bugs caros — e onde Testcontainers + VCR brilham.
Centenas de testes rodando em milissegundos. Garantem que cada peça funciona isolada. Falhas de unit tests não pegam wiring.
Dezenas, não centenas. Sobem a aplicação de verdade para validar wiring entre camadas e dependências. Foco do dia.
Poucos casos críticos de fluxo (login → checkout). Caros de manter, frágeis a mudanças de UI. Não substituem integração.
Controller chama Service que chama Repository. Cada peça passa nos seus unit tests, mas a injeção de dependência ou o middleware podem estar quebrados.
EF Core gera SQL diferente de mocks. Migrations, índices, tipos NUMERIC × DECIMAL: tudo só aparece quando você roda contra um banco de verdade.
JWT, claims, políticas de autorização, headers de cache. Tudo isso só executa quando o pipeline HTTP roda inteiro — algo que unit tests pulam.
Em SOA, sua app chama a API de outro squad. Headers, timeouts, retries, contratos de payload — só aparecem em integração, nunca em mocks isolados.
Você só conhece o contrato: entrada (request, headers, payload) → saída (status, body, side effects). Implementação interna é irrelevante.
Vantagem: o teste sobrevive a refactor. Mude o ORM, troque o algoritmo, reescreva a service — se o contrato continua igual, o teste continua verde.
Testa caminhos internos: cobertura de linhas, branches, métodos privados. Bom para unit. Em integração SOA quebra a cada refactor e acopla teste à implementação.
Em arquitetura orientada a serviços, o contrato é o que o outro squad consegue ver: o endpoint HTTP, o schema do payload, o status code, o header. É a sua superfície pública.
Quando você testa POST /pedidos só pela request/response, você está protegendo o contrato — exatamente o que outro serviço SOA consome. É o ângulo certo para integração.
📌 Regra de ouro: em teste de integração, não inspecione estado interno. Se você precisar abrir o objeto pra checar um campo privado, refatore o teste — não a regra.
São suas. Você controla schema, deploy, versão. Você pode subir uma cópia idêntica em qualquer máquina.
São de outro squad (ou de terceiros). Você só conhece pela API HTTP. Não controla o deploy nem o uptime.
Biblioteca que sobe containers Docker descartáveis dentro do ciclo de vida do teste. PostgreSQL real, Redis real, RabbitMQ real — não um mock, não um in-memory.
Sempre que o dialeto real importa: JSONB do Postgres, full-text search, índice GIN, transações isoladas, particionamento. SQLite InMemory não fala esses dialetos.
Custo: 3–10s de startup por container. Mais lento que mock.
Benefício: fidelidade total ao prod. Bug que aparece aqui, aparece lá.
Docker rodando na máquina (local) e no runner do CI. Sem Docker, sem Testcontainers — verifique antes de adotar no projeto.
📌 Mental model: Testcontainers transforma a frase "rodei contra Postgres real" em algo que cabe num dotnet test determinístico, sem precisar de banco compartilhado.
PostgreSqlBuilder + IAsyncLifetime · sobe e derruba por suitexUnit chama InitializeAsync antes da suite e DisposeAsync ao final. Sem isso, container vaza.
Compartilha o mesmo container entre todos os testes da classe — startup uma vez só, isolamento por transação.
Combine com Respawn ou TRUNCATE em Setup de cada teste pra garantir banco limpo.
Nome veio do VCR.py (Ruby/Python). Você roda o teste 1 vez contra a API real, ele grava request + response num arquivo (o cassete). Próximas execuções: o HTTP é interceptado e a resposta vem do cassete.
Dependências que você NÃO possui: API REST de outro squad, gateway de pagamento, provider de autenticação. Qualquer HTTP fora do seu controle.
A biblioteca padrão de mercado é WireMock.Net. Suporta stub manual + modo recording proxy: você define a URL real, ele grava o roundtrip, depois replay-only.
📌 Mental model: cassete = "foto do contrato que o outro serviço me deu naquele dia". É frozen-in-time. Útil, mas com cuidado — voltaremos a esse ponto.
WithProxy("https://api.real/") + SaveMapping() grava o roundtrip em JSON. Próximas execuções: replay only.
Cassete versionado no repo (Mappings/*.json). CI nunca chama a API real — determinístico e rápido.
Crie 2 mappings: um pro 200 (sucesso) e outro pro 503/timeout (erro). Teste o comportamento em cada caso.
| Pergunta | 🐳 Testcontainers | 📼 VCR / WireMock.Net |
|---|---|---|
| Quem possui? | você Schema, deploy, versão. | outro squad ou terceiro Você só consome via HTTP. |
| Exemplos típicos | PostgreSQL, Redis, RabbitMQ, MinIO — do seu serviço. | API de pagamentos, catálogo de outro squad, Auth0, SendGrid. |
| O que está rodando? | O processo real em container Docker. | Um stub HTTP que devolve respostas pré-gravadas. |
| Custo de execução | 3–10s de startup por container. | Milissegundos. Quase grátis. |
| Pega bug de dialeto? | SIM JSONB, full-text, transações reais. | não Você gravou o que o provider devolveu, nada mais. |
| Pega quebra do provider? | N/A · o provider é você. | não Se o provider mudar, seu cassete continua verde — falsamente. |
| Cobre cenários de falha? | Sim — derrube o container e veja o comportamento. | Sim — crie mapping de 503/timeout/payload inválido. |
📌 Regra prática: em SOA, mapeie as dependências do seu serviço em 2 colunas — possuídas e consumidas — antes de escrever o primeiro teste de integração. A ferramenta sai do mapa.
Isolar seu teste de integração da dependência externa. Pipeline determinístico, sem flakiness, documentação executável do que você esperava.
Pact é o canônico em SOA: o consumer define o contrato esperado, o provider executa esses contratos no próprio build dele. Quebrou no provider? Build falha no provider.
Alternativas: Spring Cloud Contract, OpenAPI schema validation com Schemathesis.
"Usei WireMock pra isolar a dependência externa em teste de integração. Para contrato de verdade, a stack é Pact." — Essa é a frase que passa em entrevista técnica.
Fluxo que toque possuída (BD/broker) e consumida (API externa). Setup obrigatório com Testcontainers + WireMock.Net em xUnit.
Antes de codar, registre o fluxo numa tabela no README (aluno · fluxo · link do MR). Sem duplicar fluxo entre colegas — força distribuição.
Branch test/integration-{flow}, dotnet test verde no pipeline, MR com RF + RNF, link direto na plataforma da disciplina.
🧠 Assuntos relacionados: Qualidade de software · Testes de integração · Arquitetura SOA · ISO/IEC 25010.
📚 Conteúdos relacionados: Testes black-box · Testcontainers · WireMock.Net · Merge Request workflow.
Fluxo único registrado em tabela no README do repo (aluno · fluxo · link MR).
Sem duplicar entre colegas do grupo.
xUnit + Testcontainers (possuída) + WireMock.Net (consumida). 1 sucesso + 1 erro.
dotnet test verde.
MR no repo oficial do grupo (Open ou Merged).
Branch test/integration-{flow}.
Descrição do MR cita qual RF o teste valida.
⭐ RF exato + falha crítica.
Eixo: eficiência, segurança, confiabilidade, manutenibilidade.
⭐ RNF exato (ex.: "RNF02").
📌 Fluxo de entrega (individual):
test/integration-{flow} · setup com Testcontainers + WireMock.Netdotnet test verdetest/integration-{flow}dotnet test verde