Po co testy jak można przeklikać

2

zależy.

są softy których nie warto testować - są relatywnie małe i/lub mocno zależą na innych systemach, więc pewnie nie będzie nawet czego testować, a postawienie infrastruktury do testów z tym czymś by mogło zająć znaczny % budżetu

10

Możesz użyć argumentu takiego, że podejście z testami manualnymi nie skaluje się razem z przyrostem ficzerów. Im bardziej system będzie rozwijany, tym lawinowo rosną przypadki testowe. A na testy potrzeba czasu, a czas to pieniądz.

Inna sprawa, że nie powinieneś prosić o pozwolenie na pisanie testów - to jest nierozłączna część Twojej profesji. Kod bez testu z założenia nie działa i taki powinien być Twój mindset niezależnie, kto jest w managemencie. Oczywiście pytanie ile masz energii, żeby pomimo trudności robić dobra robotę - IMO nie ma co się szarpać i tak na długa metę się nie rozwiniesz w takim środowisku.

0

Próbowałem tego argumentu ale nie podziadzialo (kontrargument o sprawdzaniu referencji) Chyba nie ma co się szarpać. Infrastruktury pod testy nawet nie ma, pełno staticow wszędzie. Wysiłków i tak nikt nie doceni.

7
  1. Management ma zawsze rację.
  2. Jeśli przedstawisz fakty, wskazujące inaczej to ewidentnie się mylisz i musisz się liczyć z konsekwencjami. Np. zakaz robienia błędów pod karą finansową (przerabiałem ten fragment gry).

Nic nie zrobisz. Spierniczaj - na koniec powiedz co o tym sądzisz. Niewiele to zmieni, ale jak kilku programistów coś takiego powie na odchodnym, to za parę lat okaże się, że management był zwolennikiem automatyzacji testów i tylko programiści, tacy jak Ty, w tym zawsze przeszkadzali.

2

@katakrowa:

się nawet na jego jednokrotne przetestowanie (dosłownie kompiluje się to musi być ok).

Tak przecież powinno być: kompiluje się to musi być ok.
Ale programiści to nieodpowiedzialne lenie i ignoranci, którzy nie potrafią ogarnąć języków z nieco lepszymi kompilatorami i dłubią, jak dziadowie, w podjęzykach, gdzie każdą pierdołę trzeba testować.
(Napisałem każdą, bo obecnie nawet w całkiem zaawansowanych językach i tak "biznes" zwykle trzeba testować, ale wiele rzeczy można jednak odpuścić.)

0

No niby masz racje, ale manager chce wiedziec niekiedy ze dziala, wiec przeklinanie jak nie dziala to troche malo xd

4
nobody01 napisał(a):

Jak byście odbili "argument" o tym, że wystarczy po prostu sprawdzić referencje do metody/zmiennej przed wgraniem commita?

Sprawdzę i co dalej? Mam sobie magicznie wywnioskować kontrakt na postawie wywołań? Domyśleć się jakie warunki ma spełniać metoda? Nawet jak są testy to i tak nie zawsze wiadomo, czemu ktoś podjął takie, a nie inne decyzje. Jednak jeśli jest dobra infrastruktura testowa, to można ewentualnie dopytać się i łatwo dorzucić nowy test.

Jak pracowałem w e-podróżniku jakieś prawie 10 lat temu, to była tam polityka braku testów automatycznych i braku refaktorowania starego kodu. Stary kod już działa, więc nie wolno go zmieniać, bo się jeszcze popsuje. Zwłaszcza kod napisany przez szefa był nietykalny. Trzeba co najwyżej dopisywać nowy kod, który wywołuje stary. Był jeden gość od przeklikiwania wysyłania mejli. Codziennie je generował, sprawdzał swoją skrzynkę i zastanwiał się czy te mejle są dobrze wygenerowane. Mi się udało napisać testy do kodu, który sam pisałem od zera, ale gdy miałem dopisać coś do starego kodu bez infrastruktury testowej, to nie dopisywałem.

