Estou aprendendo TDD usando c #, tanto quanto sei que o teste deve impulsionar o desenvolvimento , ou seja, primeiro escreva um teste com falha depois de escrever o código mínimo para passar no teste e refatorar.
Mas também é dito que " Programa para Interface, não Implementação ", então escreva uma interface primeiro . É aqui que começa a minha confusão: se estou escrevendo a Interface primeiro, está violando duas coisas
O código que é escrito para a interface não é conduzido pelo teste .
Não é o mínimo, obviamente, eu posso escrever com uma classe simples.
Devo começar escrevendo testes para a interface também? sem nenhuma implementação, o que vou testar?
Se esta pergunta parece bobagem, desculpe-me por isso, mas estou totalmente confuso. Pode ser que eu esteja levando as coisas muito literalmente.
fonte
interface
para tudo. Aclass
também fornece uma interface, porque você pode ocultar os detalhes da implementação emprivate
variáveis.contract
. Isso pode estar na forma de uma classe abstrata, por exemplo, embora não deva ser uma classe / método virtual porque você não pode instanciar.Respostas:
Sua primeira violação ("O código escrito para a interface não é conduzido pelo teste.") Não é válido. Vamos usar um exemplo trivial. Suponha que você esteja escrevendo uma aula de calculadora e escrevendo uma operação de adição. Que teste você pode escrever?
Seu teste acabou de definir a interface. É o
add
método, vê?add
recebe dois argumentos e retorna sua soma. Posteriormente, você pode determinar que precisa de várias calculadoras e extrair uma interface Java (nesse caso) naquele momento. Seus testes não devem mudar, pois você testou a interface pública dessa classe.Em um nível mais teórico, os testes são a especificação executável de um sistema. As interfaces para um sistema devem ser conduzidas pelos usuários desse sistema, e os testes são o primeiro método que você precisa para definir interações.
Não acho que você possa separar o design da interface do design de teste. Definir interações e projetar testes para elas é a mesma operação mental - quando envio essas informações para uma interface, espero um certo resultado. Quando algo está errado com a minha entrada, espero esse erro. Você pode fazer esse trabalho de design em papel e depois escrever seus testes a partir disso, ou pode fazê-los ao mesmo tempo - isso realmente não importa.
fonte
new Calculator()
a implementação está correta? Se for necessária uma nova implementação, talvez você faça um MultiplicationCalculator e precise alterar o teste paranew AdditionCalculator()
que ele ainda passe? Ou eu estou esquecendo de alguma coisa ?O que estamos fazendo quando escrevemos um
interface
? Estamos escrevendo código ou estamos criando?Não sou fã da noção de Design Orientado a Testes, mas adoro o Desenvolvimento Orientado a Testes . Pessoalmente, obtive meus melhores resultados ao projetar a classe com antecedência, projetando a interface antes de escrever um teste. Não conto a interface como código. A interface é um design que implementarei usando TDD. É provável que mude e evolua conforme eu trabalho, mas é o meu roteiro (junto com a minha lista de testes).
Vou parar antes de começar a reclamar, mas espero que seja uma maneira útil de você pensar sobre isso.
fonte
Tudo depende de quão ortodoxo / religioso você deseja fazer TDD .
Como você está aprendendo, experimente obter um fluxo de trabalho pessoal, que funcione para você.
Se você quiser fazer isso de acordo com os livros , escreva primeiro um teste, o que obviamente falhará, porque você está começando com nenhum código. Então você escreve algum código para fazer o teste passar. Se isso for feito, você poderá refatorar o código existente, pois você tem um teste que fornece algum tipo de rede de segurança para refatorações. Decidir usar uma interface é algum tipo de refatoração.
Além do TDD ou não: A questão de usar uma interface ou não não é interessante em primeiro lugar. É claro que, se você tiver certeza, tem um comportamento diferente que deseja espalhar por vários objetos, faz sentido pensar em usar uma Interface: Por exemplo, se você tem algum tipo de saída para destinos diferentes, faz sentido implementá-la via uma interface Writer e possui classes diferentes para a saída ( FileWriter , Printer etc.). Embora seja comum dizer para escrever em uma interface , isso não significa: use uma interface para tudo . Às vezes, é um nível de indireção para muito. Btw. o mesmo vale para serviços. Mas esse é um tópico diferente.
Por outro lado, você pode desenvolver testes conduzidos de outra maneira: crie seu código para testabilidade. O que significa que você escreve código, que é fácil de testar - embora você escreva os testes posteriormente . Não importa se você escreve testes antecipadamente ou depois, desde que faça testes de qualquer maneira.
fonte
TDD ou BDD significaria primeiro fazer as interfaces de domínio e depois escrever testes contra eles pela minha interpretação. a implementação de uma interface tem um comportamento esperado.
ainda é teste antes do código, porque uma interface não contém lógica testável; é a estrutura na qual você escreve um teste.
Eu faria da seguinte maneira
Escreva o comportamento semi-formal (dado: quando: então :)
Escreva a interface (para hospedar o método de encapsulamento de comportamento)
Escreva o teste que ele identifica (insira o dado, chame o quando, teste o então)
Escreva / altere o concreto (classe que implementa a interface) para passar no teste
fonte
Nunca escreva testes antes de projetar as interfaces. Ao pensar em quais tipos de testes escrever (design de teste), você também não deve simultaneamente projetar (arquitetar) seu aplicativo. Não pense em duas coisas ao mesmo tempo. Você já ouviu falar de separação de preocupações? Isso se aplica não apenas à estrutura física do seu código, mas também ao seu processo de pensamento.
Decida como seu aplicativo deve ser projetado primeiro. Isso significa que você projeta suas interfaces e os relacionamentos entre essas interfaces. Até que você tenha feito isso, não deve começar a pensar em testes. Depois de saber quais são suas interfaces, você pode primeiro criá-las e, em seguida, escrever testes contra elas ou escrever testes primeiro e depois criá-las. Neste último caso, obviamente, você não poderá compilar os testes. Não vejo nenhum dano nem qualquer violação da filosofia TDD na criação das interfaces antes dos testes.
fonte
interface
palavra-chave C # , não ao termo geral "interface".Não há problema em escrever a interface / código / teste ao mesmo tempo, desde que a incorporação ao projeto seja atômica.
A menos que seu chefe seja religioso sobre TDD, nesse caso, você provavelmente precisará escrever uma interface vazia -> teste -> código mínimo (etapa inútil) -> mais testes -> mais código inútil -> mais testes -> finalmente, escrever o código real - > pronto.
fonte