Testy / specyfikacje iOS TDD / BDD oraz testy integracji i akceptacji

229

Jakie są najlepsze technologie do programowania opartego na zachowaniu na iPhonie? A jakie są niektóre przykładowe projekty typu open source, które pokazują prawidłowe wykorzystanie tych technologii? Oto kilka opcji, które znalazłem:


Testów jednostkowych

Test :: Styl jednostki

  1. OCUnit / SenTestingKit zgodnie z objaśnieniem w Podręczniku programistycznym iOS: Aplikacje do testowania jednostkowego i inne odniesienia do OCUnit .
  2. ŁAPAĆ
  3. GHUnit
  4. Google Toolbox na komputery Mac: testy jednostkowe iPhone'a

Styl RSpec

  1. Kiwi (które zawiera także kpiny i oczekiwania)
  2. Cedr
  3. Jasmine z Automatyzacją interfejsu użytkownika, jak pokazano w zręcznych „Testach akceptacyjnych iOS”

Testy akceptacyjne

Styl selenowy

  1. Automatyzacja interfejsu użytkownika (działa na urządzeniu)

    AKTUALIZACJA: Zucchini Framework wydaje się łączyć automatykę Cucumber i UI! :)

    Stare posty na blogu:

  2. UISpec z UISpecRunner

  3. FoneMonkey