W e-podróżniku kilka miesięcy pracowałem nad biletomatem, a konkretnie nad modułem do przyjmowania i wydawania pieniędzy. Ja robiłem moduł w Javie, który:

  • łączył się z czytnikiem kart płatniczych przez TCP/IP - to jakoś dało się ogarnąć sensownie i napisać testy do tego, bo miało specyfikację (i to nawet na tyle dobrą, że testy napisane na jej podstawie wykryły niektóre błędy w programie zanim jeszcze dostałem sprzęt do ręki)
  • łączył się z czytnikiem monet poprzez notorycznie psujący się moduł napisany chyba w Pascalu przez pana Dariusza - sympatycznego gościa w wieku 70+
  • łączył się z czytnikiem banknotów, ale tu już nie pamiętam jak to było - chyba też się psuło, ale rzadziej niż czytnik monet

Niestety integracja z modułem pana Dariusza to była droga przez mękę. Pan Dariusz, mimo iż był sympatyczny, to jednak niereformowalny (nie dziwne, biorąc pod uwagę wiek). Napisał swój badziewny kod naszpikowany globalnym stanem i nie chciał go pokazać (w sensie dopiero jak dał się w końcu namówić to kolega zobaczył ten koszmar w środku). Testów automatycznych to prawdopodobnie nie miało żadnych. Za to ja przez pół dnia stałem przy tym biletomacie, wrzucałem monety i sprawdzałem czy biletomat nie zwariuje, albo czy przynajmniej wyda poprawnie. Podczas tego wrzucania monet sprawdzałem różne scenariusze, w sensie zmieniałem liczbę monet w tubach, by różne z nich się aktywowały. Nieraz udawało mi się "rozbić bank", tzn przy żwawym wrzucaniu monet moduł pana Dariusza głupiał i zaczął wyrzucać wszystkie monety. Opisywałem panu Dariuszowi w jakich scenariuszach jego program głupieje, on po iluś tam dniach przysyłał nową wersję swojego programu (tylko skompilowaną binarkę, bo kodu źródłowego nie chciał dawać), potem ja sprawdzałem, które scenariusze zostały poprawione, a które zepsute, znowu mu raportowałem, on znowu po iluś dniach przysyłał wersję niby poprawioną i tak w koło Macieju. Każdego ranka miałem załamanie psychiczne. Myślałem o tym, że skończyłem studia magisterskie na względnie dobrej uczelni (UJ), podchodzę ambitnie do tematu programowania, a ostatecznie i tak pół dnia wrzucam monety do biletomatu jak jakiś półgłówek.

Powyższa historia w sumie narzuca pewien wniosek - testowanie testowaniu nierówne (albo tester testerowi nierówny), nawet jeśli ograniczamy się do testowania ręcznego. Możliwe, że pan Dariusz testował swój program ręcznie w tempie 70-latka, a bardziej zwinne użycie skutkowało odpaleniem nietestowanych wcześniej interakcji w kodzie. Porządnych stress testów się ręcznie nie zrobi. Pogorszenia wydajności też się często nie wyłapie.

0

Prawie jakbym słyszał pewnego "senior" developera tureckiego pochodzenia, który na linkedin nadał sobie samozwańczy tytuł "Chief Software Architect".

Tyle że u niego ta awersja do testów, to była głównie spodowana tym, że był bardzo słabym programistą i pisał kod niemal niemożliwy do testowania, więc chciał narzucać każdemu swoje zdanie, bo robił w gacie na samą myśl, że sam będzie musiał te testy pisać/utrzymywać.

1

Kontrargument byłby pewnie taki, że jak wiesz, gdzie co jest wykorzystywane, to możesz się przedrzeć przez te wszystkie ify w środku i ogarnąć, co się tam dzieje. :/

5
nobody01 napisał(a):

Kontrargument byłby pewnie taki, że jak wiesz, gdzie co jest wykorzystywane, to możesz się przedrzeć przez te wszystkie ify w środku i ogarnąć, co się tam dzieje. :/

To byłoby równoważne z (w kółko powtarzaną) inżynierią wsteczną. Strata czasu. Testy automatyczne znacznie ograniczają potrzebę czegoś takiego. Oczywiście nie do końca, bo w praktyce testy same w sobie nie są kompletnym odwzorowaniem kontraktu i wszystkich przypadków brzegowych. Gdzieś musi być kompromis - za mało testów źle, ale za dużo kodu testowego to też źle (np. jeśli kodu testowego jest 10x więcej niż produkcyjnego to prawdopodobnie ktoś zbyt mocno zaszalał, no chyba, że projekt jest mocno nietypowy).

3
Patryk27 napisał(a):

