Quais são algumas convenções de nomenclatura populares para testes de unidade? [fechadas]

204

Geral

  • Siga os mesmos padrões para todos os testes.
  • Seja claro sobre o que é cada estado de teste.
  • Seja específico sobre o comportamento esperado.

Exemplos

1) MethodName_StateUnderTest_ExpectedBehavior

Public void Sum_NegativeNumberAs1stParam_ExceptionThrown() 

Public void Sum_NegativeNumberAs2ndParam_ExceptionThrown () 

Public void Sum_simpleValues_Calculated ()

Fonte: Nomeação de padrões para testes de unidade

2) Separando cada palavra por sublinhado

Public void Sum_Negative_Number_As_1st_Param_Exception_Thrown() 

Public void Sum_Negative_Number_As_2nd_Param_Exception_Thrown () 

Public void Sum_Simple_Values_Calculated ()

De outros

  • Terminar nomes de métodos com Teste
  • Iniciar nomes de métodos com o nome da classe
doeram
fonte

Respostas:

94

Estou praticamente com você neste homem. As convenções de nomenclatura que você usou são:

  • Claro sobre o que é cada estado de teste.
  • Específico sobre o comportamento esperado.

O que mais você precisa de um nome de teste?

Ao contrário da resposta de Ray, não acho que o prefixo Teste seja necessário. É um código de teste, nós sabemos disso. Se você precisar fazer isso para identificar o código, terá problemas maiores; o código de teste não deve ser misturado ao código de produção.

Quanto ao tamanho e uso do sublinhado, seu código de teste , quem se importa? Somente você e sua equipe verão isso, desde que seja legível e claro sobre o que o teste está fazendo, continue! :)

Dito isto, ainda sou bastante novo para testar e postar minhas aventuras no blog com ele :)

Rob Cooper
fonte
20
Pequena contradição "desde que seja legível e clara" e "quem ... se importa". Bem, todo mundo se importa quando não é legível e claro, e é por isso que importa. :-)
David Victor
1
Um argumento adicional para prefixo. Ao procurar um arquivo no IDE, você pode pesquisar facilmente casos de teste iniciando com Teste o nome da sua classe. Se o nome da classe e o nome da classe de teste forem iguais, sempre teremos que fazer uma pausa e ler o caminho de dois arquivos
ESTE USUÁRIO PRECISA DE AJUDA
@THISUSERNEEDSHELP Acho que seu ponto de vista pode ser facilmente superado com uma boa estrutura de pastas, como src / libs e src / tests . Eu sei que algumas estruturas de executores de teste exigem um prefixo como teste para identificação do código de teste, portanto, nesses casos, não será evitado, mas, pelo resto, pode ser um prefixo repetitivo e não obrigatório .
negrotico19
@ negrotico19 Estou pensando no caso como no IntelliJ quando você Search Everywhere(shift shift) ou Find a Class By Name(CMD O). Entendo que ele será diferenciado pela estrutura de pastas ou módulo, mas quando procuramos por algo, já sabemos o que queremos pesquisar. Por exemplo, se eu estou olhando para um teste, eu quero limitar a pesquisa teste, em seguida, procurar o nome, em vez de procurar o nome e , em seguida, filtrar teste manualmente pelos olhos. É uma pequena distinção, mas é muito mais fácil "testar [nome da classe]" e exibir apenas uma e reduzir a carga mental
ESTE USUÁRIO PRECISA DE AJUDA
37

Também vale a pena ler: Estruturar testes de unidade

A estrutura possui uma classe de teste por classe que está sendo testada. Isso não é tão incomum. Mas o que era incomum para mim era que ele tinha uma classe aninhada para cada método sendo testado.

por exemplo

using Xunit;

public class TitleizerFacts
{
    public class TheTitleizerMethod
    {
        [Fact]
        public void NullName_ReturnsDefaultTitle()
        {
            // Test code
        }

        [Fact]
        public void Name_AppendsTitle()
        {
            // Test code
        }
    }

    public class TheKnightifyMethod
    {
        [Fact]
        public void NullName_ReturnsDefaultTitle()
        {
            // Test code
        }

        [Fact]
        public void MaleNames_AppendsSir()
        {
            // Test code
        }

        [Fact]
        public void FemaleNames_AppendsDame()
        {
            // Test code
        }
    }
}

E aqui está o porquê:

Bem, por um lado, é uma ótima maneira de manter os testes organizados. Todos os testes (ou fatos) de um método são agrupados. Por exemplo, se você usar o atalho CTRL + M, CTRL + O para recolher os corpos dos métodos, poderá digitalizar facilmente seus testes e lê-los como uma especificação para o seu código.

Eu também gosto dessa abordagem:

MethodName_StateUnderTest_ExpectedBehavior

Então, talvez se ajuste a:

StateUnderTest_ExpectedBehavior

Porque cada teste já estará em uma classe aninhada

Lúcifer
fonte
2
Para aqueles que usam o executor de teste do Resharper no Visual Studio, eles corrigiam erros usando classes de teste aninhadas no 8.x. Desde então, essa se tornou minha estrutura preferida de longe.
Angularsen 11/03/2015
Importa que o nome se torne realmente longo com a abordagem MethodName_StateUnderTest_ExpectedBehavior? Como "InitializeApiConfiguration_MissingApiKey_IllegalArgumentException". Esse é realmente um bom nome de teste?
portfoliobuilder
28

Costumo usar a convenção de MethodName_DoesWhat_WhenTheseConditions, por exemplo:

Sum_ThrowsException_WhenNegativeNumberAs1stParam

No entanto, o que vejo muito é fazer com que o nome do teste siga a estrutura de teste da unidade de

  • Organizar
  • Aja
  • Afirmar

