Jakie są popularne konwencje nazewnictwa dla testów jednostkowych? [Zamknięte]


203

Generał

  • Przestrzegaj tych samych standardów dla wszystkich testów.
  • Wyjaśnij jasno, jaki jest każdy stan testowy.
  • Sprecyzuj spodziewane zachowanie.

Przykłady

1) MethodName_StateUnderTest_ExpectedBehavior

Public void Sum_NegativeNumberAs1stParam_ExceptionThrown() 

Public void Sum_NegativeNumberAs2ndParam_ExceptionThrown () 

Public void Sum_simpleValues_Calculated ()

Źródło: Standardy nazewnictwa dla testów jednostkowych

2) Rozdzielanie każdego słowa znakiem podkreślenia

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

Inny

  • Zakończ nazwy metod testem
  • Zacznij nazwy metod od nazwy klasy

Odpowiedzi:


94

Jestem prawie z tobą w tym jednym człowieku. Użyte konwencje nazewnictwa to:

  • Jasne informacje na temat każdego stanu testowego.
  • Specyficzne dla oczekiwanego zachowania.

Czego więcej potrzebujesz od nazwy testu?

Wbrew odpowiedzi Raya nie sądzę, aby przedrostek testowy był konieczny. To kod testowy, wiemy o tym. Jeśli musisz to zrobić, aby zidentyfikować kod, masz większe problemy, kodu testowego nie należy mylić z kodem produkcyjnym.

Jeśli chodzi o długość i użycie znaku podkreślenia, jego kodu testowego , kogo to, do diabła, obchodzi? Tylko ty i twój zespół będziecie to widzieć, o ile będzie to czytelne i jasne o tym, co robi test, kontynuujcie! :)

To powiedziawszy, wciąż jestem całkiem nowy w testowaniu i blogowaniu moich przygód z nim :)


20
Nieznaczna sprzeczność „o ile jest czytelna i jasna” oraz „kogo to obchodzi”. Wszyscy dbają o to, gdy nie jest to czytelne i jasne, dlatego to jest ważne. :-)
David Victor

1
Jeden dodatkowy argument za prefiksem. Kiedy szukasz pliku w IDE, możesz łatwo wyszukiwać przypadki testowe, zaczynając od Testi od nazwy klasy. Jeśli nazwa klasy i nazwa klasy testowej są takie same, zawsze będziemy musieli zatrzymać i odczytać ścieżkę dwóch plików
TEN UŻYTKOWNIK POTRZEBUJE POMOCY

@THISUSERNEEDSHELP Myślę, że twój problem można łatwo pokonać, mając dobrą strukturę folderów, taką jak src / libs & src / testy . Wiem, że niektóre środowiska testowe wymagają prefiksu, takiego jak test do identyfikacji kodu testowego, więc w takich przypadkach nie da się ich uniknąć, ale dla reszty może to być powtarzający się, nie wymagany przedrostek.
negrotico19,

@ negrotico19 Mam na myśli przypadek jak w IntelliJ, kiedy Search Everywhere(shift shift) lub Find a Class By Name(CMD O). Rozumiem, że będzie to różnicować strukturę folderów lub strukturę modułów, ale kiedy czegoś szukamy, wiemy już, czego chcemy szukać. Na przykład, jeśli szukam testu, chcę ograniczyć wyszukiwanie do, testa następnie szukać nazwy, zamiast szukać nazwy, a następnie ręcznie odfiltrować test wzrokowo. Jest to małe rozróżnienie, ale o wiele łatwiej jest „przetestować [nazwę klasy]” i mieć tylko jedno okienko wyskakujące i zmniejszyć obciążenie psychiczne
TEN UŻYTKOWNIK POTRZEBUJE POMOCY

37

Warto również przeczytać: Testy jednostek strukturalnych

Struktura ma klasę testową dla każdej testowanej klasy. To nie jest takie niezwykłe. Ale dla mnie niezwykłe było to, że miał klasę zagnieżdżoną dla każdej testowanej metody.

na przykład

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
        }
    }
}

A oto dlaczego:

Po pierwsze, jest to dobry sposób na zorganizowanie testów. Wszystkie testy (lub fakty) dla metody są zgrupowane razem. Na przykład, jeśli używasz skrótu CTRL + M, CTRL + O, aby zwinąć ciała metody, możesz łatwo zeskanować testy i odczytać je jak specyfikację kodu.

Podoba mi się również to podejście:

MethodName_StateUnderTest_ExpectedBehavior

Więc może dostosuj się do:

StateUnderTest_ExpectedBehavior

Ponieważ każdy test będzie już w klasie zagnieżdżonej


2
Dla tych, którzy używają programu testującego Resharpera w Visual Studio, naprawili błędy za pomocą zagnieżdżonych klas testowych w wersji 8.x. Od tego czasu stała się to zdecydowanie moja preferowana struktura.
angularsen

Czy to ważne, że nazwa staje się naprawdę długa dzięki metodzie MethodName_StateUnderTest_ExpectedBehavior? Takich jak „InitializeApiConfiguration_MissingApiKey_IllegalArgumentException”. Czy to naprawdę dobra nazwa testowa?
portfoliobuilder

28

Zazwyczaj używam konwencji MethodName_DoesWhat_WhenTheseConditions, na przykład:

Sum_ThrowsException_WhenNegativeNumberAs1stParam

Jednak często widzę, aby nazwa testu była zgodna ze strukturą testów jednostkowych

  • Zorganizować
  • działać
  • Zapewniać

Który również jest zgodny ze składnią BDD / Gherkin:

  • Dany
  • Kiedy
  • Następnie