Styl Ogórkowy

  1. Frank i iCuke (na podstawie Ogórka spotyka iPhone'a )

  2. KIF (Keep It Functional) według Square

  3. Zucchini Framework używa składni Cucumber do pisania testów i używa CoffeeScript do definicji kroków.

Wzbogacenie

Wniosek

Cóż, oczywiście, nie ma właściwej odpowiedzi na to pytanie, ale oto, z czym obecnie wybieram:

Użyłem do testów jednostkowych OCUnit / SenTestingKit w XCode 4. To proste i solidne. Ale wolę język BDD niż TDD ( dlaczego RSpec jest lepszy od Test :: Unit ?), Ponieważ nasze słowa tworzą nasz świat. Teraz używam Kiwi z uzupełnianiem / autouzupełnianiem kodu ARC i Kiwi . Wolę Kiwi niż Cedar, ponieważ jest zbudowany na OCUnit i jest wyposażony w układy dopasowywania i symulacje / odcinki w stylu RSpec. AKTUALIZACJA: Teraz patrzę na OCMock, ponieważ obecnie Kiwi nie obsługuje karczowania obiektów mostowych bez opłat .

Do testowania akceptacji używam Automatyzacji interfejsu użytkownika, ponieważ jest niesamowity. Pozwala nagrywać każdy przypadek testowy, dzięki czemu pisanie testów jest automatyczne. Apple go rozwija, więc ma obiecującą przyszłość. Działa również na urządzeniu i w Instrumentach, co pozwala na inne fajne funkcje, takie jak pokazywanie wycieków pamięci. Niestety, dzięki UI Automation nie wiem, jak uruchomić kod Objective-C, ale z Frank i iCuke możesz. Więc po prostu przetestuję niższy poziom Objective-C za pomocą testów jednostkowych lub utworzę UIButtons tylko dla TESTkonfiguracji kompilacji , która po kliknięciu uruchomi kod Objective-C.

Z jakich rozwiązań korzystasz?

Powiązane pytania

mattdipasquale
źródło
1
przynajmniej kilka miesięcy temu wiem, że kluczowe laboratoria używały cedru. (hm, wydaje mi się, że to oczywiste, biorąc pod uwagę to na ich koncie github). Przy wsparciu takiego sklepu byłby to mój wybór.
Jed Schneider,
1
Trafne spostrzeżenie. Ale z drugiej strony, Apple sugerowałoby użycie ich struktury testów jednostkowych, a nie cedru, nie? Więc to jest Pivotal vs. Jabłko. Z którym iść?
ma11hew28,
2
Napisałem post porównujący Franka, KIF i UIAutomation, które mogą zainteresować czytelników tego wątku sgleadow.github.com/blog/2011/10/26/…
Gulasz

Odpowiedzi:

53

tl; dr

W Pivotal napisaliśmy Cedar, ponieważ używamy i kochamy Rspec w naszych projektach Ruby. Cedar nie ma na celu zastąpienia lub konkurowania z OCUnit; ma na celu wprowadzenie możliwości testowania w stylu BDD do Celu C, podobnie jak Rspec był pionierem w testowaniu w stylu BDD w Ruby, ale nie wyeliminował Test :: Unit. Wybór jednego lub drugiego jest w dużej mierze kwestią preferencji stylu.

W niektórych przypadkach zaprojektowaliśmy Cedar, aby wyeliminować pewne niedociągnięcia w sposobie działania OCUnit dla nas. W szczególności chcieliśmy móc używać debugera w testach, przeprowadzać testy z wiersza poleceń i kompilacji CI oraz uzyskiwać przydatne wyniki tekstowe wyników testów. Te rzeczy mogą być dla ciebie mniej lub bardziej przydatne.

Długa odpowiedź

Wybór między dwoma platformami testowymi, takimi jak Cedar i OCUnit (na przykład), sprowadza się do dwóch rzeczy: preferowanego stylu i łatwości użycia. Zacznę od stylu, ponieważ jest to po prostu kwestia opinii i preferencji; łatwość użycia jest zwykle zbiorem kompromisów.

Względy stylowe wykraczają poza używaną technologię lub język. Testy jednostkowe w stylu xUnit istnieją znacznie dłużej niż testy w stylu BDD, ale ta ostatnia szybko zyskała na popularności, głównie dzięki Rspec.

Podstawową zaletą testowania w stylu xUnit jest jego prostota i szerokie zastosowanie (wśród programistów, którzy piszą testy jednostkowe); prawie każdy język, w którym można rozważyć pisanie kodu, ma dostępne środowisko w stylu xUnit.

Frameworki w stylu BDD mają dwie główne różnice w porównaniu ze stylem xUnit: sposób strukturyzowania testu (lub specyfikacji) oraz składnia do pisania asercji. Dla mnie różnica strukturalna jest głównym wyróżnikiem. Testy xUnit są jednowymiarowe, z jedną metodą setUp dla wszystkich testów w danej klasie testów. Klasy, które testujemy, nie są jednak jednowymiarowe; często musimy testować działania w kilku różnych, potencjalnie sprzecznych kontekstach. Rozważmy na przykład prostą klasę ShoppingCart z metodą addItem: (do celów tej odpowiedzi użyję składni celu C). Zachowanie tej metody może się różnić, gdy wózek jest pusty, w porównaniu do tego, gdy wózek zawiera inne przedmioty; może się różnić, jeśli użytkownik wprowadził kod rabatowy; może się różnić, jeśli określony element może „ zostać wysłane wybraną metodą wysyłki; itd. Gdy te możliwe warunki przecinają się ze sobą, powstaje geometrycznie rosnąca liczba możliwych kontekstów; w testach w stylu xUnit często prowadzi to do wielu metod o nazwach takich jak testAddItemWhenCartIsEmptyAndNoDiscountCodeAndShippingMethodApplies. Struktura frameworków w stylu BDD pozwala ci indywidualnie organizować te warunki, co, moim zdaniem, ułatwia upewnienie się, że obejmuję wszystkie przypadki, a także łatwiej jest znaleźć, zmienić lub dodać indywidualne warunki. Na przykład przy użyciu składni Cedar powyższa metoda wygląda następująco: w testach w stylu xUnit często prowadzi to do wielu metod o nazwach takich jak testAddItemWhenCartIsEmptyAndNoDiscountCodeAndShippingMethodApplies. Struktura frameworków w stylu BDD pozwala ci indywidualnie organizować te warunki, co, moim zdaniem, ułatwia upewnienie się, że obejmuję wszystkie przypadki, a także łatwiej jest znaleźć, zmienić lub dodać indywidualne warunki. Na przykład przy użyciu składni Cedar powyższa metoda wygląda następująco: w testach w stylu xUnit często prowadzi to do wielu metod o nazwach takich jak testAddItemWhenCartIsEmptyAndNoDiscountCodeAndShippingMethodApplies. Struktura frameworków w stylu BDD pozwala ci indywidualnie organizować te warunki, co, moim zdaniem, ułatwia upewnienie się, że obejmuję wszystkie przypadki, a także łatwiej jest znaleźć, zmienić lub dodać indywidualne warunki. Na przykład przy użyciu składni Cedar powyższa metoda wygląda następująco:

describe(@"ShoppingCart", ^{
    describe(@"addItem:", ^{
        describe(@"when the cart is empty", ^{
            describe(@"with no discount code", ^{
                describe(@"when the shipping method applies to the item", ^{
                    it(@"should add the item to the cart", ^{
                        ...
                    });

                    it(@"should add the full price of the item to the overall price", ^{
                        ...
                    });
                });

                describe(@"when the shipping method does not apply to the item", ^{
                    ...
                });
            });

            describe(@"with a discount code", ^{
                ...
            });
        });

        describe(@"when the cart contains other items, ^{
            ...
        });
    });
});

