TDD Red-Green-Refactor e se / como testar métodos que se tornam privados


91

até onde eu entendo, a maioria das pessoas parece concordar que os métodos privados não devem ser testados diretamente, mas através de métodos públicos. Eu entendo o argumento deles, mas tenho alguns problemas com isso quando tento seguir as "Três Leis do TDD" e usar o ciclo "Vermelho - verde - refatorador". Eu acho que é melhor explicado por um exemplo:

No momento, preciso de um programa que possa ler um arquivo (contendo dados separados por tabulações) e filtrar todas as colunas que contêm dados não numéricos. Acho que provavelmente já existem algumas ferramentas simples disponíveis para fazer isso, mas decidi implementá-lo do zero, principalmente porque achei que poderia ser um projeto agradável e limpo para eu praticar um pouco com o TDD.

Então, primeiro, "coloco o chapéu vermelho", ou seja, preciso de um teste que falhe. Imaginei, precisarei de um método que encontre todos os campos não numéricos em uma linha. Então, eu escrevo um teste simples, é claro que ele falha na compilação imediatamente, então começo a escrever a função em si e, depois de alguns ciclos para frente e para trás (vermelho / verde), tenho uma função de trabalho e um teste completo.

Em seguida, continuo com uma função "gatherNonNumericColumns" que lê o arquivo, uma linha de cada vez, e chama minha função "findNonNumericFields" em cada linha para reunir todas as colunas que eventualmente devem ser removidas. Um par de ciclos vermelho-verde, e eu terminei, tendo novamente uma função de trabalho e um teste completo.

Agora, acho que devo refatorar. Como meu método "findNonNumericFields" foi projetado apenas porque achei que seria necessário ao implementar "gatherNonNumericColumns", parece-me que seria razoável permitir que "findNonNumericFields" se tornasse privado. No entanto, isso interromperia meus primeiros testes, pois eles não teriam mais acesso ao método que estavam testando.

Então, acabo com métodos particulares e um conjunto de testes que o testam. Como muitas pessoas aconselham que métodos privados não devem ser testados, parece que eu me pintei de canto aqui. Mas onde exatamente eu falhei?

Acho que poderia ter começado em um nível mais alto, escrevendo um teste que testa o que acabará se tornando meu método público (ou seja, findAndFilterOutAllNonNumericalColumns), mas isso parece um pouco contrário ao ponto inteiro do TDD (pelo menos de acordo com o tio Bob) : Que você deve alternar constantemente entre escrever testes e código de produção e que, a qualquer momento, todos os seus testes funcionaram no último minuto ou mais. Porque se eu começar escrevendo um teste para um método público, haverá vários minutos (ou horas ou mesmo dias em casos muito complexos) antes que eu obtenha todos os detalhes nos métodos privados para que o teste teste o público método passa.

Então o que fazer? O TDD (com o rápido ciclo de refator vermelho-verde) simplesmente não é compatível com métodos particulares? Ou há uma falha no meu design?



2
Essas duas funcionalidades são diferentes o suficiente para serem unidades diferentes - nesse caso, os métodos privados provavelmente devem estar em suas próprias classes - ou são a mesma unidade; nesse caso, não vejo por que você está escrevendo testes para comportamento interno da unidade. Em relação ao penúltimo parágrafo, não vejo o conflito. Por que você precisaria escrever um método privado complexo inteiro para passar em um caso de teste? Por que não expulsá-lo gradualmente através do método público, ou começar com ele em linha e depois extraí-lo?
precisa

26
Por que as pessoas usam expressões idiomáticas e clichês da programação de livros e blogs como diretrizes reais sobre como programar estão além de mim.
AK_