Po co przeklikiwać, skoro można mieć testy? ;-)

Po to, że testy są bezmózgie i powiedzą jedynie czy ewentualne przeklikanie da założony uprzednio efekt, ale nic o tym czy ten efekt ma sens, ani czy klikanie było wygodne, rozsądne, intuicyjne.

2

@Azarien:
Nie wiem czy to było trolololo, ale się odniosę:

Po to, że testy są bezmózgie i powiedzą jedynie czy ewentualne przeklikanie da założony uprzednio efekt, ale nic o tym czy ten efekt ma sens

O to by test automatyczny miał sens, programista dba podczas pisania tego testu.

ani czy klikanie było wygodne, rozsądne, intuicyjne.

Tutaj najważniejsza jest opinia użytkownika, a nie twórcy programu. W naszym systemie co jakiś czas okazuje się, że rozwiązanie które wygląda dla nas bardzo fajnie jest nieużywane, bo użytkownicy wolą używać programu w zupełnie inny sposób niż sobie wyobraziliśmy.

3
Wibowit napisał(a):

@Azarien:

Nie wiem czy to było trolololo, ale się odniosę:

Było całkiem serio. I wcale nie chodzi mi o to że testy i automaty są niepotrzebne – są potrzebne, ale mają inny cel niż „klikanie”.

Po to, że testy są bezmózgie i powiedzą jedynie czy ewentualne przeklikanie da założony uprzednio efekt, ale nic o tym czy ten efekt ma sens

O to by test automatyczny miał sens, programista dba podczas pisania tego testu.

Rok później to co miało początkowo sens mogło sens utracić. Nic nie zastąpi spojrzenia na program oczami użytkownika - próby faktycznie użycia programu.

2
Azarien napisał(a):

O to by test automatyczny miał sens, programista dba podczas pisania tego testu.

Rok później to co miało początkowo sens mogło sens utracić. Nic nie zastąpi spojrzenia na program oczami użytkownika - próby faktycznie użycia programu.

O tym (w sensie: o użyteczności danej funkcji) raczej decyduje analityk czy też zespoły od sprzedaży i rozwoju produktu. Programista implementuje to, czego biznes chce i ewentualnie wytyka niezgodności w wymaganiach. Do tego oszacowuje koszt implementacji różnych pomysłów po to, by biznes wybrał rozwiązanie bardziej sensowne w danym momencie. Czasami jest tak, że wymagania od biznesu skutkują grzebaniem w jakichś starociach i wtedy może się okazać, że lepiej te starocie wyrzucić niż adaptować do nowych warunków. Tutaj jednak decyzję i tak podejmuje biznes, a nie programista. Tak to przynajmniej wygląda u mnie w banku, gdzie programiści nie utrzymują kontaktu z klientami, więc ich nie pytają o wrażenia z użytkowania (poza pewnymi wyjątkami, ale mniejsza o to).

Wracając do głównego tematu:
W sumie naszła mnie pewna myśl: co ktoś ma na myśli przez przeklikiwanie? Tutaj założyłem, że chodzi o używanie systemu mniej więcej tak jak to robi użytkownik. Jednak ręcznie testować można też ukryte (w sensie niedostępne bezpośrednio dla użytkownika) części systemu. To też będzie klikanie? Mogę np wrzucić jakiś plik do folderu, wiadomość na topic kafkowy, uderzyć do końcówki RESTowej, itp itd To się da wyklikać. Z drugiej strony - wyklikiwanie takich rzeczy dość łatwo da się zautomatyzować i wtedy przestaje być typowym ręcznym testowaniem. Zaczynamy tworzyć infrastrukturę testową, więc czemu nie iść dalej i nie testować wszystkiego automatycznie?

5

@Azarien:

Nic nie zastąpi spojrzenia na program oczami użytkownika - próby faktycznie użycia programu.

Ileś razy zdarzyło mi się, że po zgłoszeniu błędu mogłem znaleźć konkretny Test, który sprawdzał jakąś absurdalną regułę biznesową, którą sobie analitycy wydumali. Wystarczy zmienić działanie na oczekiwane, znaleźć test co się wywala, w commit message odnaleźć ticket i przekierować - najfajniej jak zgłoszenie jest od tego samego człowieka, co ową pokrętną regułę wymyślał.
Analityk jest często jak programista - po kilku miesiącach patrzy na swoje wypociny i nie wie co miał w zasadzie na myśli.
Różni użytkownicy często mają zupełnie odrębne oczekiwania jak program ma działać i to nie tylko co do GUI, ale dość często nawet do tego jak różne rzeczy są liczone.
W takim przypadku testy to dość niezłe zabezpieczenie od kręcenia się w kółko.