W niektórych przypadkach można znaleźć konteksty zawierające te same zestawy twierdzeń, które można WYSUSZIĆ przy użyciu współużytkowanych kontekstów przykładowych.

Druga główna różnica między frameworkami w stylu BDD a frameworami w stylu xUnit, asercja (lub „dopasowywanie”), po prostu sprawia, że ​​styl specyfikacji jest nieco ładniejszy; niektórzy ludzie to lubią, inni nie.

To prowadzi do pytania o łatwość użycia. W takim przypadku każda struktura ma swoje zalety i wady:

  • OCUnit istnieje już znacznie dłużej niż Cedar i jest zintegrowany bezpośrednio z Xcode. Oznacza to, że łatwo jest utworzyć nowy cel testowy i przez większość czasu uruchomienie testów „po prostu działa”. Z drugiej strony okazało się, że w niektórych przypadkach, takich jak uruchomienie na urządzeniu z systemem iOS, uruchomienie testów OCUnit było prawie niemożliwe. Konfigurowanie specyfikacji Cedar wymaga nieco więcej pracy niż testy OCUnit, ponieważ masz bibliotekę i link do niej (nigdy nie jest to łatwe zadanie w Xcode). Pracujemy nad ułatwieniem konfiguracji, a wszelkie sugestie są mile widziane.

  • OCUnit uruchamia testy w ramach kompilacji. Oznacza to, że nie trzeba uruchamiać pliku wykonywalnego, aby uruchomić testy; jeśli jakiekolwiek testy zakończą się niepowodzeniem, kompilacja nie powiedzie się. To sprawia, że ​​proces uruchamiania testów jest o jeden krok prostszy, a wyniki testów trafiają bezpośrednio do okna wyników kompilacji, co ułatwia ich zobaczenie. Wybraliśmy, aby specyfikacje Cedar były wbudowane w plik wykonywalny, który uruchamiasz osobno z kilku powodów:

    • Chcieliśmy mieć możliwość korzystania z debuggera. Uruchamiasz specyfikacje Cedar tak samo, jak inne pliki wykonywalne, więc możesz używać debugera w ten sam sposób.
    • Chcieliśmy łatwych testów logowania do konsoli. Możesz użyć NSLog () w testach OCUnit, ale dane wyjściowe trafiają do okna kompilacji, gdzie musisz rozłożyć etap kompilacji, aby go odczytać.
    • Chcieliśmy łatwego do odczytania raportowania z testów, zarówno w wierszu poleceń, jak iw Xcode. Wyniki OCUnit ładnie wyświetlają się w oknie kompilacji w Xcode, ale kompilacja z wiersza poleceń (lub jako część procesu CI) powoduje, że wyniki testu przeplatają się z mnóstwem innych wyników kompilacji. Dzięki osobnym fazom kompilacji i uruchamiania Cedar oddziela dane wyjściowe, dzięki czemu wyniki testowe można łatwo znaleźć. Domyślny program uruchamiający Cedar kopiuje standardowy styl drukowania „”. dla każdej mijającej specyfikacji, „F” dla niespełniających specyfikacji itp. Cedar ma również możliwość korzystania z niestandardowych obiektów reportera, dzięki czemu można uzyskać wyniki w dowolny sposób, przy niewielkim wysiłku.
  • OCUnit to oficjalna platforma testowania jednostek dla Celu C, obsługiwana przez Apple. Apple ma w zasadzie nieograniczone zasoby, więc jeśli chcą coś zrobić, zostanie to zrobione. I w końcu to jest piaskownica Apple, w którą gramy. Jednak drugą stroną tej monety jest to, że Apple otrzymuje codziennie rzędu bajillionów próśb o wsparcie i raportów o błędach. Są wyjątkowo dobrzy w radzeniu sobie z nimi wszystkimi, ale mogą nie być w stanie poradzić sobie z problemami zgłaszanymi natychmiast lub wcale. Cedar jest znacznie nowszy i mniej upieczony niż OCUnit, ale jeśli masz pytania, problemy lub sugestie, wyślij wiadomość na listę mailingową Cedar ([email protected]), a my zrobimy co w naszej mocy, aby ci pomóc. Ponadto możesz rozwidlić kod z Github (github.com/pivotal/cedar) i dodać wszystko, co Twoim zdaniem brakuje.

  • Przeprowadzanie testów OCUnit na urządzeniach z iOS może być trudne. Szczerze mówiąc, nie próbowałem tego od dłuższego czasu, więc mogło być łatwiej, ale ostatnim razem po prostu nie mogłem uzyskać testów OCUnit pod kątem działania jakiejkolwiek funkcji UIKit. Kiedy pisaliśmy Cedar, upewniliśmy się, że możemy przetestować kod zależny od UIKit zarówno na symulatorze, jak i na urządzeniach.

