Os resultados esperados de um teste de unidade devem ser codificados permanentemente ou podem depender de variáveis inicializadas? Os resultados codificados ou codificados aumentam o risco de introdução de erros no teste de unidade? Existem outros fatores que não considerei?
Por exemplo, qual desses dois é um formato mais confiável?
[TestMethod]
public void GetPath_Hardcoded()
{
MyClass target = new MyClass("fields", "that later", "determine", "a folder");
string expected = "C:\\Output Folder\\fields\\that later\\determine\\a folder";
string actual = target.GetPath();
Assert.AreEqual(expected, actual,
"GetPath should return a full directory path based on its fields.");
}
[TestMethod]
public void GetPath_Softcoded()
{
MyClass target = new MyClass("fields", "that later", "determine", "a folder");
string expected = "C:\\Output Folder\\" + string.Join("\\", target.Field1, target.Field2, target.Field3, target.Field4);
string actual = target.GetPath();
Assert.AreEqual(expected, actual,
"GetPath should return a full directory path based on its fields.");
}
EDIT 1: Em resposta à resposta do DXM, a opção 3 é uma solução preferida?
[TestMethod]
public void GetPath_Option3()
{
string field1 = "fields";
string field2 = "that later";
string field3 = "determine";
string field4 = "a folder";
MyClass target = new MyClass(field1, field2, field3, field4);
string expected = "C:\\Output Folder\\" + string.Join("\\", field1, field2, field3, field4);
string actual = target.GetPath();
Assert.AreEqual(expected, actual,
"GetPath should return a full directory path based on its fields.");
}
c#
unit-testing
Mão-E-Comida
fonte
fonte
Respostas:
Acho que calculamos os resultados do valor esperado em casos de teste mais robustos e flexíveis. Também usando bons nomes de variáveis na expressão que calcula o resultado esperado, fica muito mais claro de onde o resultado esperado veio em primeiro lugar.
Dito isto, no seu exemplo específico, NÃO confiaria no método "Softcoded" porque ele usa o seu SUT (sistema em teste) como entrada para seus cálculos. Se houver um erro no MyClass em que os campos não sejam armazenados corretamente, seu teste será aprovado porque o cálculo do valor esperado usará a string errada, como target.GetPath ().
Minha sugestão seria calcular o valor esperado onde faz sentido, mas verifique se o cálculo não depende de nenhum código do próprio SUT.
Em resposta à atualização do OP à minha resposta:
Sim, com base no meu conhecimento, mas com uma experiência um pouco limitada no TDD, eu escolheria a opção 3.
fonte
E se o código fosse o seguinte:
Seu segundo exemplo não pegaria o bug, mas o primeiro exemplo pegaria.
Em geral, eu recomendaria a codificação branda, pois ela pode ocultar bugs. Por exemplo:
Você consegue identificar o problema? Você não cometeria o mesmo erro em uma versão codificada. É mais difícil fazer os cálculos corretos do que os valores codificados. É por isso que prefiro trabalhar com valores codificados que com códigos codificados.
Mas há exceções. E se o seu código precisar ser executado no Windows e Linux? Não apenas o caminho precisa ser diferente, mas também deve ser usado separadores de caminho diferentes! Calcular o caminho usando funções que abstraem a diferença entre pode fazer sentido nesse contexto.
fonte
Na minha opinião, ambas as suas sugestões são inferiores ao ideal. A maneira ideal de fazer isso é esta:
Em outras palavras, o teste deve funcionar exclusivamente com base na entrada e na saída do objeto, e não com base no estado interno do objeto. O objeto deve ser tratado como uma caixa preta. (Eu desconsidero outros problemas, como a inadequação de usar string.Join em vez de Path.Combine, porque este é apenas um exemplo.)
fonte
target.Dispose(); Assert.IsTrue(target.IsDisposed);
(um exemplo muito simples.)Existem dois aspectos na discussão:
1. Usando o próprio destino para o caso de teste
A primeira pergunta é / você pode usar a própria classe para confiar e fazer parte do trabalho realizado no esboço de teste? - A resposta é NÃO , pois, em geral, você nunca deve assumir o código que está testando. Se isso não for feito corretamente, com o tempo os bugs se tornam imunes a alguns testes de unidade.
2. Você
deve codificar corretamente ? Mais uma vez a resposta é não . porque como qualquer software - a codificação da informação torna-se difícil quando as coisas evoluem. Por exemplo, quando você deseja que o caminho acima seja modificado novamente, você precisa escrever uma unidade adicional ou continuar modificando. Um método melhor é manter a data de entrada e avaliação derivada da configuração separada que pode ser facilmente adaptada.
por exemplo, aqui está como eu corrigiria o esboço de teste.
fonte
Existem muitos conceitos possíveis, fizemos alguns exemplos para ver a diferença
Para resumir: Em geral, seu primeiro teste apenas codificado faz mais sentido para mim porque é simples, direto ao ponto etc. Se você começar a codificar um caminho muitas vezes, basta colocá-lo no método de configuração.
Para mais testes estruturados futuros, eu verificaria as fontes de dados para que você possa adicionar mais linhas de dados se precisar de mais situações de teste.
fonte
Estruturas de teste modernas permitem fornecer parâmetros ao seu método. Eu aproveitaria esses:
Existem várias vantagens para isso, na minha opinião:
fonte