3

@jarekr000000:

Tak przecież powinno być: kompiluje się to musi być ok.
Ale programiści to nieodpowiedzialne lenie i ignoranci, którzy nie potrafią ogarnąć języków z nieco lepszymi kompilatorami i dłubią, jak dziadowie, w podjęzykach, gdzie każdą pierdołę trzeba testować.

no generalnie zgodzę się z tezą że przez korzystanie z silnego typowania (nie mylić z typowaniem stringami) można wyeliminować dużo błędów, to trudno mi wyobrazić sobie żeby FP wyeliminowało błędy całkowicie zwłaszcza związane z błędnym zaimplementowaniem logiki biznesowej. Na przykładzie przysłowiowego równiania kwadratowego jeżeli ktoś pomyli wzór na delte to nic mu silne typowanie nie da...

1
Wibowit napisał(a):
Azarien napisał(a):

O to by test automatyczny miał sens, programista dba podczas pisania tego testu.

Rok później to co miało początkowo sens mogło sens utracić. Nic nie zastąpi spojrzenia na program oczami użytkownika - próby faktycznie użycia programu.

O tym (w sensie: o użyteczności danej funkcji) raczej decyduje analityk czy też zespoły od sprzedaży i rozwoju produktu. Programista implementuje to, czego biznes chce i

Ale ja nie mówię że to powinien robić programista.

Wracając do głównego tematu:
W sumie naszła mnie pewna myśl: co ktoś ma na myśli przez przeklikiwanie?

Mam na myśli pracę testera tzw. manualnego.

więc czemu nie iść dalej i nie testować wszystkiego automatycznie?

Ależ testuj sobie wszystko automatycznie. Uważam po prostu że to nie zastąpi „przeklikania”.
Testy automatyczne np. nie zauważą że layout jest źle spasowany czy z nieznanych przyczyn nagle kompletnie rozwalony.

4

@Azarien:

Testy automatyczne np. nie zauważą że layout jest źle spasowany czy z nieznanych przyczyn nagle kompletnie rozwalony.

Oczywiście, że zauważą.
Są do tego frameworki oparte o np. screenshoty i porównywanie wyników z oczekiwanymi. Wadą jest oczywiście koszt utrzymania - wysoki - jak w selenium, opłaca się raczej jak mamy miliony uzytkowników, lub bardzo krytyczną domenę.

Choć najciekawiej wygląda to: http://galenframework.com/ i możliwe, że koszt nie jest tak duży, (ale akurat nie używałem).

@Aleksander32

Na przykładzie przysłowiowego równiania kwadratowego jeżeli ktoś pomyli wzór na delte to nic mu silne typowanie nie da...

Ale silnym typowaniem można zmniejszyć prawdopodobieństwo pomyłki.
Wystarczy spojrzeć na sygnaturę sqrt, w prawie każdym języku, żeby wiedzieć, że coś jest nie tak z tą "funkcją":
double sqrt(double a)

Gdyby była zdefiniowana poprawnie,
PositiveNum sqrt(PositiveNum a) albo Complex sqrt(double a) to szanse zrypania czegoś w liczeniu równania kwadratowego spadają.

1
Azarien napisał(a):

Testy automatyczne np. nie zauważą że layout jest źle spasowany czy z nieznanych przyczyn nagle kompletnie rozwalony.

Jeżeli layout się na tyle rozjedzie, że nie będzie się dało kliknąć tam gdzie trzeba, to testy oparte o Selenium się sypną. Selenium symuluje wejście od użytkownika, czyli jest w stanie kliknąć dokładnie tam gdzie użytkownik jest w stanie kliknąć, jest w stanie wpisać tekst dokładnie tam gdzie użytkownik jest w stanie wpisać tekst, itp itd Dla przykładu - jeśli layout rozjedzie się tak, że jeden przycisk zasłoni drugi, to drugiego nie będzie dało się kliknąć w Selenium. To już sporo daje.