7
Não gosto do TDD exatamente por esse motivo: se você estiver em uma nova área, estará fazendo muito trabalho extra ao tentar descobrir como deve ser a arquitetura e como certas coisas funcionam. Por outro lado: se você está em uma área com a qual já tem experiência, será útil escrever os testes primeiro, além de incomodá-lo, porque o intellisense não entende por que você escreve código não compilável. Sou um fã muito maior de pensar sobre o design, escrevê-lo e testá-lo em unidade.
Jeroen Vannevel 15/04

1
"a maioria das pessoas parece concordar que os métodos privados não devem ser testados diretamente" - não, teste um método diretamente se fizer sentido. Esconda-o como privatese fizesse sentido.
Osa

Respostas:


44

Unidades

Acho que posso identificar exatamente onde o problema começou:

Imaginei, precisarei de um método que encontre todos os campos não numéricos em uma linha.

Isso deve ser seguido imediatamente com a pergunta "Será uma unidade testável separada gatherNonNumericColumnsou parte da mesma?"

Se a resposta for " sim, separe ", seu curso de ação será simples: esse método precisa ser público em uma classe apropriada, para que possa ser testado como uma unidade. Sua mentalidade é algo como "Eu preciso testar um método e também preciso testar outro método"

Pelo que você diz, você achou que a resposta é " não, faz parte da mesma ". Nesse ponto, seu plano não deve mais ser o de escrever e testar completamente e findNonNumericFields depois escrever gatherNonNumericColumns. Em vez disso, deve ser simplesmente escrever gatherNonNumericColumns. Por enquanto, findNonNumericFieldsdeve ser apenas uma parte provável do destino que você tem em mente ao escolher seu próximo caso de teste vermelho e refatorar. Desta vez, sua mentalidade é "Preciso testar um método e, enquanto faço isso, devo ter em mente que minha implementação final provavelmente incluirá esse outro método".


Mantendo um ciclo curto

O procedimento acima não deve levar aos problemas que você descreve em seu penúltimo parágrafo:

Porque se eu começar escrevendo um teste para um método público, haverá vários minutos (ou horas, ou mesmo dias em casos muito complexos) antes de obter todos os detalhes nos métodos privados para que o teste teste o público método passa.

Em nenhum momento, essa técnica exige que você escreva um teste vermelho que só ficará verde quando você implementar a totalidade findNonNumericFieldsdo zero. Muito provavelmente, findNonNumericFieldscomeçará como um código em linha no método público que você está testando, que será construído ao longo de vários ciclos e eventualmente extraído durante uma refatoração.


Roteiro

Para fornecer um roteiro aproximado para este exemplo em particular, não conheço os casos de teste exatos que você usou, mas diga que estava escrevendo gatherNonNumericColumnscomo seu método público. Então provavelmente os casos de teste seriam os mesmos para os quais você escreveu findNonNumericFields, cada um usando uma tabela com apenas uma linha. Quando esse cenário de uma linha foi totalmente implementado e você queria escrever um teste para forçar a extração do método, você escreveria um caso de duas linhas que exigiria a adição de sua iteração.


2
Eu acho que esta é a resposta aqui. Adotando o TDD em um ambiente OOP, muitas vezes me vejo tendo dificuldade em superar meus próprios instintos de baixo para cima. Sim, as funções devem ser pequenas, mas depois da refatoração. Antes, eles podem ser enormes monólitos. +1
João Mendes

2
@ JoãoMendes Bem, não tenho certeza se você deve chegar ao estado de um enorme monólito antes de refatorar, especialmente em ciclos RGR muito curtos. Mas sim, dentro de uma unidade testável, trabalhar de baixo para cima pode levar aos problemas descritos pelo OP.
precisa

1
OK, acho que entendo onde deu errado agora. Muito obrigado a todos vocês (marcado esta como a resposta, mas a maioria das outras respostas são igualmente útil também)
Henrik Berg

66

Muitas pessoas pensam que o teste de unidade é baseado em métodos; não é. Deve ser baseado na menor unidade que faz sentido. Para a maioria das coisas, isso significa que a classe é o que você deve testar como uma entidade inteira. Não métodos individuais nele.

