Automatyzacja procesu testowego Prowadzący: Michał Zarzycki Krzysztof Prochowicz 1 Agenda 1. Wprowadzenie Omówienie pojęć związanych z automatyzacją testów 2. Porównanie testów manualnych i automatycznych (wady i zalety) 3. Omówienie narzędzi do zarządzania i wykonywania testów: Zarządzanie testami: IBM Rational Clear Quest Testy funkcjonalne (IBM Rational Functional Tester, Automated QA TestComplete) Testy wydajnościowe (Mercury Loadrunner) Testy modułowe (xunit) 2 1
Rodzaje testów automatycznych Testy modułowe Testowanie pojedynczych modułów programu Tworzone przez programistów dla programistów. Testy obciąŝeniowe Testowanie przeprowadzane w celu określenia wydajności oprogramowania. Tworzone i przeprowadzane przez testerów. Testy funkcjonalne Testowanie wykonywane w oparciu o analizę specyfikacji funkcjonalności systemu lub jego modułu. Tworzone i przeprowadzane przez testerów. 3 Kandydaci i antykandydaci do automatyzacji testów Potencjalni kandydaci: ilość danych testowych, częstotliwość wykorzystania, stabilność aplikacji, dokumentacja Potencjalni antykandydaci: duŝa złoŝoność, częsta modyfikowalność, skomplikowane przygotowanie danych testowych 4 2
Zalety automatyzacji Koszty wykrycia błędu są mniejsze Testy modułowe MoŜliwość podania duŝej liczby danych testowych - Testy wydajnościowe Analiza testów - program po zakończeniu testowania dostarcza informacje o jego przebiegu. MoŜliwość odtworzenia identycznego testu - jest to szczególnie przydatne kiedy chcemy sprawdzić, czy wprowadzone poprawki rozwiązały problem. Znaczny wzrost prędkości testowania - programy testujące przeprowadzają testy znacznie szybciej niŝ testerzy. 5 Wady automatyzacji Koszty związane: z zakupem narzędzi do automatyzacji, ze szkoleniami, z wykonaniem skryptów, z rozwojem i utrzymaniem skryptów. Automat testowy nie zastąpi człowieka - nie dokona analizy logów, klasyfikacji nieprawidłowości i błędów, nie zgłosi błędów do poprawy 6 3
Testy manualne wciąŝ potrzebne Wykorzystując automaty testowe nie zaobserwowano zwiększonej wykrywalności błędów, zwłaszcza w odniesieniu do testów regresji Większość błędów jest wykrywanych podczas testów manualnych (zwłaszcza podczas testów nowej funkcjonalności) Testy manualne są wykonywane zawsze! 7 Narzędzia wspomagające pracę testerów UŜycie oprogramowania do: wsparcia czynności testowych, np. do zarządzania testami, projektowania i sprawdzania rezultatów. wykonania testów - ciągłe wykonywanie sekwencji działań bez ingerencji człowieka, pomagające eliminować ludzkie błędy, dające szybszy rezultat. 8 4
IBM Rational Clear Quest Monitorowanie zmian i defektów Rozbudowane funkcje tworzenia wykresów i raportów Interfejs WWW ułatwiający korzystanie z programu za pośrednictwem standardowych przeglądarek Ścisła integracja z programem Rational ClearCase i Rational Test Manager Integracja z wielomaśrodowiskami: WebSphere Studio, Eclipse i Microsoft.NET. 9 Clear Quest - wersja stacjonarna 10 5
11 Przykład - zgłaszania defektu 12 6
Wersja WWW zgłaszanie defektu 13 Testy funkcjonalne IBM Rational Functional Tester / Automated QA TestComplete 14 7
Automatyzacja testów funkcjonalnych Capture & replay Technika polegająca na rejestrowaniu za pomocą specjalnych programów (np. TestComplete, Rational Fuctional Tester itd.) zachowania uŝytkownika, a następnie dokładne odtwarzanie go. Rejestrowane są takie zachowania jak np. kliknięcie myszką, wpisanie wartości w pole, rozwiniecie menu itp 15 Przykładowe narzędzia IBM Rational Functional Tester - zaawansowane, zautomatyzowane narzędzie do testowania funkcjonalnego i regresywnego, przeznaczone dla testerów i twórców interfejsów graficznych, potrzebujących lepiej kontrolować aplikacje w technologiach Java, VS.NET, webowych i konstruowane z gotowych pakietów typu SAP i Siebel. Automated QA TestComplete - narzędzie wspiera tworzenie testów modułowych, funkcjonalnych, regresyjnych, pozwala testować aplikacje rozproszone i badać wydajność aplikacji WWW. 16 8
Testy wydajnościowe Mercury Loadrunner 17 Rodzaje testów wydajnościowych Performance testing badanie czasu odpowiedzi krytycznych dla biznesu funkcji systemu porównywanie czasu odpowiedzi przejścia pojedynczego vs. wielu uŝytkowników przez aplikację kryterium testów jest sprawdzenie czy poszczególne akcje wykonywane są przez aplikację w akceptowalnym przedziale czasowym 18 9
Stress testing załoŝenie: zbyt wielu uŝytkowników, danych, czasu oraz malejące zasoby systemowe badanie czy system zawiedzie w oczekiwany sposób wyszukiwanie defektów w aplikacji działającej w trybie awaryjnym sprawdzanie konsekwencji utraty danych po awarii wywołanej nadmiernym obciąŝeniem Load testing Rodzaje testów obciąŝeniowych duŝa liczba jednocześnie działających uŝytkowników / przeprowadzanych transakcji utrzymanie takiego stanu przez określony w scenariuszu czas jak wiele zapytań (requests) jest w stanie obsłuŝyć system w określonym przedziale czasu. Główne kryterium: jak wiele zamiast jak szybko. 19 Komponenty LoadRunner a Generator wirtualnych uŝytkowników generowanie skryptów, vusers, parametryzacja Kontroler wraz z agentem procesów uruchamianie skryptów, scenariusze, generatory vusers Moduł analizy i monitorowania Bottlenecks (wąskie gardła), warstwy 20 10
Mercury LoadRunner: Wirtualni uŝytkownicy Wirtualni uŝytkownicy (Vusers) emulują akcje podejmowane przez człowieka Zwiększenie liczby wirtualnych uŝytkowników powoduje zwiększenie obciąŝenia testowanego systemu Wielu wirtualnych uŝytkowników moŝe działać na pojedynczym komputerze 21 Mercury LoadRunner: Generator wirtualnych uŝytkowników Definiuje akcje, podejmowane są przez przez wirtualnych uŝytkowników. Typowe akcje: logowanie, nawigacja po aplikacji, wychodzenie z programu. Serie akcji przechowywane są w wygenerowanych skryptach. 22 11
23 Mercury LoadRunner: Kontroler Uruchamia skrypt stworzony w generatorze w oparciu o warunki przeprowadzenia testu. Przykładowe warunki: liczba wirtualnych uŝytkowników, czas trwania testu, kryteria zakończenia scenariusza (określony czas trwania lub osiągnięcie zdefiniowanej liczby wirtualnych uŝytkowników) 24 12
Mercury LoadRunner: Kontroler 25 Mercury LoadRunner: Moduł analizy i monitorowania Prezentuje wyniki testów w formie grafów, danych sumarycznych lub szczegółowych widoków. Pozwala zidentyfikować w aplikacji miejsca powodujące spowolnienie jej działania 26 13
Mercury LoadRunner: Moduł analizy i monitorowania 27 Mercury LoadRunner: Moduł analizy i monitorowania 28 14
Testy modułowe xunit Krzysztof Prochowicz 29 Testy modułowe - przypomnienie (ang. unit/component testing) Wyszukiwanie defektów w pojedynczych komponentach systemu (np. w modułach, obiektach, klasach itp.), które mogą być testowane oddzielnie Komponenty testowane są w separacji od siebie, Przygotowywane są przez programistę / autora, Projektowane w oparciu o strukturę kodu, Znalezione defekty są poprawiane od razu, bez formalnego zgłaszania 30 15
XUnit: środowiska do tworzenia testów modułowych www.junit.org www.vbunit.org cppunit.sourceforge.net www.nunit.org MSUnit 31 Typowy scenariusz public class Account private int balance; public Account() this.balance = 0; public void Deposit(int amount) balance+=amount; 1. Arrange Stwórz instancję testowanej klasy i ustaw stan początkowy 2. Act Wywołaj jedną lub więcej metod testowanej klasy [TestClass] public class AccountTest [TestMethod] public void Deposit() 1 2 3 Account account = new Account(); int amount = 100; account.deposit(amount); int expectedbalance = amount; int actualbalance = account.balance; Assert.AreEqual(expectedBalance, actualbalance); 3. Assert Zweryfikuj rezultat 32 16
Asserty (weryfikacja) Assert.AreEqual( int expected, int actual ); Assert.AreEqual( int expected, int actual, string message ); Assert.AreSame( object expected, object actual ); Assert.Contains( object anobject, IList collection ); Assert.IsTrue( bool condition ); Assert.IsFalse( bool condition); Assert.IsNull( object anobject ); Assert.IsEmpty( string astring ); Assert.IsEmpty( ICollection collection ); StringAssert.Contains( string expected, string actual ); StringAssert.StartsWith( string expected, string actual ); StringAssert.AreEqualIgnoringCase( string expected, string actual ); Assert.Fail(); 33 Obsługa wyjątków [TestMethod] [ExpectedException(typeof(myException))] public void Withdraw() int initialamount = 100; account.deposit(initialamount); int amount = 150; account.withdraw(amount); int expectedbalance = initialamount int actualbalance = account.balance; Assert.AreEqual(expectedBalance, actualbalance); [TestMethod] public void Withdraw() int initialamount = 100; account.deposit(initialamount); int amount = 150; try account.withdraw(amount); Assert.Fail( Exception expected"); catch (InsufficientFundsException) int expectedbalance = initialamount int actualbalance = account.balance; Assert.AreEqual(expectedBalance, actualbalance); 34 17
Co z modułami zaleŝnymi od innych modułów? Unit Under Test Data Access Object insert update delete get RDBMS 35 Mock Implementuje ten sam interfejs co klasa jaką zastępuje UmoŜliwia konfigurację swojego zachowania z zewnątrz, czyli np. z klasy testowej UmoŜliwia zliczanie ilości wywołań UnitTest «creates» «creates» Unit Under Test «interface» Data Access Object insert update delete get MockDAO DaoImpl 36 18
public class Account public const int SUPERVISION_THRESHOLD = 100000; private ISupervisor supervisor; public enum TransactionType Deposit, Withdrawal; private int balance; private string id; public Account(string id) this.id = id; this.balance = 0; public void Deposit(int amount) balance+=amount; if (amount > SUPERVISION_THRESHOLD && supervisor!= null) supervisor.notify(this.id, this.owner, TransactionType.Deposit, amount); public interface ISupervisor void Notify(string id, Account.TransactionType type, int amount); Przykład NMock 1 2 3 4 [TestMethod] public void LargeDepositShouldTriggerNotification() String id = "id"; int amount = Account.SUPERVISION_THRESHOLD + 1; Mockery mocks = new Mockery(); ISupervisor mocksupervisor = (ISupervisor) mocks.newmock(typeof(isupervisor)); Expect.Once.On(mockSupervisor).Method("Notify").With(id, Account.TransactionType.Deposit, amount); Account source = new Account(); source.supervisor = mocksupervisor; source.deposit(amount); int expectedbalance = amount; int actualbalance = account.balance; Assert.AreEqual(expectedBalance, actualbalance); mocks.verifyallexpectationshavebeenmet(); 1. Stworzenie Mock a 2. Ustawienie oczekiwań 3. Podstawowy kod Unit Testu 4. Weryfikacja 37 NMock oczekiwania Podstawowa składnia oczekiwania: Expect.Once.On(obiekt mock).method(nazwa metody).with(wartości parametrów wejściowych).will(return.value(wartość))) Expect.Once.On(obiekt mock).method(nazwa metody).with(wartości parametrów wejściowych.will(throw.exception(wyjątek)); Expect.Once.On(obiekt mock).getproperty(nazwa atrybutu).will(return.value( wartość ); Expect.Once.On(obiekt mock).setproperty(nazwa atrybutu).to(wartość); MoŜliwe inne oczekwania: Expect.Once Expect.Never Expect.AtLeastOnce Expect.AtLeast(liczba wystąpień) Expect.AtMost(liczba wystąpień) Expect.Exactly(liczba wystąpień) Expect.Between(liczba wystąpień, liczba wystąpień) 38 19
Pokrycie kodu (ang. Code Coverage) Pokazuje, która część aplikacji została wykonania Pokazuje, która część kodu nie jest pokryta testami 39 Test Driven Development NAJPIERW NAPISZ TESTY, A NASTĘPNIE TWÓRZ KOD! Osiąga się w ten sposób dwa cele: wymusza się przemyślenie problemu przed stworzeniem kodu (bardziej na poziomie specyfikacji niŝ walidacji), zwiększa się poprawność tworzonego kodu. 40 20
Schemat działania TDD Krok pierwszy: Przemyśl problem Przemyśl jak to testować Napisz prosty test z dobrym interfejsem Krok drugi: Napisz tylko tyle kodu, by uruchomić test Obserwuj, dlaczego test nie przeszedł Krok trzeci: Napisz tylko tyle kodu, by test przeszedł Uruchom ponownie test, sprawdź czy napisany moduł przechodzi test (a takŝe wszystkie poprzednio napisane testy) Krok czwarty: Usuń wszelkie powtórzenia, zwiększ czytelność kodu Ponownie wykonaj testy Jeśli działa, to zapisz 41 Nieoczywiste efekty działań Test-Driven Development Tworząc testy mniej czasu poświęcane jest na usuwanie błędów (oraz debugowanie), programy są szybciej tworzone. Tworząc takie testy nie potrzebujemy tak długiego czasu na cykle testowe na koniec projektu. Testowanie przed kodowaniem jest duŝo bardziej interesujące niŝ testowanie gotowego kodu. 42 21
Referencje http://www.automatedqa.com/products/testcomplete/ http://www-306.ibm.com/software/rational/ www.mercury.com/ www.junit.org www.vbunit.org www.cppunit.sourceforge.net www.nunit.org 43 Pytania? 44 22
Zadanie 45 23