Samo sprawdzenie czy layout wygląda mniej więcej "jak trzeba" i czy na GUI wyświetlają się mniej więcej te dane co trzeba to podchodzi mi pod smoke testing i owszem robimy coś takiego, ale nie jest to kompleksowe testowanie funkcjonalności systemu, tylko szybki rzut okiem. Mamy nawet krótki zestaw smoke testów (kilka minut klikania) dla zespołu wsparcia produkcji, który wykonuje je po każdym releasie na produkcję (a przynajmniej powinien). Takie testy przydają się między innymi dlatego, że każde środowisko ma nieco odmienną konfigurację oraz różne dane i testując na środowiskach testowych nie zawsze da się wyłapać błędy w uwalonej konfiguracji produkcyjnej.

2

Mając zautomatyzowane testy łatwiej jest namierzyć commit który zepsuł legacy. Z programistami jest tak że jeden przeklika, trzech nie przeklika, ten jeden przeklika i znajdzie błąd, revertuje swój commit i dalej błąd, i albo będzie siedział szukając wadliwego commita albo zleje temat i dostarczy nic nie mówiąc nikomu. A tak to masz jenkins joba trigerrowanego commitem, testy regresyjne się wysypią i commit co zepsuł będzie revertowany i nie dostarczy się póki programista nie naprawi.

2

@katakrowa:
Jakich tych testów nie jesteś w stanie zrobić? Jak pracowałem w e-podróżniku nad modułem do komunikacji z czytnikiem kart płatniczych to pisałem go wraz z testami jeszcze nie mając sprzętu. Miałem za to specyfikację z przykładami wiadomości lecących po TCP/IP i to je wrzuciłem do testów i wykryłem część błędów w implementacji. W sumie jakbym się dobrze wczytał w dokumentację to może i wszystkie bym znalazł "na sucho" (jeszcze bez sprzętu w ręce), ale pewne rzeczy były niezrozumiale napisane.

Na pewno wiele zależy od konkretnego przypadku. Napisanie np. testów dla sterowników dla kart graficznych działających bez karty graficznej (ale za to z nagraną wymianą danych między sterownikiem, a kartą) byłoby karkołomne, bo między sterownikiem, a kartą wymieniana jest masa danych. Jednak we wspomnianym przypadku czytnika kart płatniczych tej komunikacji było mało i dało się to opisać w krótkiej specyfikacji.

1

A propos testowania, ktoś tu chyba nie przeklikał: Najnowsza afera programistyczno-szczepionkowa 4 RP

3

ja pisze testy jak mi sie nie chce klikać ;)

2

@katakrowa:

@Wibowit: niby żadne cudo ale to napisz... Tak żeby funkcja leciała w tle a bity zmieniały się "obok niej". To nie jest test, w którym podajesz coś na wejściu i dostajesz wyjście. Jednak widzę, że co do jednego się zgadzamy. Jak się uprzesz to napiszesz nawet testy symulujące małpę skaczącą przed kamerą ale ekonomicznie często nie ma to sensu i zwykłe "przeklikiwanie" okazuje się być najlepszą formą testowania. — katakrowa 26 minut temu

Oto klasa (napisana w Scali, ale to mocno imperatywny styl, raczej łatwo przekładający się na C++) symulująca zmieniający się w zadanych odstępach czasu sygnał zero-jedynkowy:

import BitSignalsIterator.SignalItem

import java.time.LocalDateTime
import scala.concurrent.duration._

class BitSignalsIterator private (startTimeNano: Long,
                                  signalsPrefixSum: Array[SignalItem],
                                  private var currentIndex: Int) {
  def currentBit(): Boolean = {
    val currDuration = System.nanoTime() - startTimeNano
    while (currentIndex < signalsPrefixSum.length && currDuration > signalsPrefixSum(currentIndex)._2) {
      currentIndex += 1
    }
    if (currentIndex >= signalsPrefixSum.length) {
      sys.error("signals buffer ended")
    } else {
      signalsPrefixSum(currentIndex)._1
    }
  }
}

object BitSignalsIterator {
  type InputSignal = (Boolean, FiniteDuration)
  type SignalItem  = (Boolean, Long)

  // factory method for class BitSignalIterator
  def apply(signals: Seq[InputSignal]): BitSignalsIterator = {
    val array              = Array.ofDim[SignalItem](signals.size)
    var cumulativeDuration = 0L
    for (((signal, duration), index) <- signals.zipWithIndex) {
      cumulativeDuration += duration.toNanos
      array(index) = (signal, cumulativeDuration)
    }
    new BitSignalsIterator(System.nanoTime(), array, 0)
  }