Agora, obviamente, você chamará métodos na classe, mas você deve pensar nos testes como aplicando-se ao objeto de caixa preta que possui, para poder ver que quaisquer operações lógicas que sua classe ofereça; estas são as coisas que você precisa testar. Se sua classe é tão grande que a operação lógica é muito complexa, você tem um problema de design que deve ser corrigido primeiro.

Uma classe com mil métodos pode parecer testável, mas se você testar apenas cada método individualmente, não estará realmente testando a classe. Algumas classes podem precisar estar em um determinado estado antes que um método seja chamado, por exemplo, uma classe de rede que precisa de uma conexão configurada antes de enviar dados. O método de envio de dados não pode ser considerado independentemente de toda a classe.

Portanto, você deve ver que os métodos privados são irrelevantes para o teste. Se você não pode exercitar seus métodos particulares chamando a interface pública de sua classe, esses métodos privados são inúteis e não serão usados ​​de qualquer maneira.

Acho que muitas pessoas tentam transformar métodos privados em unidades testáveis ​​porque parece fácil executar testes para elas, mas isso leva a granularidade do teste muito longe. Martin Fowler diz

Embora eu comece com a noção de que a unidade é uma classe, geralmente tomo um monte de classes estreitamente relacionadas e as trato como uma única unidade

o que faz muito sentido para um sistema orientado a objetos, objetos sendo projetados para serem unidades. Se você quiser testar métodos individuais, talvez esteja criando um sistema procedural como C ou uma classe composta inteiramente de funções estáticas.


14
Para mim, parece que essa resposta ignora completamente a abordagem TDD na pergunta do OP. É apenas uma repetição do mantra "não teste métodos privados", mas não explica como o TDD - que é realmente baseado em métodos - pode funcionar com uma abordagem de teste de unidade não baseada em métodos.
Doc Brown

6
@DocBrown não, responde-o completamente ao dizer "não exagere em excesso" suas unidades e dificulta a vida de si mesmo. TDD é não método baseado, é unidade de base, onde uma unidade é tudo o que faz sentido. Se você possui uma biblioteca C, sim, cada unidade será uma função. Se você tem uma classe, a unidade é um objeto. Como Fowler diz, às vezes uma unidade tem várias classes fortemente relacionadas. Eu acho que muitas pessoas consideram o teste de unidade método por método simplesmente porque algumas ferramentas burras geram stubs com base em métodos.
Gbjbaanb

3
@gbjbaanb: tente sugerir um teste que permita ao OP implementar seus "reunir campos não numéricos em uma linha" usando primeiro o TDD puro, sem ter a interface pública da classe que ele pretende escrever já escrita.
Doc Brown

8
Eu tenho que concordar com @DocBrown aqui. O problema do questionador não é que ele deseja mais granularidade de teste do que pode obter sem testar métodos privados. É que ele tentou seguir uma abordagem estrita do TDD e - sem planejamento como tal - o levou a bater em uma parede onde de repente ele descobre que tem vários testes para o que deveria ser um método privado. Esta resposta não ajuda nisso. É uma boa resposta para algumas perguntas, mas não essa.
precisa

7
@ Matthew: Seu erro é que ele escreveu a função em primeiro lugar. Idealmente, ele deveria ter escrito o método público como código espaguete e depois refatorado para uma função privada no ciclo de refatoração - não marcado como privado no ciclo de refatoração.
slebetman

51

O fato de seus métodos de coleta de dados serem suficientemente complexos para merecer testes e se separarem o suficiente de seu objetivo principal para serem métodos próprios, e não parte de alguns pontos de loop da solução: torne esses métodos não privados, mas membros de alguma outra classe que fornece funcionalidade de coleta / filtragem / tabulação.

