• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Pytania odnośnie testów jednostkowych

Object Storage Arubacloud
0 głosów
148 wizyt
pytanie zadane 17 kwietnia 2020 w C# przez dawid2002 Mądrala (5,190 p.)
zamknięte 18 kwietnia 2020 przez dawid2002

Witam! Uczę się C# , ale ostatnio zagłębiam się w temacie testów. Chciałem zadać kilka pytań odnośnie tego tematu.

1. Czy dobrą praktyką jest próba testowania metod prywatnych poprzez zamianę ich na metody internal oraz użycie atrybutu InternalsVisibleTo? Słyszałem różne opinie o tym. Ponoć lepiej jest je testować wyżej za pomocą metod publicznych lub wydzielić je do osobnej klasy, ale to chyba nie zawsze jest możliwe.

2. Jak testować metody, które używają Console.Readkey? Czy da się zasymulować kliknięcie klawisza?

3. Co powinno się testować, a co nie?

4. Jeśli jakaś metoda wyświetla tekst w konsoli to jak przetestować to działanie, jak sprawdzić co dokładnie wyświetla konsola?

5. Jeśli metoda wykonuje się zdecydowanie więcej niż 1 sekunda, to czy opłaca się ją testować?

6. Jeśli jest klasa, która sama ustawia wartości swoich pól, a chcielibyśmy sprawdzić jak zachowują się metody tej klasy podczas gdy pola tej klasy mają jakieś specyficzne wartości to czy można udostępnić testom te pola poprzez settery? Np: byłby przypadek, że wartości tych pól są ustawiane przez Console.Readkey a nie można zasymulować kliknięcia klawisza, więc czy tutaj można użyć settera?

7. Załóżmy, że mamy taką sytuację, że jest klasa "A" i ma metodę "a" oraz klasę "B" i  metodę "b" i metoda "B.b" wywołuje "A.a". Czy napisać osobne testy do tych metod, czy wystarczy, że przetestujemy tylko "B.b"?

8. Jest klasa ZegarBinarny i ma publiczną metodę WyświetlCzas oraz prywatną metodę KonwertujLiczbęDecymalnąNaBinarną. Chciałbym przetestować tę metodę prywatną, więc nie byłoby złem gdybym zamienił ją na public/internal, czy muszę ją wydzielić do osobnej klasy Konwerter?

9. Mam klasę, która jest odpowiedzialna za uruchamianie notatnika (która używa do tego klas ProcessStartInfo i Process), chciałbym za pomocą testów sprawdzić czy ona faktycznie uruchamia notatnik. Czy w środowisku testowym można uruchomić notatnik? Z tego co mi wiadomo to podczas testów nie powinno się używać baz danych i innych tego typu rzeczy.

To wszystko! Sporo trochę tego, ale będę wdzięczny jeśli ktoś pomoże.

komentarz zamknięcia: Znam już odpowiedzi do pytań
komentarz 17 kwietnia 2020 przez tkz Nałogowiec (42,000 p.)
Tak z grubsza odpowiem na kilka pytań, testujesz metody prywatne pośrednio. Nie ma sensu ich testować osobno.
komentarz 17 kwietnia 2020 przez dawid2002 Mądrala (5,190 p.)
Wiem o tym, ale ja mam taki przypadek, że moja metoda publiczna posiada wewnątrz Console.ReadKey , który zatrzymuje wykonywanie programu aż do momentu kiedy zostanie naciśnięty klawisz. Problem polega na tym, że nie wiem jak zrobić symulacje kliknięcia takiego klawisza w C#
komentarz 17 kwietnia 2020 przez tkz Nałogowiec (42,000 p.)
Problem leży z pisaniem testów po kodzie. Nie powinno, a nawet w wielu style guidach zabrania się testowania tak dużych zależności na które nie mamy wpływu. Podziel kod na mniejszy, lub stwórz mocka.
komentarz 17 kwietnia 2020 przez dawid2002 Mądrala (5,190 p.)
Dzięki!

A jakbyś się odniósł do pytań 5-9?
komentarz 17 kwietnia 2020 przez tkz Nałogowiec (42,000 p.)
5. To zależy. Bo więcej niż 1 sekunda, to również miesiąc.

6.

7. To zależy. Ale prawdopodobnie podwajasz ten sam kod testowy.

8. To zależ. Osobiście bym rozdzielił.

9. Mocki.

Trudno odpowiedzieć na jakiekolwiek pytanie nie mając żadnych szczegółowych informacji. Poczytaj o zasad(ach)zie FIRST, to takie SOLID wśród testów.
komentarz 17 kwietnia 2020 przez dawid2002 Mądrala (5,190 p.)
Dziękuje bardzo!