  // main method with example usage
  def main(args: Array[String]): Unit = {
    val signalsBuffer =
      Array(true -> 5.seconds, false -> 1.second, true -> 3.seconds, false -> 2.seconds)
    val signalsIterator = BitSignalsIterator(signalsBuffer)
    while (true) {
      println(LocalDateTime.now() + " " + signalsIterator.currentBit())
      Thread.sleep(1 * 650)
    }
  }
}

Wynik:

2021-04-01T12:58:11.712 true
2021-04-01T12:58:12.371 true
2021-04-01T12:58:13.021 true
2021-04-01T12:58:13.672 true
2021-04-01T12:58:14.322 true
2021-04-01T12:58:14.973 true
2021-04-01T12:58:15.623 true
2021-04-01T12:58:16.274 true
2021-04-01T12:58:16.924 false
2021-04-01T12:58:17.574 false
2021-04-01T12:58:18.225 true
2021-04-01T12:58:18.875 true
2021-04-01T12:58:19.525 true
2021-04-01T12:58:20.176 true
2021-04-01T12:58:20.826 false
2021-04-01T12:58:21.477 false
2021-04-01T12:58:22.128 false
Exception in thread "main" java.lang.RuntimeException: signals buffer ended
	at scala.sys.package$.error(package.scala:27)
	at BitSignalsIterator.currentBit(BitSignalsIterator.scala:15)
	at BitSignalsIterator$.main(BitSignalsIterator.scala:42)
	at BitSignalsIterator.main(BitSignalsIterator.scala)
3
heyyou napisał(a):

ja pisze testy jak mi sie nie chce klikać ;)

A ja klikam jak mi się nie chce pisać testów :)

Pobawię się trochę w adwokata diabła, bo wszyscy tu oczywiście konserwatywnie orędują za testami, "by the book", żadne wyzwanie :). A ja konserwatystą nie jestem. Przedstawię kilka argumentów, nie mają one raczej uniwersalnego charakteru, ale pokazują że jak zwykle wszystko zależy.

  1. Żeby napisać test trzeba wiedzieć czego się konkretnie oczekuje na wyjściu danej metody. Są działki gdzie, po pierwsze: nie zawsze wiadomo, po drugie: czasem to w ogóle nie jest ściśle określone. Przykładowo: moja metoda wyrzuca na wyjściu jakiś wektor liczb v. Nikt nie wie czy v[18] powinno być 9.2389 czy może 9.3445. Nawet nie ma możliwości na tym etapie określić jakiegoś progu. Po prostu nie wiem co jest prawidłowym wynikiem, bo to właśnie narzędzie które jest przedmiotem testu służy do określenia tego wyniku, którego ja w inny sposób poznać nie mogę. Gdybym mógł, to to narzędzie nie byłoby mi potrzebne.
  2. Przypadek zbliżony - narzędzie działa niedeterministycznie. Nie tylko nie mogę określić a'priori czy v[18] powinno być 9.2389 czy może 9.3445, ale to co dostanę na wyjściu raz będzie 9.2389, raz 9.3445, raz jeszcze czymś innym.
  3. Być może jestem w stanie ocenić dane wyjściowe, ale mogę to zrobić tylko w złożony sposób. Np. oczekuję by zbiór punktów na wyjściu tworzył oczekiwaną strukturę (skupiał się wokół płaszczyzny o zadanych parametrach). Mój test powinien zatem stworzyć tą płaszczyznę z parametrów i sprawdzić dopasowanie punktów. Ale to zadanie wymaga implementacji pewnej logiki, czasem równie skomplikowanej to ta w testowanej metodzie. To kłóci się trochę z ideą testów jednostkowych, które nie powinny zawierać skomplikowanej logiki. Bywa że i tak się to robi - przyjmując że po prostu oba algorytmy (zaimplementowany w teście i przedmiocie testu) weryfikują się wzajemnie, jeśli na końcu nie ma między nimi sprzeczności.
  4. Innym problemem jest gdy mogę sprawdzić jakość danych na wyjściu, ale potrzebuję je porównać z danymi referencyjnymi, a one zajmują mnóstwo miejsca (np. kilkaset MB).