Em seguida, você escreve testes para os aspectos estúpidos de troca de dados da classe auxiliar (por exemplo, "distinguir números de caracteres") em um local e testa seu objetivo principal (por exemplo, "obter os números de vendas") em outro local, e você não é necessário repetir testes básicos de filtragem nos testes para sua lógica comercial normal.

Geralmente, se sua classe que faz uma coisa contém código extenso para fazer outra coisa necessária, mas separada de seu objetivo principal, esse código deve viver em outra classe e ser chamado por métodos públicos. Ele não deve estar oculto nos cantos particulares de uma classe que contém acidentalmente esse código. Isso melhora a testabilidade e a compreensão ao mesmo tempo.


Sim, eu concordo com você. Mas eu tenho um problema com sua primeira declaração, tanto a parte "suficientemente complexa" quanto a parte "suficientemente separada". Em relação ao "suficientemente complexo": estou tentando fazer um ciclo rápido de verde-vermelho, o que significa que só posso codificar por no máximo um minuto por vez antes de mudar para o teste (ou o contrário). Isso significa que meus testes serão muito detalhados. Achei que essa era uma das vantagens do TDD, mas talvez eu tenha exagerado, para que se torne uma desvantagem.
Henrik Berg

Sobre "separar o suficiente": eu aprendi (novamente com o tiobob) que as funções devem ser pequenas e que devem ser menores que isso. Então, basicamente, eu tento fazer funções de 3-4 linhas. Portanto, mais ou menos toda a funcionalidade é separada em métodos próprios, não importa quão pequena e simples.
Henrik Berg

De qualquer forma, sinto que os aspectos de troca de dados (por exemplo, findNonNumericFields) devem ser realmente particulares. E se eu separá-lo em outra classe, terei que torná-lo público de qualquer maneira, para que eu não entenda exatamente o que é isso.
Henrik Berg

6
O @HenrikBerg pensa por que você tem objetos em primeiro lugar - eles não são maneiras convenientes de agrupar funções, mas são unidades independentes que facilitam o trabalho com sistemas complexos. Portanto, você deve pensar em testar a classe como uma coisa.
Gbjbaanb

@gbjbaanb Eu diria que ambos são o mesmo.
precisa

29

Pessoalmente, sinto que você foi muito longe na mentalidade de implementação quando escreveu os testes. Você assumiu que precisaria de certos métodos. Mas você realmente precisa que eles façam o que a classe deve fazer? A turma falharia se alguém aparecesse e os refatorasse internamente? Se você estivesse usando a classe (e essa deveria ser a mentalidade do testador na minha opinião), você realmente se importaria menos se houver um método explícito para verificar números.

Você deve testar a interface pública de uma classe. A implementação privada é privada por um motivo. Não faz parte da interface pública porque não é necessário e pode mudar. É um detalhe de implementação.

Se você escrever testes na interface pública, nunca encontrará o problema que encontrou. Você pode criar casos de teste para a interface pública que abrangem seus métodos particulares (ótimo) ou não é possível. Nesse caso, talvez seja hora de pensar muito sobre os métodos privados e talvez descartá-los completamente, se não puderem ser alcançados.


1
"Detalhes da implementação" são coisas como "usei uma variável temporária ou XOR para trocar ints entre variáveis". Métodos protegidos / privados têm contratos, como qualquer outra coisa. Eles recebem entrada, trabalham com ela e produzem alguma saída, sob certas restrições. Em última análise, qualquer coisa com um contrato deve ser testada - não necessariamente para quem consome sua biblioteca, mas para quem a mantém e modifica depois de você. Só porque não é "público" não significa que não faz parte de uma API.
Knetic

11

Você não faz TDD com base no que espera que a classe faça internamente.

Seus casos de teste devem se basear no que a classe / funcionalidade / programa tem que fazer com o mundo externo. No seu exemplo, o usuário chamará sua classe de leitor com parafind all the non-numerical fields in a line?

