Zależy od definicji jednostki i funkcji. Jeżeli przez jednostkę uznajesz coś pokroju klasy/metody (chodzi o rozmiar, nie o dokładną strukturę kodu) a przez funkcję rozumiesz scenariusz testowy czarnej skrzynki, to test jednostkowy może być testem funkcjonalnym, gdy kod nie ma zależności. Ale jeżeli zależności są i zaczynasz je mockować, to wtedy test jednostkowy już funkcjonalny nie jest (bo znasz strukturę kodu pod spodem i ją mockujesz).
Nie znam struktury kodu, znam jedynie zewnętrzne zależności. Może będą używane bezpośrednio przez punkt wejścia jednostki, a może przez jakąś klasę pomocniczą.
Jaka jest właściwie definicja testów funkcjonalnych?
Zależy od kodu. Jak nie ma nic do integracji, to nie będą to testy integracyjne (ale ciągle nic nie mockujesz).
No i to określiłem jako jednostkowe kodu bez zmiennych zależności
. Skoro nie ma zmiennych (zewnętrznych jeśli wolisz) zależności, to nie ma czego mockować.
O te szczegóły się rozbija, bo wiele osób definiuje jednostkę jako dobrze określony rozmiarem fragment kodu (na przykład jedna metoda lub jedna klasa).
Wiele osób jest po prostu w błędzie. Jednostka sama z siebie jest kompletna, potrafi wykonać określone zadanie. Nie każda klasa ma tę cechę, niektóre klasy istnieją tylko po to, aby wykonać kawałek zadania. To nie są jednostki. Człowiek jest jednostką, noga nią nie jest.
A tu definiujesz jednostkę jako coś ściśle związanego z efektami ubocznymi, co nie jest konieczne (a obecne trendy nawet sugerują, żeby jak najmniej efektów ubocznych mieć, więc większość kodu będzie bez nich).
Więc większość kodu będzie się wreszcie dało skutecznie testować jednostkowo. :)
Ale to nie jest definicja, ile sposób rozpoznania na podstawie sposobu działania. Test jednostkowy nie może mieć efektów ubocznych, integracyjny może mieć, może nie mieć, zależy co testuje. Gdyby test jednostkowy miał efekty uboczne, to znaczy, że z czymś by się integrował, więc byłby już integracyjny (może nieumyślnie, ale nadal).
No i tutaj prezentujesz właśnie pogląd, że testy mają być izolowane od siebie. Niektórzy za to definiuję izolację jako izolację jednostek między sobą, niezależnie od efektów ubocznych wpływających na testy.
Chodzi mi po prostu o to, że jeden test nie powinien pracować na wynikach drugiego testu, ani w żaden sposób dzielić stanu znajdującego się gdziekolwiek, bo to prosta droga do strzelenia sobie w stopę.
Warto też pamiętać, że izolacja testów nie musi oznaczać mockowania.
Oczywiście, że nie. Zresztą w testach jednostkowych izolacja zazwyczaj nie jest problemem, to np. w testach integracyjnych piszących coś do bazy zdarza się jakieś zamieszanie z danymi i niespodziewanie psujące się testy.
Jeżeli w milisekundę postawię stos aplikacji całkowicie od zera, ze wszystkimi zależnościami i danymi, odpalę test, posprzątam i będę znał wynik, to nie ma potrzeby mockować niczego, będzie to test izolowany (od innych testów), a będzie miał efekty uboczne.
I będzie integracyjny.
Parser nie ma efektów ubocznych, jest osobną jednostką. Mockujesz go tutaj? Podejrzewam, że nie (bo mówisz, że testy mają nie wpływać na siebie, więc tutaj nie ma potrzeby)
Do testu tego kodu napisałbym test integracyjny, bo jednostkowy z zamockowanym parserem nie będzie miał wartości.
bo izolują jednostki, czyli chcą uniezależnić jednostkę liczącą sumę od jednostki parsującej CSV.
No tak w realnym życiu też bym tak zrobił, ale najpierw bym wyniósł sumowanie do oddzielnej jednostki. Miałbym dwie jednostki: parser i sumator, a do tego orkiestrator (Twoją obecną funkcję sum
), który je wywołuje. Tego orkiestratora już bym nie testował jednostkowo, bo nie miałoby to wartości. (No, a ponieważ nie testuję jednostkowo, to nie ma sensu nazywanie go jednostką.)
Można mieć jednostki będące jednostkami, realną izolację ich testów, i brak mockowania utrudniającego życie. Tylko trzeba się zastanowić nad układem kodu.
Jednostka i izolacja to są dwa różne obszary testów, można je różnorako definiować i przez to mieć różne kombinacje.
Nie można różnie definiować, można jedynie uznawać błędne definicje, ale ziemniak pomalowany czerwoną farbą nigdy nie będzie pomidorem.