Skąd zatem wiem, czy narzędzie robi w ogóle coś sensownego?

  • Analiza logiczna. Moje narzędzia są implementacją jakiegoś algorytmu, na który składają się poszczególne kroki. Czasem jedyną możliwością jest po prostu dogłębne przeanalizowanie zaimplementowanej logiki.
  • Szerszy kontekst. Moje dane wyjściowe da się zweryfikować, ale dopiero gdy nakarmi się nimi dalsze komponenty procesu. Istnieje metoda weryfikacji ostatecznego wyniku procesu, czasem jest to ocena dość subiektywna, i dopiero jeśli na tym etapie okaże się, że jakość jest niezadowalająca, to przeprowadza się "backtracing" to miejsca gdzie prawdopodobnie popełniono błąd. Czy można zmockować ten kontekst? Nie zawsze. Całość może być niezwykle złożona i wykraczająca poza jedną platformę narzędziową.
  • Smoke-test: mając doświadczenie jak generalnie wyglądają "właściwe" dane na wyjściu, przetwarzając wcześniej jakieś inne zbiory, można ocenić "z grubsza" czy narzędzie działa czy nie.
  • Przeklikanie :) - generalnie mając pewne doświadczenie, wiem jakie brzegowe lub problematyczne przypadki mogą prowadzić do powstania błędów. Mogę je zasymulować bezpośrednio w kodzie (nie w teście) i sprawdzić czy moje oczekiwania się sprawdziły.
2

Ja nie wierzę deweloperom, którzy mówią, że sprawdzili manualnie. Już nie raz widziałem, że albo kłamali albo źle sprawdzili.
Jeszcze jak to tester przeklikuje, to OK, bo jemu płacą za to, by znaleźć błąd. Ale developer często chce wypchnąć kod i przestać się martwić.

2
nalik napisał(a):

Ja nie wierzę deweloperom, którzy mówią, że sprawdzili manualnie.

Wypraszam sobie :)
Sprawdziłem manualne. Za pierwszym razem.
Za drugim razem sprawdziłem ogólnie czy po zmianach hula-kula.
Za trzecim razem - przecież zmiany nie były duże - sprawdzę przy następnej poprawce

2
GutekSan napisał(a):

Żeby napisać test trzeba wiedzieć czego się konkretnie oczekuje na wyjściu danej metody. Są działki gdzie, po pierwsze: nie zawsze wiadomo, po drugie: czasem to w ogóle nie jest ściśle określone. Przykładowo: moja metoda wyrzuca na wyjściu jakiś wektor liczb v. Nikt nie wie czy v[18] powinno być 9.2389 czy może 9.3445. Nawet nie ma możliwości na tym etapie określić jakiegoś progu. Po prostu nie wiem co jest prawidłowym wynikiem, bo to właśnie narzędzie które jest przedmiotem testu służy do określenia tego wyniku, którego ja w inny sposób poznać nie mogę. Gdybym mógł, to to narzędzie nie byłoby mi potrzebne.

Przecież można napisać test po zaimplementowaniu testowanej metody i to na podstawie jej wyników. W ten sposób i tak zyskujesz, bo masz test automatyczny i nie musisz klikać tego samego ponownie i porównywać. Później, gdy wprowadzisz np optymalizacje wydajnościowe, ten test pozwoli ci wyłapać potencjalne błędy wprowadzane przy takich zmianach.

0

Testy służą dowodzeniu, że dane funkcjonalności działają w zamierzony sposób i jest to równoznaczne matematycznemu dowodzeniu twierdzeń.

Możemy sami przeklikać się przez aplikację, ale inne osoby po za naszymi słowami nie mają żadnych dowodów.
Musieli by je wykonać sami, co może im zabrać kilka godzin przy dużym projekcie.
Pomijam fakt kiepskich testów lub inaczej źle, przeprowadzonych dowodów udowadniających ich tożsamość określoną w dokumentacji.

Nowe osoby dobierające się do projektu, mogą mieć większe problemy jeśli nie ma testów.
Także błędy łatwiej namierzyć jeśli wiemy, który test zawinił i nie musimy debugować całego projektu.

2

@Szalony Programista:

równoznaczne matematycznemu dowodzeniu twierdzeń.

prędzej formalne udowadnianie kodu tym jest

1 użytkowników online, w tym zalogowanych: 0, gości: 1