Do tego 5 to chodziło mi coś mniej więcej około minuty lub kilku minut. A w 6 to podejrzewam, że odpowiedź była zbyt oczywista (czyli, że można napisać setter dla testu) i dlatego nie odpowiedziałeś.
komentarz 17 kwietnia 2020 przez tkz Nałogowiec (42,000 p.)
Niezupełnie w tym 6., po prostu nie jestem pewny, bo to też zależy od projektu. Z grubsza setery i getery są rozwiązaniem, czy najlepszym? Trudno mi powiedzieć. Bo może się zdarzyć, że walidacja danych odbywa się pośrednio w innej klasie, to poco testować coś, czego nigdy nie będzie? Przykład, nieidealny, znajdzie się na pewno "ale": klasa Waga i klasa Obciążnik. Klasa Obciążnik dba o to, by waga obciążnika była większa niż 0 gram, to po co testować w klasie Waga, czy obciążnik jest lżejszy niż 0 gram?

Co do czasu, jeżeli coś trwa aż tak długo(a to naprawdę długo, średni czas mierzy się w nanosekundach), to możesz spróbować rozbić to na mniejsze funkcję, które będzie łatwiej testować, czy czas się skróci? Może tak, może nie, może rozbicie pozwoli wyłapać jakiś niuans. Wszystko zależy i bez testów nie udowodnisz, że coś działa.
komentarz 17 kwietnia 2020 przez dawid2002 Mądrala (5,190 p.)

Ok.

Mam jeszcze dwa pytania.

Jest taki kod:

// pseudokod
void metoda()
{
    if (warunek)
        Console.WriteLine("Tekst dla true");

    else
         Console.WriteLine("Tekst dla false");
}

Jak napisać test do tego kodu, jak sprawdzić co zostało wyświetlone w języku C#? Pisałem kiedyś program, który dla istniejącego pliku wykonywał określone operacje, zaś gdy plik ten nie istniał to był wyświetlany komunikat o tym.

Czego nie powinno się testować?

komentarz 17 kwietnia 2020 przez tkz Nałogowiec (42,000 p.)
Generalizując, nie powinno łączyć się logiki, oraz interfejsu, a standardowe wyjście owym jest, mimo, że bardzo ograniczonym. Ale jeżeli chcesz, możesz przechwycić bufor konsoli. Możesz również dodaj jako argument funkcji strumień do którego będzie kierowała wynik.

Polecam pisać test, by kod był testowalny. Często pisanie testów jest niemożliwe przez błędy popełnione przy projektowaniu.
komentarz 18 kwietnia 2020 przez dawid2002 Mądrala (5,190 p.)
Jak to zrobić podczas pisania aplikacji konsolowej? W sensie jak oddzielić logikę od interfejsu. Gdybym pisał program okienkowy to zastosowałbym wzorzec MVC/MVVM, a tutaj to szczerze nie wiem jak zrobić.
komentarz 18 kwietnia 2020 przez tkz Nałogowiec (42,000 p.)

Z racji, że nie piszę w c# trudno mi odpowiedzieć. Mogę podać co najwyżej sposób z c++, który prawdopodobnie da się przełożyć na c#. 

#include <sstream>
#include <iostream>

void f()
{
    std::cout << "hello world\n";
}

int main()
{
    std::ostringstream oss;
    std::streambuf* p_cout_streambuf = std::cout.rdbuf();
    std::cout.rdbuf(oss.rdbuf());

    f();

    std::cout.rdbuf(p_cout_streambuf);

    assert(oss && oss.str() == "hello world\n";
    std::cout << oss.str();
}

Po szybkim i mało dokładnym przejrzeniu docsów od MS, widzę, że jest taka klasa jak StreamWriter, która może pomóc. 

komentarz 18 kwietnia 2020 przez dawid2002 Mądrala (5,190 p.)
No dobrze. Ale chciałbym wiedzieć jak oddzielić logikę od interfejsu w aplikacjach konsolowych.
komentarz 18 kwietnia 2020 przez tkz Nałogowiec (42,000 p.)
To zależy jak wygląda kod.
komentarz 18 kwietnia 2020 przez dawid2002 Mądrala (5,190 p.)
edycja 18 kwietnia 2020 przez dawid2002
No dobrze to wszystko. Dziękuje ci za pomoc!

PS. Odnośnie testowania strumienia wyjścia (i wejścia) w C# to można to zrobić tak:

https://gist.github.com/asierba/ad9978c8b548f3fcef40
komentarz 18 kwietnia 2020 przez tkz Nałogowiec (42,000 p.)
Ogólnie bez kodu i jakiegoś zarysu założeń, trudno cokolwiek powiedzieć. Dzięki za link.

Podobne pytania

+2 głosów
1 odpowiedź 606 wizyt
0 głosów
1 odpowiedź 161 wizyt
pytanie zadane 20 kwietnia 2020 w PHP przez michal_php Stary wyjadacz (13,700 p.)
0 głosów
1 odpowiedź 112 wizyt
pytanie zadane 18 kwietnia 2020 w PHP przez michal_php Stary wyjadacz (13,700 p.)

92,555 zapytań

141,402 odpowiedzi

319,553 komentarzy

61,939 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...