który miałby nazwać test w następujący sposób: UnderTheseTestConditions_WhenIDoThis_ThenIGetThis

tak na twój przykład:

WhenNegativeNumberAs1stParam_Sum_ThrowsAnException

Jednak zdecydowanie wolę umieścić najpierw testowaną nazwę metody, ponieważ wtedy testy można ułożyć alfabetycznie lub posortować alfabetycznie w polu rozwijanym elementu w VisStudio, a wszystkie testy dla 1 metody są grupowane razem.


W każdym razie lubię oddzielać główne sekcje nazwy testu podkreślnikami, a nie każdym słowem , ponieważ uważam, że ułatwia to odczytanie i przejście do sedna testu.

Innymi słowy, lubię: Sum_ThrowsException_WhenNegativeNumberAs1stParamlepiej niż Sum_Throws_Exception_When_Negative_Number_As_1st_Param.


22

Nazywam swoje metody testowe tak jak inne metody przy użyciu „PascalCasing” bez podkreślników i separatorów. Opuszczam test Postfiksa dla tej metody, ponieważ nie dodaje ona żadnej wartości. O tym, że metoda jest metodą testową, wskazuje atrybut TestMethod .

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

Z uwagi na fakt, że każda klasa testowa powinna testować tylko jedną inną klasę, zostawiam nazwę klasy poza nazwą metody. Nazwa klasy zawierającej metody testowe nosi nazwę podobną do klasy testowanej z rozszerzeniem „Testy”.

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

W przypadku metod testujących wyjątki lub działania, które nie są możliwe, poprzedzam metodę testową słowem Nie można .

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

Moja konwencja nazywania oparta jest na artykule „Wskazówki TDD: Testowanie konwencji i wytycznych dotyczących nazewnictwa” Bryana Cooka. Uważam, że ten artykuł jest bardzo pomocny.


1
+1 za link do mojego postu - chociaż nie jest konieczne używanie prefiksu „Test” w swoich Testach. Upewnij się, że testy określają oczekiwane zachowanie. Na przykład CanRetrieveProperCountWhenAddingMultipleItems ()
bryanbcook

2
Nie podoba mi się to, ponieważ nie obejmuje oczekiwanego zachowania
Johannes Rudolph

5

Pierwszy zestaw nazw jest dla mnie bardziej czytelny, ponieważ CamelCasing oddziela słowa, a podpórki oddzielają części schematu nazewnictwa.

Staram się także zawierać gdzieś „Test”, albo w nazwie funkcji, albo w otaczającej przestrzeni nazw lub klasie.


2
@Frank methodName = camelCase MethodName = PascalCase
Metro Smurf

@ metro-smurf: ciekawe rozróżnienie, nigdy nie słyszałem terminu PascalCase i robiłem to od dłuższego czasu. Widzę tylko termin PascalCase pojawiający się w kręgach programistów Microsoft, czy to właśnie robisz?
Frank Szczerba,

Historia wokół Pascala Casinga i Camela Casinga (od: Brad Abrams - blogs.msdn.com/brada/archive/2004/02/03/67024.aspx ) ... ”W początkowej fazie projektu mieliśmy setki godzin debata na temat stylu nazewnictwa Aby ułatwić te debaty, ukształtowaliśmy kilka terminów. Z Anders Heilsberg (oryginalny projektant Turbo Pascal) kluczowym członkiem zespołu projektowego, nic dziwnego, że wybraliśmy termin Pascal Casing na styl obudowy spopularyzowany przez język programowania Pascal. ”
Heliac

-3

Tak długo, jak wykonasz jedną praktykę, tak naprawdę nie ma to znaczenia. Generalnie piszę pojedynczy test jednostkowy dla metody, która obejmuje wszystkie odmiany metody (mam proste metody;), a następnie piszę bardziej złożone zestawy testów dla metod, które tego wymagają. Moja struktura nazewnictwa jest więc zwykle testowa (relacja z JUnit 3).


-8

Używam przedrostka „T” do testowych przestrzeni nazw, klas i metod.

Staram się być schludny i tworzę foldery, które replikują przestrzenie nazw, a następnie tworzę folder testów lub oddzielny projekt dla testów i replikuję strukturę produkcyjną dla podstawowych testów:

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

Z łatwością widzę, że coś jest testem, wiem dokładnie, do czego odnosi się oryginalny kod (jeśli nie możesz tego rozwiązać, test i tak jest zbyt skomplikowany).

Wygląda to tak samo, jak konwencja nazewnictwa interfejsów (tzn. Nie mylisz się z rzeczami zaczynającymi się od „ja”, ani z literą „T”).

Kompilacja z testami lub bez nich jest łatwa.

W każdym razie jest dobry w teorii i działa całkiem dobrze w przypadku małych projektów.


3
Ciekawe podejście Niektórzy ludzie mogą argumentować, że prefiks T jest sprzeczny z konwencją używaną w generycznych (np. Func (T1, T2, TResult)), ale osobiście nie dbam o to, dopóki w zespole panuje konsensus. Nazwy są krótkie, co czyni je też bardziej czytelnymi.
użądlony

Zbyt węgierski (notacja) dla mnie. Ponadto, zgodnie z informacją, przedrostek T jest używany dla ogólnych parametrów typu.
Danny Varod

Zgadzam się, notacja węgierska została osłabiona, a ponieważ konflikt ze standardowymi parametrami typu ogólnego, nie widzę w tym przypadku wyjątku (podobnie jak w przypadku interfejsów).
SonOfPirate,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.