def find_limits
aet = Namespace::ClassName.arel_table
person.
association_name.
where( aet[:from].le(to) ).
where( aet[:to].ge(from) ).
where( aet[:used].lt(aet[:quota]) ).
where( aet[:type_id].in( types.map(&:id) ) ).
order(‘column1 ASC, column2 ASC, column3 ASC’).
all
end
end[/code]
Jak ją przetestować? Mogę stworzyć oczywiście na bazie kilka rekordów, wywołać ją i sprawdzić czy zwrócone wyniki są tymi, których oczekuję, ale czy to dobre podejście ?
Mógłbym też użyć mocha i sprawdzić czy poszczególne wher’y są wywołane ale to się chyba mija z cele bo napiszę test, który wygląda dokładnie tak samo jak metoda, którą testuje…
Dokładnie. Dodatkowo problem ze scope’ami problem jest taki, że nigdy nie masz pewności, że jeżeli 2 scope’y są poprawne, to ich połączenie będzie poprawne. W Twoim przypadku jest to tylko kilka where i order, więc nie ma raczej takiej możliwości, ale wystarczy, że dorzucisz coś bardziej skomplikowanego (jakiś join) i już nie masz pewności czy to dalej działa tak jak powinno.
Dodatkowo warto testować na próbce realnych danych wziętych z produkcji (oczywiście jeśli nie ma przeszkód prawnych i a projekt jest już w produkcji). Ewentualnie postarać się o jakieś dane zbliżone do realnych. Zwykle pokazuje to sporo problemów, które nie wychodzą przy kilku ręcznie stworzonych rekordach.
@apohllo - nie do końca rozumiem co mam na myśli. Zakładając, że mam dane realne (akurat ich nie mam) jak miałbym ich użyć do testowania czegoś w aplikacji w testach automatycznych ? Potrafię to sobie wyobrazić przy testach integracyjnych ale jednostkowych nie bardzo.
Wciąż nie rozumiem
Musisz być konkretny zamiast użyć jednego skrótu myślowego.
Po prostu nie wiem jakbym miał tych danych użyć w teście? Może lepsze pytanie to: do czego ?
Gdyby były jakieś dziwne dane na produkcji, które generują nietypowe wyniki w kodzie z powodu błędu to:
a) już wiem o ty rekordach bo ten błąd się obawił
b) jeszcze o tym nie wiem bo błąd się nie objawił
W przypadku a) fixując bład mogę dodać nowe case’y do testu - te o których wiem, że powodowały problemy.
W przypadku b) ? Chyba nic nie mogę zrobić bo nawet nie wiem przy jakich wartościach nie działa, więc nie wiem wg czego miałbym tych złych rekordów poszukać.
Nie wiem co miał na myśli Filip, ale mnie chodzi o to, że ręczne tworzenie rekordów jest co najmniej żmudne, a przez to zazwyczaj robi się to metodą kopij-wklej. Jeśli masz realne dane, albo generator danych zbliżonych do realnych i masz nie 5 a 500 rekordów, to taki zbiór jest zdecydowanie lepszy do testowania, w szczególności złożonych zapytań. Jeśli masz 5 kryteriów i 5 rekordów, to z dużym prawdopodobieństwem mogę przewidzieć, że spośród teoretycznych 2^5=32 grup danych (dla 5 binarnych warunków) będziesz miał co najwyżej 5, a najpewniej jakieś 2-3. Zatem posiadanie próbki realnych danych zwalnia cię z konieczności tworzenie setek rekordów.
Czy to się nadaje tylko do testów integracyjnych? Raczej nie. Jak zatem określić poprawny wynik - dla kilku parametrów z palca piszesz zapytanie SQL i patrzysz na wyniki (takie zapytanie może być znacznie prostsze niż to które jest testowana, bo możesz wykorzystać pewne dodatkowe założenia, np. wynikające ze struktury bazy). Możesz też te dane wrzucić do Excela (np. kilka tabel połączonych w jedną) i tam obliczać sobie poprawne/pożądane wartości.
Oczywiście zasadnicze pytanie brzmi - czy jest sens bawić się w takie rzeczy, no ale to już zależy od Ciebie i Twojej aplikacji.
Ale uważasz, że powinno się wrzucić 500 rekordów do testu i na nich robić testować, czy czy jeśli wiem, że z tych 500 to tylko 2 wyniki pasują to dodać do testu jeden z nich ?
Dodajesz kilka, które powinny zostać zwrócone, i kilka które nie powinny zostać. Gdzie podstawienie kilka=1 to minimum, kilka=2 w zupełności wystarczy, a kilka=3 to już będzie overkill.
tak jak pisze Tomasz 1,2 przypadki pozytywne/negatywne
przypadki z granic warunków (tzn. jeśli <18 to bierzesz jeden <18 i jeden = 18) (co nie stoi w sprzeczności z poprzednim punktem)
patrzysz tylko na statystyki - nie testujesz konkretnych wartości, ale liczbę zwróconych rekordów (wtedy przydaje się tabelka w Excelu)
Tyle, że bez przesady - takie testy robiłbym dla biblioteki, która ma być używana w wielu kluczowych projektach. W przypadku aplikacji końcowych, takie zagadnienie przerzuciłbym na testy integracyjne/akceptacyjne.
Zważywszy na fakt, że testy integracyjne są dużo dłuższe w wykonywaniu oraz bardziej czasochłonne w utrzymywaniu staram sie raczej prawie wszystko testowac w jednostkowych. W Akcpetacyjnych 1 case negatywny i 1 pozytywny, żeby przetestować cały stack i to tyle.