Zadanie test jednostkowy

0

Hej mam problem jak porownac czy wartosci w liscie sa prawidlowe po wykonaniu metody, Wiem ze musze to zrobic za pomoca assert. Metoda dziala poprawnie bo pobiera tylko wartosci parzyste (porownanie wielkosci listy sie zgadza)

@Test
public void testOddNumbersExterminatorNormalList() {
    //Given
    OddNumbersExterminator exterminator = new OddNumbersExterminator();
    ArrayList<Integer> normalList = new ArrayList<>();
            normalList.add(4);
            normalList.add(7);
            normalList.add(8);
            normalList.add(11);
            normalList.add(13);
            normalList.add(16);
            normalList.add(18);
            normalList.add(19);
    //When
    ArrayList<Integer> normalTestList = exterminator.exterminate(new ArrayList<Integer>(normalList));
    //Then
    Assert.assertEquals(4, normalTestList.size());
    Assert.assertEquals((4, 8 , 16, 18), normalTestList);
}
0

tutaj klasa z metoda

package com.kodilla.testing.collection;

import java.util.ArrayList;

public class OddNumbersExterminator {
    public ArrayList<Integer> exterminate(ArrayList<Integer> numbers) {
        ArrayList<Integer> evenNumbers = new ArrayList<>();
        for(int number : numbers) {
            if(number % 2 == 0)
            {
                evenNumbers.add(number);
            }
        }
        return evenNumbers;
    }
}
1

Czy kolejność elementów ma znaczenie? Jeśli tak, to assertEquals(list1, list2) da pożądany efekt. Na marginesie - polecam przesiąść się na AssertJ.

0

Ja bym osobiście w tym teście zrobił:

  • losowy rozmiar inputu
  • losowe wartości w inpucie (a potem zrobił parzyste za pomocą 2*x i nie parzyste 2*x+1
0

Ja bym zminimalizował input, ponieważ filtrowanie listy 10 elementów niczym nie różni się od filtrowania 2-3 elementów, a łatwiej się to czyta. Do tego test na pustą listę. Przy TDD takie przypadki testowe powinny wyjść naturalnie. Nie jestem też fanem losowego inputu :)

0
Charles_Ray napisał(a):

Nie jestem też fanem losowego inputu :)

FIRST to m.in. Repeatable
Jak w losowym input, w losowym przypadku, wyjdzie raz red to jak wrócić do input który wyłożył test?
Dlatego losowe dane IMO nie powinny być używane. Tylko dobrane do granicznych przypadków.

Z drugiej strony

Nie mam na szybko pomysłu na skopanie: eliminacja parzyste/nieparzyste raczej nie wyłoży się tylko raz na któryś raz

Ale np. proste binary search dla losowej tablicy z losową wielkością może się wyłożyć z zaskoczenia np. na przekroczeniu Integer.MAX
kiedy liczymy mid = (left + right)/2
a nie mid = left + (right-left)/2

Do przetestowania przypadki skrajne: null, pusta kolekcja, 1 element i problem przy przekraczaniu zakresu typu (left+right) przepełni zakres kiedy obie zmienne-indeksy będą zaraz po połowie zakresu dla int a nie jak można się spodziewać przy przekroczeniu rozmiaru tablicy ponad zakres int.

Zakres indeksu to jedno.
Czy da się zaalokować dużą tablicę? Jak dużą?
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
Czy moje i tam gdzie polecą testy ustawienia JVM będą takie jak na maszynie gdzie będzie pracować kod?

Jak na swojej lokalnej maszynie nie puścisz trochę losowych danych, ale nie pętelka 0..100, tylko np. po całym zakresie typu danych, to może umknąć coś o czym nie pomyślałeś.
Później do wyciągnięcia wnioski, oszacowanie granicznych przypadków, dla nich opracowane konkretne testy i takie testy z danymi na twardo do udostępnienia.

0

FIRST to m.in. Repeatable

żelazna logika, lepiej nie znaleźć błędu, niż znaleźć na losowych danych :D Rozumiem ze mutation tests też nie stosujecie z tego samego wzlgędu? ;)

0

Napisałem, z jednej strony FIRST, z drugiej strony losowe dane kontra o czym nie pomyślał developer.
Szerokie pole do interpretacji kiedy można szybko zamknąć temat a kiedy nie.
Czy czasem spuszcza się temat po brzytwie? Tak. Dlaczego? Bo takie jest polecenie (priorytety). Nie wszystko to krytyczny lot na Marsa i świadomie zakłada się ponowne podejście przy następnym zgłoszeniu (kiedyś, najlepiej "nie na mojej zmianie").

0

@Shalom przy tym testowym inpucie jaką masz pewność, że wykryje błąd przed użytkownikiem na prodzie? Ile razy będziesz puszczał taki test? :)

0
BraVolt napisał(a):
Charles_Ray napisał(a):

Nie jestem też fanem losowego inputu :)

Jak w losowym input, w losowym przypadku, wyjdzie raz red to jak wrócić do input który wyłożył test?
Dlatego losowe dane IMO nie powinny być używane. Tylko dobrane do granicznych przypadków.

