Olá de novo. Antecipando o início do curso "Desenvolvedor C #", traduzimos material interessante sobre afirmar mensagens em testes e estamos felizes em compartilhar a tradução com você.
Neste post, falaremos sobre se você deve usar as mensagens Assert em seus testes.Recebi uma pergunta interessante de um colega leitor, sobre a qual gostaria de me aprofundar em mais detalhes:Tenho uma pergunta sobre Assert messages: devo usar a sobrecarga que contém o parâmetro message e usá-lo para enviar uma string descrevendo o motivo da falha de Assert (também "Declarações") ?A resposta a esta pergunta se resume a dois aspectos:- Legibilidade do teste - como é fácil entender o que o teste faz.
- Facilidade de diagnóstico - como é fácil entender por que o teste falha.
Vamos discutir cada um deles individualmenteLegibilidade do teste
As pessoas costumam usar as mensagens Assert para ajudar os membros da equipe e eles mesmos no futuro a entender o que está acontecendo no teste. Vejamos o seguinte exemplo:[Test]
public void Hiring_a_new_team_member()
{
var company = new Company();
var person = new Person(UserType.Customer);
company.HireNewMember(person);
Assert.AreEqual(UserType.Employee, person.Type);
Assert.AreEqual(1, company.NumberOfEmployees);
}
Em vez de uma declaração simples, você também pode indicar o motivo pelo qual a declaração de teste valida algo:[Test]
public void Hiring_a_new_team_member()
{
var company = new Company();
var person = new Person(UserType.Customer);
company.HireNewMember(person);
Assert.AreEqual(UserType.Employee, person.Type, "Person must become an employee after hiring");
Assert.AreEqual(1, company.NumberOfEmployees, "Number of employees must increase");
}
Tais declarações ajudam, mas têm um preço. Essas mensagens exigem que você- Gaste tempo escrevendo-os
- Mantenha-os seguindo em frente
Aqui, o conjunto de prós e contras é o mesmo dos comentários ao código. E, como no caso dos comentários, aconselho: não escreva mensagens de afirmação apenas para fins de legibilidade. Se você acha que o teste não é óbvio sem afirmar mensagens, tente refatorá-lo. A longo prazo, é mais fácil fazer o teste falar por si mesmo do que mantê-lo sincronizado com as mensagens de afirmação (e isso é apenas uma questão de tempo até que a sincronização seja interrompida).Insira as mensagens de afirmação somente quando absolutamente necessário - quando você não puder melhorar a legibilidade do teste de nenhuma outra maneira. Mas, mesmo assim, incline-se a optar por não escrevê-las.A maneira mais fácil de obter um ganho rápido na legibilidade do teste é mudar para um registro de instrução legível. Por exemplo, o NUnit possui um modelo de instrução especial baseado em restrições que ajuda você a escrever suas instruções da seguinte maneira:[Test]
public void Hiring_a_new_team_member()
{
var company = new Company();
var person = new Person(UserType.Customer);
company.HireNewMember(person);
Assert.That(person.Type, Is.EqualTo(UserType.Employee));
Assert.That(company.NumberOfEmployees, Is.EqualTo(1));
}
Ou você pode usar minhas afirmações fluentes favoritas :[Test]
public void Hiring_a_new_team_member()
{
var company = new Company();
var person = new Person(UserType.Customer);
company.HireNewMember(person);
person.Type.Should().Be(UserType.Employee);
company.NumberOfEmployees.Should().Be(1);
}
Essas instruções são lidas em inglês simples - exatamente da maneira que você deseja que todo o seu código seja lido. Nós, humanos, preferimos perceber informações na forma de histórias. Todas as histórias aderem a este modelo:[] [] [].
Por exemplo, .
Aqui
- o sujeito,
- a ação e
- o objeto. O mesmo vale para o código.Esta versãocompany.NumberOfEmployees.Should().Be(1);
lê melhor queAssert.AreEqual(1, company.NumberOfEmployees);
precisamente porque a história é traçada aqui., . , .
Outra visão das mensagens de afirmação é em termos de facilidade de diagnóstico. Em outras palavras, a simplicidade de entender a causa de uma falha no teste sem examinar o código desse teste. Isso é útil ao ler os resultados da montagem do IC.Do ponto de vista do diagnóstico, siga este guia: se você pode reiniciar facilmente o teste localmente, esse teste não precisará de uma mensagem de confirmação. Isso é válido para todos os testes de unidade (já que eles não funcionam com dependências fora de processo), mas em menor grau para testes de integração e de ponta a ponta.
Pirâmide de testeAo subir mais alto na pirâmide de teste, você pode precisar de informações mais detalhadas, porque os testes de integração (e especialmente de ponta a ponta) são mais lentos e você pode não ser capaz de executá-los novamente.Mas, mesmo com testes de integração e de ponta a ponta, há maneiras de facilitar o diagnóstico sem recorrer à declaração de mensagens:- Faça do teste um módulo de comportamento - quando um teste verifica uma coisa, geralmente é fácil determinar o que deu errado. (Isso nem sempre é aplicável aos testes de ponta a ponta, pois você pode querer que esses testes verifiquem como várias unidades de comportamento funcionam de perto).
- Nomear seus testes de unidade de acordo - O nome ideal do teste descreve o comportamento do aplicativo em termos comerciais, para que até um não programador possa entendê-lo.
E não esqueça que, mesmo sem as instruções do usuário, você ainda possui as mensagens que o ambiente de teste de unidade gera para você.Por exemplo, um erro na seguinte instrução:person.Type.Should().Be(UserType.Employee);
dá a seguinte mensagem de erro:Xunit.Sdk.EqualException: Assert.Equal() Failure
Expected: Employee
Actual: Customer
A combinação de tais mensagens geradas pelo ambiente e nomes de testes legíveis por humanos torna 90% das mensagens de afirmação do usuário inúteis, mesmo em termos de facilidade de diagnóstico. A única exceção são os longos testes de ponta a ponta. Eles geralmente contêm verificações em vários estágios; portanto, faz sentido usar mensagens de afirmação adicionais para entender qual das etapas falhou. No entanto, não deve haver muitos desses testes de ponta a ponta.Obviamente, para tirar proveito das mensagens de erro geradas pela estrutura, você precisa evitar comparações booleanas comuns, como:(person.Type == UserType.Employee).Should().BeTrue();
Porque eles levam à seguinte mensagem de erro:Xunit.Sdk.TrueException: Assert.True() Failure
Expected: True
Actual: False
O que não ajuda no diagnóstico.Sumário
Você costuma se sentir preguiçoso quando se trata de escrever declarações? Bem, agora você pode justificá-lo e enviar seus colegas para este artigo.
“Fico feliz que isso tenha um nome”Piadas à parte, no entanto, aqui está um resumo:- Existem dois aspectos no uso de mensagens de declaração:
- Legibilidade do teste (como é fácil entender o que o teste faz).
- Facilidade de diagnóstico (como é fácil entender por que o teste falha durante a criação do IC).
- Em termos de legibilidade de teste, as mensagens de asserção são comentários de código. Em vez de confiar neles, refatorar seu teste para obter legibilidade.
- Em termos de facilidade de diagnóstico, a melhor alternativa para afirmar mensagens é:
- Testando um único módulo de comportamento por um teste
- Nomeando testes em termos de negócios
- A única exceção são os longos testes de ponta a ponta.
Isso é tudo. Você pode aprender mais sobre o nosso curso no seminário on-line gratuito , que será realizado hoje.