Se a resposta for "não", é um teste ruim para escrever em primeiro lugar. Você deseja escrever o teste sobre a funcionalidade no nível de classe / interface - e não no nível "o que o método de classe precisará implementar para que isso funcione", que é o seu teste.

O fluxo do TDD é:

  • vermelho (o que a classe / objeto / função / etc está fazendo com o mundo externo)
  • verde (escreva o código mínimo para que essa função externa do mundo funcione)
  • refator (qual é o melhor código para fazer isso funcionar)

NÃO é necessário "porque precisarei do X no futuro como método privado, deixe-me implementá-lo e testá-lo primeiro". Se você estiver fazendo isso, está fazendo o estágio "vermelho" incorretamente. Esse parece ser o seu problema aqui.

Se você se encontra frequentemente escrevendo testes para métodos que se tornam métodos privados, está fazendo uma de algumas coisas:

  • Não entender corretamente os casos de uso de interface / nível público o suficiente para escrever um teste para eles
  • Mudando drasticamente o seu design e refatorando vários testes (o que pode ser uma boa coisa, dependendo se essa funcionalidade é testada em testes mais recentes)

9

Você está encontrando um equívoco comum com os testes em geral.

A maioria das pessoas que são novas nos testes começa a pensar assim:

  • escreva um teste para a função F
  • implementar F
  • escreva um teste para a função G
  • implementar G usando uma chamada para F
  • escreva um teste para uma função H
  • implementar H usando uma chamada para G

e assim por diante.

O problema aqui é que, de fato, você não possui um teste de unidade para a função H. O teste que deveria testar H, na verdade, está testando H, G e F ao mesmo tempo.

Para resolver isso, você deve perceber que as unidades testáveis ​​nunca devem depender umas das outras, mas de suas interfaces . No seu caso, onde as unidades são funções simples, as interfaces são apenas sua assinatura de chamada. Portanto, você deve implementar G de tal maneira que possa ser usado com qualquer função com a mesma assinatura que F.

Como exatamente isso pode ser feito depende da sua linguagem de programação. Em muitos idiomas, você pode passar funções (ou ponteiros para eles) como argumentos para outras funções. Isso permitirá que você teste cada função isoladamente.


3
Eu gostaria de poder votar isso muitas mais vezes. Resumindo, você não arquitetou sua solução corretamente.
23415 Justin Ohms

Em uma linguagem como C, isso faz sentido, mas para linguagens OO nas quais a unidade geralmente deve ser uma classe (com métodos públicos e privados), você deve testar a classe, e não todos os métodos privados isoladamente. Isolando suas aulas, sim. Isolando os métodos em cada classe, não.
Gbjbaanb

8

Os testes que você escreve durante o Test Driven Development devem garantir que uma classe implemente corretamente sua API pública, enquanto simultaneamente garantem que essa API pública seja fácil de testar e usar.

Você pode, por todos os meios, usar métodos privados para implementar essa API, mas não há necessidade de criar testes por meio do TDD - a funcionalidade será testada porque a API pública funcionará corretamente.

Agora, suponha que seus métodos privados sejam complicados o suficiente para merecer testes independentes - mas não fazem sentido como parte da API pública da sua classe original. Bem, isso provavelmente significa que eles realmente devem ser métodos públicos em alguma outra classe - uma que sua classe original aproveita em sua própria implementação.

Ao testar apenas a API pública, você está facilitando muito a modificação dos detalhes da implementação no futuro. Os testes inúteis só o incomodam mais tarde quando precisam ser reescritos para oferecer suporte a alguma refatoração elegante que você acabou de descobrir.


4

Eu acho que a resposta certa é a conclusão que você chegou sobre o início dos métodos públicos. Você começaria escrevendo um teste que chama esse método. Falha na criação de um método com esse nome que não faz nada. Então você pode corrigir um teste que verifica se há um valor de retorno.

(Não estou totalmente claro quanto ao que sua função faz. Ele retorna uma sequência com o conteúdo do arquivo com os valores não numéricos eliminados?)