Nic prostszego, większość bibliotek zrobi nawet o wiele więcej za Ciebie. Poza tym, że pokaże Ci dane dla jakich test zfailował to jednocześnie postara się je ograniczyć do jak najdokładniejszych wartości które również failują (shrinking) i poda seed'a, żebyś mógł sobie odpalić test z tymi konkretnymi danymi. Tak więc, jak widzisz, ostatnie czym się martwisz w takich testach to jak odtworzyć zfailowany test.

Charles_Ray napisał(a):

przy tym testowym inpucie jaką masz pewność, że wykryje błąd przed użytkownikiem na prodzie? Ile razy będziesz puszczał taki test?

Tyle samo razy - za każdym razem jak idzie build na CI. Z tym, że tutaj dochodzimy do kolejnej rzeczy - rzadko kiedy puszcza się testy z losowymi danymi tylko raz (mówimy o unitach). Zazwyczaj jest to kilkanaście bądź kilkadziesiąt razy bo koszt jest niewielki, a kod masz przetestowany znacznie bardziej niż w przypadku puszczania w kółko tych samych testów z tymi samymi danymi.
Kluczem jest zrozumienie gdzie jaki typ testów się sprawdza. Nie wszędzie wepchniesz property based testing bo nie wszędzie ma to sens, ale działa to też w drugą stronę. W przykładzie podanym przez założyciela tematu losowe dane są jak najbardziej ok. Łatwo wyznaczyć właściwości jakie dana funkcjonalność ma przestrzegać - w całym zakresie typu danych, a nie tylko w kilku konkretnych przypadkach.

0

Dzięki za wyjaśnienie. Co prawda na dwoje babka wróżyła, nie wiem czy mam odpalić to 1000 razy czy miljon, natomiast widzę wartość w takich testach jeśli mamy jakiś problem stricte obliczeniowy czy algorytmiczny. Natomiast IMO jedynie jako dopełnienie, a nie wiodąca technika testowania.

0

Natomiast IMO jedynie jako dopełnienie, a nie wiodąca technika testowania.

Moim zdaniem nie ma panaceum żadnego. Nie ma jednego typu testów które wystarczą za wszystko :)

0
Charles_Ray napisał(a):

Dzięki za wyjaśnienie. Co prawda na dwoje babka wróżyła, nie wiem czy mam odpalić to 1000 razy czy miljon, natomiast widzę wartość w takich testach jeśli mamy jakiś problem stricte obliczeniowy czy algorytmiczny.

Też nie bardzo czuję ideę takich testów, wrzucam swój patch, lecą testy odpalane dziesiątki, setki, tysiące? razy na losowych danych. Co mają znaleźć? W jednym miejscu źle określone warunki brzegowe? Co jaki czas ma polecieć błąd z takich testów? Często? Nie przemyślana implementacja kodu, nie ogarnia danych, warunków. Rzadko? Rzadziej niż znalezione problemy w logu albo zgłoszone przez użytkownika?

1
BraVolt napisał(a):
Charles_Ray napisał(a):

Dzięki za wyjaśnienie. Co prawda na dwoje babka wróżyła, nie wiem czy mam odpalić to 1000 razy czy miljon, natomiast widzę wartość w takich testach jeśli mamy jakiś problem stricte obliczeniowy czy algorytmiczny.

Też nie bardzo czuję ideę takich testów, wrzucam swój patch, lecą testy odpalane dziesiątki, setki, tysiące? razy na losowych danych. Co mają znaleźć? W jednym miejscu źle określone warunki brzegowe? Co jaki czas ma polecieć błąd z takich testów? Często? Nie przemyślana implementacja kodu, nie ogarnia danych, warunków. Rzadko? Rzadziej niż znalezione problemy w logu albo zgłoszone przez użytkownika?

Ile razy są odpalane zależy od Ciebie, ot zwykły parametr w konfiguracji danego suitu. Przykładowo w Scalachecku jest to 60 razy, o ile mnie pamięć nie myli.
Mają znaleźć wszystko to, co potencjalnie programista mógł pominąć bo zapomniał, nie wiedział, bądź zwyczajnie przeoczył. Czy to są źle określone warunki brzegowe czy też błąd w logice dla jakiejś danej - większego znaczenia nie ma.
Najlepiej to żeby nigdy nie leciał błąd z takich testów (tak jak i z każdych innych ;)). W rzeczywistości, zacząłem pisać niektóre testy w takim stylu może rok temu i do tej pory znalazły potencjalnych błędów może kilka, pewnie na palcach jednej ręki policzysz. Co nie zmienia faktu - jest to kilka błędów, które zostały znalezione na poziomie testów, a nie produkcji.

Trzeba pamiętać, że narzędzie powinno być dobrane do problemu. Jeśli system przy którym pracujesz pozwala na wprowadzenie buga na produkcji i nie będzie to wielkim problemem to jasne, pisanie takich testów może być kosztem który nigdy się nie zwróci. Z drugiej strony, jeśli jednym z wymagań pracy w projekcie jest minimalizowanie ryzyka błędów na prodzie, to wtedy warto pomyśleć czy nie zacząć testować w taki sposób.

Tak czy siak polecam spróbować napisać kilka testów w takim stylu, ot tak z czystej ciekawości :)

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