O que é BDD e por que não é apenas mais uma moda?
\n\nVocê já escreveu um código que funciona perfeitamente do ponto de vista do compilador, mas não faz o que o negócio precisa? Conhece aquela situação em que o gerente olha para a funcionalidade pronta e diz: "Bem, eu pensei que seria diferente". Se sim — bem-vindo ao mundo do BDD (Behaviour-Driven Development) — desenvolvimento orientado a comportamento. Não é apenas uma metodologia, mas uma ponte entre "quero que o botão seja verde" e "aqui está um teste que falha se o botão não for verde".
\n\nAo contrário do TDD (Test-Driven Development) clássico, onde pensamos em testes como verificação de funções, o BDD foca no comportamento do sistema do ponto de vista do usuário. No contexto de C++, isso é especialmente valioso: a linguagem é complexa, os projetos são enormes, e reescrever a lógica após um mal-entendido com o cliente é um prazer caro. O BDD em C++ ajuda a matar dois coelhos com uma cajadada só: obter documentação que até um gerente de projetos entende e um conjunto de testes automatizados que não deixam quebrar a lógica de negócio.
\n\nNeste artigo, vamos explorar como implementar behaviour-driven development em um projeto C++ real. Sem enrolação, com código e técnicas concretas.
\n\nFundamentos do BDD: a linguagem Gherkin e seu papel em C++
\n\nO coração do BDD são os cenários escritos na linguagem Gherkin. Eles se parecem com isto:
\n\nFuncionalidade: Transferência de fundos entre contas\n Cenário: Transferência bem-sucedida com saldo suficiente\n Dado que o usuário tem uma conta A com saldo de 1000 reais\n E o usuário tem uma conta B com saldo de 0 reais\n Quando o usuário transfere 500 reais da conta A para a conta B\n Então o saldo da conta A se torna 500 reais\n E o saldo da conta B se torna 500 reais\n\nSim, isso não é C++. Mas é aí que está a mágica: o cenário é escrito em linguagem humana e depois é "vinculado" ao código C++ real através de etapas (steps). Cada linha Dado, Quando, Então se transforma em uma função que chama suas classes e verifica os resultados.
Para C++, existem vários frameworks que trabalham com Gherkin. Os mais populares são:
\n\n- \n
- Catch2 com estilo BDD — leve, integrado ao Catch2, não requer parsers externos. \n
- Cucumber-CPP — implementação completa do Cucumber para C++, faz parsing de arquivos .feature diretamente. \n
- Boost.Test — também suporta sintaxe BDD-like, mas é menos flexível. \n
Pessoalmente, recomendo começar com Catch2: ele já está presente em 90% dos projetos C++, e para BDD não é necessário instalar nada adicional. Se o projeto for grande e precisar de integração com analistas de negócios — escolha Cucumber-CPP.
\n\nBDD com Catch2: escrevendo cenários diretamente no código
\n\nCatch2 fornece as macros SCENARIO, GIVEN, WHEN, THEN e AND_WHEN/AND_THEN. Não é Gherkin puro, mas o estilo é o mais próximo possível. Vamos escrever um teste para uma conta bancária simples.
Primeiro — a classe da conta:
\n\n// account.h\n#pragma once\n#include <string>\n#include <stdexcept>\n\nclass Account {\npublic:\n explicit Account(std::string owner, double initial_balance = 0.0)\n : owner_(std::move(owner)), balance_(initial_balance) {}\n\n void deposit(double amount) {\n if (amount <= 0) throw std::invalid_argument("Amount must be positive");\n balance_ += amount;\n }\n\n void withdraw(double amount) {\n if (amount > balance_) throw std::runtime_error("Insufficient funds");\n if (amount <= 0) throw std::invalid_argument("Amount must be positive");\n balance_ -= amount;\n }\n\n double balance() const { return balance_; }\n const std::string& owner() const { return owner_; }\n\nprivate:\n std::string owner_;\n double balance_ = 0.0;\n};\n\nE agora — o teste BDD usando Catch2:
\n\n// tes