Se o seu método retornar uma string, você verificará esse valor de retorno. Então você apenas continua construindo.

Eu acho que tudo o que acontece em um método privado deve estar no método público em algum momento durante o processo e, em seguida, somente foi movido para o método privado como parte de uma etapa de refatoração. A refatoração não exige testes com falha, até onde eu sei. Você só precisa falhar nos testes ao adicionar funcionalidade. Você só precisa executar seus testes após o refator para garantir que todos sejam aprovados.


3

parece que eu me pintei em um canto aqui. Mas onde exatamente eu falhei?

Há um velho ditado.

Quando você não planeja, planeja falhar.

As pessoas parecem pensar que, quando você faz TDD, você apenas senta, escreve testes e o design simplesmente acontece magicamente. Isso não é verdade. Você precisa ter um plano de alto nível. Descobri que obtive meus melhores resultados com o TDD ao projetar a interface (API pública) primeiro. Pessoalmente, crio um real interfaceque define a classe primeiro.

suspiro Eu escrevi um "código" antes de escrever qualquer teste! Bem não. Eu não fiz. Escrevi um contrato a ser seguido, um design . Suspeito que você possa obter resultados semelhantes anotando um diagrama UML em papel milimétrico. O ponto é que você deve ter um plano. O TDD não é uma licença para piratear um pedaço de código.

Eu realmente sinto que "Test First" é um nome impróprio. Design Primeiro , teste.

Obviamente, siga os conselhos de outras pessoas sobre como extrair mais classes do seu código. Se você sentir fortemente a necessidade de testar os internos de uma classe, extraia esses internos em uma unidade facilmente testada e injete-a.


2

Lembre-se de que os testes também podem ser refatorados! Se você tornar um método privado, estará reduzindo a API pública e, portanto, é perfeitamente aceitável jogar fora alguns testes correspondentes para essa "funcionalidade perdida" (AKA reduziu a complexidade).

Outros disseram que seu método privado será chamado como parte de outros testes de API ou será inacessível e, portanto, deletável. De fato, as coisas são mais refinadas se pensarmos nos caminhos de execução .

Por exemplo, se tivermos um método público que realiza divisão, podemos querer testar o caminho que resulta em divisão por zero. Se tornarmos o método privado, teremos uma escolha: podemos considerar o caminho da divisão por zero ou podemos eliminá-lo, considerando como é chamado pelos outros métodos.

Dessa forma, podemos jogar fora alguns testes (por exemplo, dividir por zero) e refatorar os outros em termos da API pública restante. Obviamente, em um mundo ideal, os testes existentes cuidam de todos os caminhos restantes, mas a realidade é sempre um compromisso;)


1
Enquanto as outras respostas estão corretas, pois o método privado não deveria ter sido escrito no ciclo vermelho, os humanos cometem erros. E quando você seguiu o caminho do erro suficientemente longe, esta é a solução apropriada.
slebetman

2

Há momentos em que um método privado pode se tornar um método público de outra classe.

Por exemplo, você pode ter métodos particulares que não são seguros para threads e deixar a classe em um estado temporário. Esses métodos podem ser movidos para uma classe separada, que é realizada em particular pela sua primeira classe. Portanto, se sua classe for uma Fila, você poderá ter uma classe InternalQueue com métodos públicos, e a classe Queue manterá a instância InternalQueue em particular. Isso permite testar a fila interna e também esclarece quais são as operações individuais no InternalQueue.

(Isso é mais óbvio quando você imagina que não havia classe List e se você tentou implementar as funções List como métodos privados na classe que os utiliza.)


2
"Há momentos em que um método privado pode se tornar um método público de outra classe." Não posso enfatizar isso o suficiente. Às vezes, um método privado é simplesmente outra classe gritando por sua própria identidade.

0

Eu me pergunto por que seu idioma tem apenas dois níveis de privacidade, totalmente público e completamente privado.

