Em relação ao padrão de teste clássico de Arrange-Act-Assert , frequentemente me pego adicionando uma contra-afirmação que antecede a Act. Dessa forma, eu sei que a afirmação que passa está realmente passando como resultado da ação.
Eu penso nisso como análogo ao vermelho em red-green-refactor, onde somente se eu tiver visto a barra vermelha no decorrer do meu teste, eu sei que a barra verde significa que escrevi um código que faz a diferença. Se eu escrever um teste de aprovação, qualquer código o satisfará; da mesma forma, com relação a Arrange-Assert-Act-Assert, se minha primeira afirmação falhar, eu sei que qualquer ato teria sido aprovado na Assert final - de modo que não estava realmente verificando nada sobre a lei.
Seus testes seguem esse padrão? Por que ou por que não?
Esclarecimento da atualização : a afirmação inicial é essencialmente o oposto da afirmação final. Não é uma afirmação de que Arrange funcionou; é uma afirmação de que Act ainda não funcionou.
fonte
Também pode ser especificado como Arrange- Assume -Act -Assert.
Há um identificador técnico para isso no NUnit, como no exemplo aqui: http://nunit.org/index.php?p=theory&r=2.5.7
fonte
Aqui está um exemplo.
Pode ser que eu tenha escrito
Range.includes()
simplesmente para retornar verdadeiro. Não o fiz, mas posso imaginar que sim. Ou eu poderia ter escrito errado de várias outras maneiras. Eu esperava e esperava que com TDD eu realmente acertasse - issoincludes()
simplesmente funciona - mas talvez não. Portanto, a primeira afirmação é uma verificação de sanidade, para garantir que a segunda afirmação seja realmente significativa.Lido por si mesmo,
assertTrue(range.includes(7));
está dizendo: "afirmar que o intervalo modificado inclui 7". Lido no contexto da primeira asserção, está dizendo: "afirme que invocar encompass () faz com que inclua 7. E uma vez que engloba é a unidade que estamos testando, acho que tem algum valor (pequeno).Estou aceitando minha própria resposta; muitos outros interpretaram mal minha pergunta como sendo sobre testar a configuração. Eu acho que isso é um pouco diferente.
fonte
Um
Arrange-Assert-Act-Assert
teste sempre pode ser refatorado em dois testes:e
O primeiro teste só fará valer o que foi configurado na fase de arranjo, e o segundo teste só valerá o que aconteceu na fase de ato.
Isso tem a vantagem de dar um feedback mais preciso sobre se foi a fase de arranjo ou ação que falhou, enquanto no original
Arrange-Assert-Act-Assert
eles estão combinados e você teria que cavar mais fundo e examinar exatamente qual afirmação falhou e por que falhou para saber se foi o arranjo ou ato que falhou.Também satisfaz a intenção de testar melhor a unidade, pois você está separando o teste em unidades independentes menores.
Por último, tenha em mente que sempre que você vir seções similares de Arrange em diferentes testes, você deve tentar puxá-las para métodos auxiliares compartilhados, de modo que seus testes sejam mais DRY e mais fáceis de manter no futuro.
fonte
Agora estou fazendo isso. AAAA de um tipo diferente
Exemplo de um teste de atualização:
O motivo é que o ACT não contém a leitura do ReadUpdated é porque ele não faz parte do ato. O ato é apenas mudar e salvar. Então, realmente, ARRANGE ReadUpdated for assertion, estou chamando ASSEMBLE para assertion. Isso evita confundir a seção ARRANGE
ASSERT deve conter apenas asserções. Isso deixa ASSEMBLE entre ACT e ASSERT, que configura a declaração.
Por último, se você está falhando no Arrange, seus testes não estão corretos porque você deve ter outros testes para prevenir / encontrar esses bugs triviais . Porque para o cenário que apresento, já deve haver outros testes que testam READ e CREATE. Se você criar uma "Asserção de Guarda", pode estar interrompendo o DRY e criando manutenção.
fonte
Lançar uma declaração de "verificação de integridade" para verificar o estado antes de executar a ação que está testando é uma técnica antiga. Eu geralmente os escrevo como um andaime de teste para provar a mim mesmo que o teste faz o que eu espero, e os removo mais tarde para evitar testes complicados com o andaime de teste. Às vezes, deixar o scaffolding ajuda o teste a servir de narrativa.
fonte
Eu já li sobre essa técnica - possivelmente de você btw - mas não a uso; principalmente porque estou acostumado com o formulário triplo A para meus testes de unidade.
Agora, estou ficando curioso e tenho algumas perguntas: como você escreve seu teste, você faz com que essa afirmação falhe, seguindo um ciclo red-green-red-green-refactor, ou você adiciona depois?
Você falha às vezes, talvez depois de refatorar o código? O que isso diz a você ? Talvez você possa dar um exemplo em que ajudou. Obrigado.
fonte
Já fiz isso antes, ao investigar um teste que falhou.
Depois de coçar a cabeça consideravelmente, concluí que a causa eram os métodos chamados durante "Arrange" não estavam funcionando corretamente. A falha do teste foi enganosa. Eu adicionei um Assert após o arranjo. Isso fez com que o teste falhasse em um local que destacava o problema real.
Acho que também há um cheiro de código aqui se a parte Organizar do teste for muito longa e complicada.
fonte
Em geral, gosto muito de "Organizar, agir, afirmar" e usar isso como meu padrão pessoal. A única coisa que não me lembra de fazer, no entanto, é desorganizar o que arranjei quando as afirmações forem feitas. Na maioria dos casos, isso não causa muito aborrecimento, já que a maioria das coisas desaparecem automaticamente por meio da coleta de lixo, etc. Se você estabeleceu conexões com recursos externos, no entanto, provavelmente desejará fechar essas conexões quando terminar com suas afirmações ou você tem um servidor ou recurso caro por aí em algum lugar segurando conexões ou recursos vitais que deveria ser capaz de ceder para outra pessoa. Isso é particularmente importante se você um daqueles desenvolvedores que não usa TearDown ou TestFixtureTearDownpara limpar após um ou mais testes. Claro, "Arrange, Act, Assert" não é responsável por minha falha em fechar o que abro; Eu só mencionei esse "pegadinha" porque ainda não encontrei um bom sinônimo de "palavra A" para "dispor" para recomendar! Alguma sugestão?
fonte
Dê uma olhada na entrada da Wikipedia sobre Design by Contract . A sagrada trindade Arrange-Act-Assert é uma tentativa de codificar alguns dos mesmos conceitos e é sobre como provar a correção do programa. Do artigo:
Existe uma compensação entre a quantidade de esforço despendido na configuração e o valor que isso agrega. AAA é um lembrete útil para as etapas mínimas necessárias, mas não deve desencorajar ninguém de criar etapas adicionais.
fonte
Depende do seu ambiente / idioma de teste, mas geralmente se algo na parte Arrange falhar, uma exceção é lançada e o teste falha exibindo-o em vez de iniciar a parte Act. Então, não, eu geralmente não uso uma segunda parte Assert.
Além disso, no caso de sua parte Arrange ser bastante complexa e nem sempre lançar uma exceção, talvez você possa considerar envolvê-la em algum método e escrever um teste próprio para ela, para ter certeza de que não falhará (sem lançando uma exceção).
fonte
Não uso esse padrão, porque acho que fazer algo como:
Pode ser inútil, porque supostamente você sabe que sua parte Arrange funciona corretamente, o que significa que tudo o que está na parte Arrange deve ser testado também ou ser simples o suficiente para não precisar de testes.
Usando o exemplo da sua resposta:
fonte
Se você realmente deseja testar tudo no exemplo, tente mais testes ... como:
Porque, caso contrário, você perderá tantas possibilidades de erro ... por exemplo, após englobar, o intervalo inclui apenas 7, etc ... Existem também testes para o comprimento do intervalo (para garantir que também não abrange um valor aleatório), e outro conjunto de testes inteiramente para tentar englobar 5 no intervalo ... o que esperaríamos - uma exceção em englobar ou o intervalo inalterado?
De qualquer forma, a questão é se houver alguma suposição no ato que você deseja testar, coloque-a em seu próprio teste, certo?
fonte
Eu uso:
Porque uma configuração limpa é muito importante.
fonte