Quais são algumas convenções de nomenclatura populares para Testes de Unidade?

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 ()

Source: Naming standards for Unit Tests

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

  • End method names with Test
  • Start method names with class name
0
adicionado editado
Visualizações: 1
adicionado o autor Wedge, fonte

7 Respostas

Eu estou muito bem com você neste homem. As convenções de nomenclatura que você usou são:

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

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

Contrary to Ray's answer I don't think the Test prefix is necessary. It's test code, we know that. If you need to do this to identify the code, then you have bigger problems, your test code should not be mixed up with your production code.

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

Dito isso, ainda sou novo em testes e blogando minhas aventuras com ele :)

0
adicionado
Um argumento adicional para o prefixo. Quando você está procurando por um arquivo no IDE, é possível pesquisar facilmente os casos de teste iniciando com Test e o nome da sua turma. Se o nome da classe e o nome da classe de teste forem iguais, sempre teremos que pausar e ler o caminho de dois arquivos.
adicionado o autor THIS USER NEEDS HELP, fonte
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, então é por isso que importa. :-)
adicionado o autor David Victor, fonte

Eu nomeio meus métodos de teste como outros métodos usando "PascalCasing" sem quaisquer sublinhados ou separadores. Eu deixo o postfix Test para o método, porque ele não adiciona nenhum valor. Que o método é 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, eu 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 Cannot .

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

My naming convension are base on the article "TDD Tips: Test Naming Conventions & Guidelines" of Bryan Cook. I found this article very helpful.

0
adicionado
Eu não gosto porque não inclui o comportamento esperado
adicionado o autor Johannes Rudolph, fonte
+ 1 para o link para o meu post - embora seja desnecessário usar um prefixo "Test" nos seus testes. Certifique-se de que seus testes especifiquem o comportamento esperado. Por exemplo, CanRetrieveProperCountWhenAddingMultipleItems ()
adicionado o autor bryanbcook, fonte

This is also worth a read: Structuring Unit Tests

A estrutura tem uma classe de teste por classe 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 que estava 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 boa maneira de manter os testes organizados. Todos   testes (ou fatos) para um método são agrupados. Por exemplo, se   você usa o atalho CTRL + M, CTRL + O para recolher os corpos do método, você pode   Digitalize facilmente seus testes e leia-os como uma especificação para o seu código.

Eu também gosto dessa abordagem:

MethodName_StateUnderTest_ExpectedBehavior

Então, talvez ajuste para:

StateUnderTest_ExpectedBehavior

Porque cada teste já estará em uma classe aninhada

0
adicionado
Para aqueles que usam o executor de testes do Resharper no Visual Studio, eles corrigiram erros usando classes de teste aninhadas no 8.x. Desde então, esta se tornou minha estrutura preferida de longe.
adicionado o autor angularsen, fonte

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

Sum_ThrowsException_WhenNegativeNumberAs1stParam

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

  • Organizar
  • Agir
  • asseverar

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

  • Dado
  • Quando
  • Então

which would be to name the test in the manner of: UnderTheseTestConditions_WhenIDoThis_ThenIGetThis

Então, para o seu exemplo:

WhenNegativeNumberAs1stParam_Sum_ThrowsAnException

No entanto, prefiro colocar o nome do método sendo testado primeiro, porque os testes podem ser organizados em ordem alfabética ou aparecer em ordem alfabética na caixa suspensa de membros do VisStudio, e todos os testes do método 1 são agrupados.


Em qualquer caso, eu gosto de separar as principais seções do nome do teste com sublinhados, ao contrário de todas as palavras , porque eu acho que torna mais fácil ler e entender o ponto do teste em toda.

Em outras palavras, eu gosto: Sum_ThrowsException_WhenNegativeNumberAs1stParam melhor que Sum_Throws_Exception_When_Negative_Number_As_1st_Param .

0
adicionado

Contanto que você siga uma única prática, isso realmente não importa. Geralmente, escrevo um único teste unitário para um método que abrange todas as variações de um método (tenho métodos simples;) e, em seguida, escrevo conjuntos de testes mais complexos para métodos que o exigem. Minha estrutura de nomenclatura é, portanto, normalmente testada (um resquício da JUnit 3).

0
adicionado

O primeiro conjunto de nomes é mais legível para mim, uma vez que o CamelCasing separa palavras e as partes separadas do underbars do esquema de nomenclatura.

Eu também tendem a incluir "Test" em algum lugar, seja no nome da função ou no namespace ou classe envolvente.

0
adicionado
@Frank methodName = camelCase MethodName = PascalCase
adicionado o autor Metro Smurf, fonte
@ metro-smurf: distinção interessante, eu nunca ouvi o termo PascalCase usado, e eu venho fazendo isso há muito tempo. Eu só vejo o termo PascalCase aparecer nos círculos de desenvolvedores da Microsoft, é isso que você faz?
adicionado o autor Frank Szczerba, fonte
História em torno de Pascal Casing e Camel Casing (de: Brad Abrams - blogs .msdn.com/brada/archive/2004/02/03/67024.aspx ) ... "Na concepção inicial do Framework, tivemos centenas de horas de debate sobre o estilo de nomeação. Para facilitar esses debates, Com Anders Heilsberg (o criador original do Turbo Pascal) um membro-chave 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. "
adicionado o autor Heliac, fonte

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

Eu tento ser limpo e criar pastas que replicam os namespaces, em seguida, criar uma pasta de testes ou projeto separado para os testes e replicar a estrutura de produção para os testes básicos:

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

Eu posso ver facilmente que algo é um teste, eu sei exatamente a que código original pertence, (se você não pode resolver isso, então o teste é complicado demais).

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

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

É bom em teoria, e funciona muito bem para pequenos projetos.

0
adicionado
Demasiado húngaro (notação) para mim. Além disso, ad stung declarado, o prefixo T é usado para parâmetros de tipo genérico.
adicionado o autor Danny Varod, fonte
Concordo, a notação húngara foi depreciada e, como o conflito com os parâmetros de tipo genérico padrão, não vejo uma exceção aplicável neste caso (como existe para interfaces).
adicionado o autor SonOfPirate, fonte
Abordagem interessante. Algumas pessoas podem argumentar que o prefixo T está em conflito com as convenções que você usa em genéricos (por exemplo, func (T1, T2, TResult)), mas eu pessoalmente não me importo, desde que haja um consenso dentro da equipe. Os nomes são curtos, o que torna as coisas mais legíveis também.
adicionado o autor stung, fonte