Escrevi alguns algoritmos de classificação para uma atribuição de classe e também escrevi alguns testes para garantir que os algoritmos fossem implementados corretamente. Meus testes têm apenas 10 linhas e existem 3 deles, mas apenas 1 linha muda entre os 3, portanto há muito código repetido. É melhor refatorar esse código para outro método que é chamado a partir de cada teste? Eu não precisaria escrever outro teste para testar a refatoração? Algumas das variáveis podem até ser movidas para o nível da classe. As classes e métodos de teste devem seguir as mesmas regras que as classes / métodos regulares?
Aqui está um exemplo:
[TestMethod]
public void MergeSortAssertArrayIsSorted()
{
int[] a = new int[1000];
Random rand = new Random(DateTime.Now.Millisecond);
for(int i = 0; i < a.Length; i++)
{
a[i] = rand.Next(Int16.MaxValue);
}
int[] b = new int[1000];
a.CopyTo(b, 0);
List<int> temp = b.ToList();
temp.Sort();
b = temp.ToArray();
MergeSort merge = new MergeSort();
merge.mergeSort(a, 0, a.Length - 1);
CollectionAssert.AreEqual(a, b);
}
[TestMethod]
public void InsertionSortAssertArrayIsSorted()
{
int[] a = new int[1000];
Random rand = new Random(DateTime.Now.Millisecond);
for (int i = 0; i < a.Length; i++)
{
a[i] = rand.Next(Int16.MaxValue);
}
int[] b = new int[1000];
a.CopyTo(b, 0);
List<int> temp = b.ToList();
temp.Sort();
b = temp.ToArray();
InsertionSort merge = new InsertionSort();
merge.insertionSort(a);
CollectionAssert.AreEqual(a, b);
}
givenThereAreProductsSet(amount)
e até tão simples quantoactWith(param)
. Consegui fazer isso com uma API fluente (por exemplogivenThereAre(2).products()
) uma vez, mas parei rapidamente porque parecia um exagero.Como Oded já disse, o código de teste ainda precisa ser mantido. Eu acrescentaria que a repetição no código de teste torna mais difícil para os mantenedores entender a estrutura dos testes e adicionar novos testes.
Nas duas funções que você postou, as seguintes linhas são absolutamente idênticas, exceto por uma diferença de espaço no início do
for
loop:Este seria um candidato perfeito para mudar para algum tipo de função auxiliar, cujo nome indica que está inicializando dados.
fonte
Não, não está ok. Você deve usar um TestDataBuilder . Você também deve cuidar da legibilidade de seus testes: a? 1000? b? Se amanhã for necessário trabalhar na implementação que você está testando, os testes são uma ótima maneira de entrar na lógica: escreva seus testes para seus colegas programadores, não para o compilador :)
Aqui está a sua implementação de testes, "renovada":
fonte
Ainda mais do que o código de produção, o código de teste precisa ser otimizado para facilitar a leitura e a manutenção, pois precisa ser mantido ao longo do código que está sendo testado e também lido como parte da documentação. Considere como o código copiado pode dificultar a manutenção do código de teste e como isso pode se tornar um incentivo para não escrever testes para tudo. Além disso, não esqueça que quando você escreve uma função para secar seus testes, ela também deve estar sujeita a testes.
fonte
Duplicar código para testes é uma armadilha fácil de cair. Claro que é conveniente, mas o que acontece se você começar a refatorar o código de implementação e todos os testes começarem a precisar mudar? Você corre os mesmos riscos que você, se duplicou seu código de implementação, pois provavelmente também precisará alterar seu código de teste em muitos lugares. Isso tudo gera muito tempo perdido e um número crescente de pontos de falha que precisam ser resolvidos, o que significa que o custo para manter seu software se torna desnecessariamente alto e, portanto, reduz o valor comercial geral do software que você trabalho em.
Considere também que o que é fácil de fazer nos testes se tornará fácil na implementação. Quando você pressiona pelo tempo e sob muito estresse, as pessoas tendem a confiar nos padrões de comportamento aprendidos e geralmente tentam fazer o que parece mais fácil no momento. Portanto, se você achar que recorta e cola muito do seu código de teste, é provável que faça o mesmo no código de implementação, e esse é um hábito que você deseja evitar no início de sua carreira, para economizar muito de dificuldade mais tarde, quando você precisar manter o código mais antigo que você escreveu e que sua empresa não pode necessariamente se dar ao luxo de reescrever.
Como já foi dito, você aplica o princípio DRY e procura oportunidades para refatorar quaisquer duplicações prováveis nos métodos e classes auxiliares; sim, você deve fazer isso nos testes para maximizar a reutilização do código e salvar você mesmo enfrentando dificuldades com a manutenção mais tarde. Você pode até se desenvolver lentamente uma API de teste que pode ser usada repetidamente, possivelmente até em vários projetos - certamente foi assim que as coisas aconteceram comigo nos últimos anos.
fonte