Na koniec napisaliśmy Cedar do testów jednostkowych, co oznacza, że ​​tak naprawdę nie jest porównywalny z projektami takimi jak UISpec. Minęło sporo czasu, odkąd próbowałem używać UISpec, ale zrozumiałem, że koncentruje się przede wszystkim na programowym sterowaniu interfejsem użytkownika na urządzeniu z systemem iOS. W szczególności zdecydowaliśmy, że nie będziemy starać się, aby Cedar wspierał tego rodzaju specyfikacje, ponieważ Apple miał (wtedy) ogłosić UIAutomation.

Adam Milligan
źródło
Dzięki za dokładną odpowiedź. Przeczytam książkę RSpec i wypróbuję Cedera. Przeniosłem UISpec do sekcji Selenium i tam też dodałem UIAutomation. Czytam twój post na blogu o UIAutomation. Frank faktycznie wygląda na znacznie prostszy i bardziej czytelny, a także lepiej udokumentowany, więc myślę od tego zacząć. Mam tylko nadzieję, że jest tak potężny jak UIAutomation. Mówisz, że UIAutomation może testować problemy związane z cyklem życia. Zastanawiam się, czy iCuke też może ...
ma11hew28,
8

Będę musiał wrzucić Franka do zestawu testów akceptacyjnych. Jest to dość nowy dodatek, ale do tej pory działał doskonale dla mnie. Ponadto, w przeciwieństwie do icuke i innych, jest aktywnie nad tym pracowany.

raidfive
źródło
5

Do programowania opartego na testach lubię używać GHUnit , którego konfiguracja jest dziecinnie prosta, i świetnie nadaje się również do debugowania.

Richard J. Ross III
źródło
Dzięki. Widziałem to, ale zapomniałem o tym wspomnieć.
ma11hew28,
PLus 1 dla GHUnit. użyłem go dużo z OCMock. Łatwa konfiguracja, rozbudowa i bardzo niezawodne działanie.
drekka
4

Świetna lista!

Znalazłem inne interesujące rozwiązanie do testowania interfejsu użytkownika aplikacji na iOS.

Zucchini Framework

Opiera się na UIAutomation . Struktura pozwala pisać scenariusze zorientowane na ekran w stylu Ogórek. Scenariusze mogą być wykonywane w Symulatorze i na urządzeniu z konsoli (jest przyjazny dla CI).

Asercje oparte są na zrzutach ekranu. Brzmi nieelastycznie, ale daje ci niezły raport HTML, z wyróżnionym porównaniem ekranu i możesz dostarczyć maski, które określają regiony, w których chcesz precyzyjnie potwierdzić piksele.

Każdy ekran musi być opisany, CoffeScripta samo narzędzie napisane w rubinie. Jest to rodzaj koszmaru poliglota, ale narzędzie zapewnia przyjemną abstrakcję, UIAutomationa kiedy opisano ekrany, można je zarządzać nawet dla osoby odpowiedzialnej za kontrolę jakości.

1129998
źródło
Mocno! Dzięki. Dodałem to do powyższego pytania.
ma11hew28
2

Wybrałbym iCuke do testów akceptacyjnych i Cedar do testów jednostkowych. UIAutomation to krok w dobrym kierunku dla Apple, ale narzędzia potrzebują lepszego wsparcia dla ciągłej integracji; na przykład automatyczne uruchamianie testów UIAutomation z przyrządami nie jest obecnie możliwe.

SamCee
źródło
1

GHUnit jest dobry do testów jednostkowych; do testów integracyjnych użyłem UISpec z pewnym powodzeniem (github fork tutaj: https://github.com/drync/UISpec ), ale nie mogę się doczekać wypróbowania iCuke, ponieważ zapowiada się lekka konfiguracja i możesz używaj szyn testujących dobroć, takich jak RSpec i Cucumber.

Obrabować
źródło
1

Używam obecnie Specta dla RSpec jak konfiguracje i jest partnerem (jak wspomniano powyżej) expecta który ma ton na awesome opcji dopasowania.

Keith Smiley
źródło
0

Zdarza mi się naprawdę lubić OCDSpec2, ale jestem stronniczy, napisałem OCDSpec i przyczyniłem się do drugiego.

Jest bardzo szybki nawet na iOS, częściowo dlatego, że jest zbudowany od podstaw, a nie na OCUnit. Ma również składnię RSpec / Jasmine.

https://github.com/ericmeyer/ocdspec2

Eric Smith
źródło