Testy jednostkowe–struktura folderów

Na blogu oraz MSDN pisałem niejednokrotnie o testach jednostkowych oraz integracyjnych. Ostatnio jednak zastanawiałem się nad podstawowym problemem – jak zorganizować to od strony struktury katalogowej? Musimy rozważyć następujące problemy:

  1. Testy powinny być w każdej chwili dostępnie do odpalenia i weryfikacji.
  2. Wykonując prostą refaktoryzację (zmiana nazwy klasy), automatycznie nazwa powinna zaktualizować się w testach.
  3. Testy jednostkowe stanowią dobrą dokumentację oraz instrukcję używania zaimplementowanej funkcjonalności. Z tego względu każdy z developerów z łatwością powinien odnaleźć dowolne projekty testów zanim przejdzie do konkretnej specyfikacji. Moim zdaniem jeśli ktoś chce zobaczyć co robi kod, powinien zacząć od przeczytania testów a nie właściwego kodu.
  4. Zbyt wysoka liczba projektów w solucji ZNACZĄCO obniża wydajność VS.
  5. Projekty zawierające testy będą odpalanie automatycznie na serwerze w jakiś odstępach czasu.

Zdecydowałem się podzielić testy na dwie grupy – wymagające konfiguracji oraz te, wykonywane w całości w pamięci. Warto zaznaczyć, że nie mam podziału na testy integracyjne oraz jednostkowe. O ile test integracyjny nie wymaga zasobów poza pamięcią (bazy danych, usługi itp.) lub jakieś konfiguracji (np. nazwa portu, ip address) wciąż przechowuje je w projekcie z innymi testami jednostkowymi z tym, że w odpowiednim namespace. Wciąż mogą być w każdej chwili odpalane i weryfikowane ponieważ nie wymagają jakiejkolwiek konfiguracji. Czyli jeśli mam test integracyjny który łączy klasę A z klasą B (połączenie jest in-memory), umieszczam go w odpowiednim namespace w testach jednostkowych.

Testy jednostkowe powinny być na bieżącą odpalane i sprawdzanie przez programistów (poza automatycznym uruchamianiem przez buildmachine). Aby to ułatwić wszystkie projekty testów umieszczam w osobnym folderze. Proponuje podział na trzy foldery: Production Code, In-Memory tests oraz Configurable tests. Na przykład:

Production Code:

  • SampleApp.Presentation.Behaviour.csproj
  • SampleApp.Presentation.Views.csproj
  • SampleApp.BusinessLayer.csproj
  • Device1 (folder)
    • SampleDevice.csproj

In-Memory Tests:

  • AllTests.sln (opcjonalne)
  • RunAll (opcjonalne)
  • SampleApp.Presentation.Behaviour.Test.csproj
  • SampleApp.BusinessLayer.Test.csproj
  • Device1 (folder)
    • SampleDevice.Testcsproj

Configurable Tests – analogicznie do In-Memory Tests

 

Struktura katalogów w In-Memory Tests jest taka sama jak w Production Code – z tym, że zamiast właściwego kodu, projekty zawierają wyłącznie testy. Opcjonalnie tworze AllTests.sln, który ułatwia ewentualne debugowanie (np. odpalamy wszystkie unit testy i chcemy sprawdzić co dokładnie popsuło się w którymś z nich).

Warto również w solucjach w Producton Code dodać referencje do projektu z testami. Dzięki temu jakakolwiek refaktoryzacja na kodzie, zostanie również wykonana na testach (np. zmiana klasy, kolejności parametrów itp.). Wadą tego jest oczywiście spowolnienie solucji i dlatego mam wątpliwości – w dużych solucjach naprawdę każdy dodany projekt znaczący ma wpływ na wydajność.

Jak widać jestem zwolennikiem tworzenia nowego projektu z testami dla każdego projektu. Uważam, że bardzo ułatwia to czytanie (testy jako dokumentacja). W In-Memory Tests można również umieścić jakiś skrypt uruchamiający wszystkie testy – taki szybki test dla programistów, którzy zmodyfikowali coś w Production Code.

Podział na foldery a nie mieszanie projektów z testami z projektami produkcyjnymi w jednym folderze, ułatwia znalezienie konkretnego testu (szczególnie nowym programistom).

2 thoughts on “Testy jednostkowe–struktura folderów”

  1. Może zamiast dodawać w Production Code referencje do testów użyj InternalsVisibleTo w AssemblyInfo projektów, które maja być testowane?

Leave a Reply

Your email address will not be published.