Você pode organizar seus métodos não públicos como acessíveis por pacotes ou algo assim? Em seguida, coloque seus testes no mesmo pacote e aproveite para testar o funcionamento interno que não faz parte da interface pública. Seu sistema de compilação excluirá testes ao criar um binário de versão.

É claro que às vezes você precisa ter métodos verdadeiramente privados, não acessíveis a nada além da classe que define. Espero que todos esses métodos sejam muito pequenos. Em geral, manter os métodos pequenos (por exemplo, abaixo de 20 linhas) ajuda muito: testar, manter e apenas entender o código se torna mais fácil.


3
Alterar um modificador de acesso ao método apenas para executar testes é uma situação em que uma cauda mexe com um cachorro. Acho que testar partes internas de uma unidade está dificultando a refatoração mais tarde. Testar a interface pública, pelo contrário, é ótimo porque funciona como um "contrato" para uma unidade.
scriptin

Você não precisa alterar o nível de acesso de um método. O que estou tentando dizer é que você tem um nível de acesso intermediário que permite escrever certo código, incluindo testes, mais fácil, sem fazer um contrato público. É claro que você precisa testar a interface pública, mas, além disso, às vezes é benéfico testar parte do funcionamento interno isoladamente.
9000

0

Ocasionalmente, troquei métodos privados para protegidos para permitir testes mais refinados (mais rigorosos que a API pública exposta). Essa deve ser a exceção (espero que muito rara) e não a regra, mas pode ser útil em certos casos específicos que você pode encontrar. Além disso, isso é algo que você não gostaria de considerar ao criar uma API pública, mais "truques" que se pode usar no software de uso interno nessas raras situações.


0

Eu experimentei isso e senti sua dor.

Minha solução foi:

pare de tratar testes como construir um monólito.

Lembre-se de que quando você escreve um conjunto de testes, digamos 5, para eliminar algumas funcionalidades, não precisa manter todos esses testes por perto , especialmente quando isso se torna parte de outra coisa.

Por exemplo, muitas vezes tenho:

  • teste de baixo nível 1
  • código para encontrá-lo
  • teste de baixo nível 2
  • código para encontrá-lo
  • teste de baixo nível 3
  • código para encontrá-lo
  • teste de baixo nível 4
  • código para encontrá-lo
  • teste de baixo nível 5
  • código para encontrá-lo

então eu tenho

  • teste de baixo nível 1
  • teste de baixo nível 2
  • teste de baixo nível 3
  • teste de baixo nível 4
  • teste de baixo nível 5

No entanto, se agora adicionar funções de nível superior que a chamam, com muitos testes, agora posso reduzir os testes de baixo nível para:

  • teste de baixo nível 1
  • teste de baixo nível 5

O diabo está nos detalhes e a capacidade de fazer isso dependerá das circunstâncias.


-2

O sol gira em torno da terra ou a terra em torno do sol? De acordo com Einstein, a resposta é sim, ou ambos, como os dois modelos diferem apenas pelo ponto de vista, da mesma forma o encapsulamento e o desenvolvimento orientado a testes estão apenas em conflito porque pensamos que estão. Ficamos sentados aqui, como Galileu e o papa, lançando insultos uns aos outros: tolo, você não vê que métodos privados também precisam ser testados; herege, não quebre o encapsulamento! Da mesma forma, quando reconhecemos que a verdade é maior do que pensávamos, podemos tentar algo como encapsular os testes para as interfaces privadas, para que os testes para as interfaces públicas não quebrem o encapsulamento.

Tente o seguinte: adicione dois métodos, um que não tem entrada, mas apenas retorna o número de testes particulares e outro que aceita um número de teste como parâmetro e retorna aprovado / reprovado.


1
Os insultos escolhidos foram utilizados por Galileu e O Papa, e não por qualquer resposta a essa pergunta.
Hildred 18/04
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.