Que também segue a sintaxe BDD / Gherkin de:

  • Dado
  • Quando
  • Então

que seria nomear o teste da seguinte maneira: UnderTheseTestConditions_WhenIDoThis_ThenIGetThis

Então, para o seu exemplo:

WhenNegativeNumberAs1stParam_Sum_ThrowsAnException

No entanto, prefiro colocar o nome do método que está sendo testado primeiro, porque os testes podem ser organizados em ordem alfabética ou exibidos em ordem alfabética na caixa suspensa do membro no VisStudio, e todos os testes para 1 método são agrupados.


De qualquer forma, gosto de separar as principais seções do nome do teste com sublinhados, em vez de todas as palavras , porque acho que facilita a leitura e a compreensão do ponto do teste.

Em outras palavras, eu gosto: Sum_ThrowsException_WhenNegativeNumberAs1stParammelhor que Sum_Throws_Exception_When_Negative_Number_As_1st_Param.

CodingWithSpike
fonte
22

Eu nomeio meus métodos de teste como outros métodos usando "PascalCasing" sem sublinhados ou separadores. Deixo o teste postfix para o método de fora, porque ele não agrega valor. O fato de o método ser um método de teste é indicado pelo atributo TestMethod .

[TestMethod]
public void CanCountAllItems() {
  // Test the total count of items in collection.
}

Devido ao fato de que cada classe de teste deve testar apenas uma outra classe, deixo o nome da classe fora do nome do método. O nome da classe que contém os métodos de teste é nomeado como a classe em teste com o postfix "Tests".

[TestClass]
public class SuperCollectionTests(){
    // Any test methods that test the class SuperCollection
}

Para métodos que testam exceções ou ações que não são possíveis, prefixo o método de teste com a palavra Não é possível .

[TestMethod]
[ExpectedException(typeOf(ArgumentException))]
public void CannotAddSameObjectAgain() {
  // Cannot add the same object again to the collection.
}

Minha convenção de nomenclatura é baseada no artigo "Dicas para TDD: convenções e diretrizes de nomenclatura de teste" de Bryan Cook. Achei este artigo muito útil.

Jehof
fonte
1
+1 para o link da minha postagem - embora seja desnecessário usar um prefixo "Teste" em seus testes. Certifique-se de que seus testes especifiquem o comportamento esperado. Por exemplo, CanRetrieveProperCountWhenAddingMultipleItems ()
bryanbcook 2/09/09
2
Eu não gosto dele porque ele não inclui o comportamento esperado
Johannes Rudolph
5

O primeiro conjunto de nomes é mais legível para mim, uma vez que o CamelCasing separa palavras e as barras inferiores separam partes do esquema de nomeação.

Eu também tendem a incluir "Test" em algum lugar, no nome da função ou no espaço para nome ou classe anexa.

Frank Szczerba
fonte
2
@Frank methodName = camelCase MethodName = PascalCase
Metro Smurf
@ metro-smurf: distinção interessante, nunca ouvi o termo usado pelo PascalCase e faço isso há muito tempo. Só vejo o termo PascalCase nos círculos de desenvolvedores da Microsoft, é isso que você faz?
Frank Szczerba
História sobre Pascal Casing e Camel Casing (de: Brad Abrams - blogs.msdn.com/brada/archive/2004/02/03/67024.aspx ) ... "No design inicial do Framework, tínhamos centenas de horas de Para facilitar esses debates, criamos vários termos: com Anders Heilsberg (o designer original do Turbo Pascal), um membro importante da equipe de design, não é de admirar que tenhamos escolhido o termo Pascal Casing para o estilo de revestimento. popularizado pela linguagem de programação Pascal ".
Heliac
-3

Contanto que você siga uma única prática, isso realmente não importa. Geralmente, escrevo um único teste de unidade para um método que cubra todas as variações de um método (tenho métodos simples;) e depois escrevo conjuntos de testes mais complexos para os métodos que o exigem. Minha estrutura de nomenclatura é, portanto, geralmente testada (uma retração do JUnit 3).

Munger
fonte
-8

Eu uso um prefixo 'T' para namespaces, classes e métodos de teste.

Tento ser limpo e criar pastas que replicam os espaços para nome, em seguida, crio uma pasta de testes ou um projeto separado para os testes e replico a estrutura de produção para os testes básicos:

AProj
   Objects
      AnObj
         AProp
   Misc
      Functions
         AFunc
   Tests
      TObjects
         TAnObj
            TAnObjsAreEqualUnderCondition
      TMisc
         TFunctions
            TFuncBehavesUnderCondition

Percebo facilmente que algo é um teste, sei exatamente a que código original ele se refere (se você não consegue resolver isso, o teste é complicado demais).

Parece com a convenção de nomenclatura de interfaces (quero dizer, você não se confunde com as coisas que começam com 'I', nem com 'T').

É fácil compilar apenas com ou sem os testes.

De qualquer forma, é bom em teoria e funciona muito bem para pequenos projetos.

user566399
fonte
3
Abordagem interessante. Algumas pessoas podem argumentar que o prefixo T entra em conflito com a convenção usada em genéricos (por exemplo, func (T1, T2, TResult)), mas eu pessoalmente não me importo, desde que haja um consenso na equipe. Os nomes são curtos, o que torna as coisas mais legíveis também.
picado
Muito húngaro (notação) para mim. Além disso, conforme indicado, o prefixo T é usado para parâmetros do tipo genérico.
precisa saber é o seguinte
Concordo que a notação húngara foi privada e, como o conflito com os parâmetros de tipo genérico padrão, não vejo uma exceção se aplicando neste caso (como há para interfaces).
SonOfPirate