Skip to content

Commit 62a6bbd

Browse files
committed
junit post added
1 parent 888a3be commit 62a6bbd

File tree

7 files changed

+60
-8
lines changed

7 files changed

+60
-8
lines changed

_drafts/2018-12-31-proces.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ date: 2018-12-31
55
categories: ["Testowanie"]
66
image: testing/process
77
description: "Testowanie - proces"
8-
keywords: "testowanie, testing, testy, jednostkowe, integracyjne, systemowe, akceptacyjne, manualne, automatyczne, lokalne, integracyjne, unit test, ui test, błąd, usterka, junit, jmeter, espresso, roboelectric, android, programowanie, programming"
8+
keywords: "testowanie, testing, testy, jednostkowe, integracyjne, systemowe, akceptacyjne, manualne, automatyczne, lokalne, integracyjne, unit test, ui test, błąd, usterka, junit, jmeter, espresso, robolectric, android, programowanie, programming"
99
---
1010

1111
## Definicja
@@ -27,4 +27,4 @@ W celu wykrycia błędów w interfejsach oraz interakcjach pomiędzy integrowany
2727
Celem testów akceptacyjnych jest uzyskanie formalnego potwierdzenia wykonania aplikacji o ustalonej jakości zgodnie z ustalonymi założeniami i wymaganiami wg specyfikacji. Testy przeprowadzane są przez zespół odbiorców i twórców na środowisku produkcyjnym lub najbardziej zbliżonym do środowiska docelowego. Można wyróżnić etap testów `alfa` dokonywany przez wewnętrzny zespół testowy niezależny od zespołu twórców oraz testy `beta` wykonywane na zewnątrz firmy w różnorodnych środowiskach testowych. W przypadku tworzenia aplikacji przeznaczonych na sklep `Google Play` wydanie aplikacji w wersji beta przeznaczonej dla użytkowników zapisanych na `betatesty` może być sposobem realizacji testów akceptacyjnych. Wykorzystanie narzędzi automatycznie rejestrujących awarie aplikacji z urządzeń użytkowników np. `Firebase` pozwala poznać błędy i lokalizować usterki co ułatwia naprawę popełnionych błędów.
2828

2929
## Wyzwania
30-
Podstawowymi czynnościami procesu testowania aplikacji na platformę Android, które spoczywają na barkach programisty jest `debugowanie` oraz `pisanie testów automatycznych`. Niestety w odróżnieniu od innych środowisk przeprowadzenie testów jednostkowych w Android jest utrudnione ze względu na SDK i zależności sprzętowe. Wykorzystywane w środowisku deweloperskim klasy pochodzące z `Android SDK` we fragmentach kodu aplikacji są na dobrą sprawę zaślepką bez implementacji zachowania, które dopiero uruchomione na fizycznym urządzeniu czy emulatorze zyskują pełnie działania. Testy jednostkowe mogą być bez przeszkód wykonane na kodzie wolnym od zależności klas Android SDK co tyczy się przede wszystkim klas typu Utils i logiki. Co więcej testowaniu powinny podlegać komponenty Androida, których cykl życia jest tworzony i zarządzany przez system. Przeprowadzenie testów na klasach z Android SDK, a przede wszystkim komponentów rodzi problem braku instancji co nawet w przypadku stworzenia zaślepek za pomocą zewnętrznych bibliotek nie jest trywialne. Rozwiązaniem tego problemu może być wykorzystanie dedykowanych bibliotek np. `Roboelectric`, które dostarczają środowiska uruchomieniowego dla testów jednostkowych. Ze względu na fragmentację platformy oraz dokonywane zmiany w SDK należy mieć na uwadze również to, że aplikacja może w różny sposób zachowywać się na różnych telefonach. Warto zatem przeprowadzać także automatyczne testy UI oraz testy manualne właściwie dobierając przekrój zestawu urządzeń testowych.
30+
Podstawowymi czynnościami procesu testowania aplikacji na platformę Android, które spoczywają na barkach programisty jest `debugowanie` oraz `pisanie testów automatycznych`. Niestety w odróżnieniu od innych środowisk przeprowadzenie testów jednostkowych w Android jest utrudnione ze względu na SDK i zależności sprzętowe. Wykorzystywane w środowisku deweloperskim klasy pochodzące z `Android SDK` we fragmentach kodu aplikacji są na dobrą sprawę zaślepką bez implementacji zachowania, które dopiero uruchomione na fizycznym urządzeniu czy emulatorze zyskują pełnie działania. Testy jednostkowe mogą być bez przeszkód wykonane na kodzie wolnym od zależności klas Android SDK co tyczy się przede wszystkim klas typu Utils i logiki. Co więcej testowaniu powinny podlegać komponenty Androida, których cykl życia jest tworzony i zarządzany przez system. Przeprowadzenie testów na klasach z Android SDK, a przede wszystkim komponentów rodzi problem braku instancji co nawet w przypadku stworzenia zaślepek za pomocą zewnętrznych bibliotek nie jest trywialne. Rozwiązaniem tego problemu może być wykorzystanie dedykowanych bibliotek np. `Robolectric`, które dostarczają środowiska uruchomieniowego dla testów jednostkowych. Ze względu na fragmentację platformy oraz dokonywane zmiany w SDK należy mieć na uwadze również to, że aplikacja może w różny sposób zachowywać się na różnych telefonach. Warto zatem przeprowadzać także automatyczne testy UI oraz testy manualne właściwie dobierając przekrój zestawu urządzeń testowych.

_drafts/2019-01-07-testy_jednostkowe.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ date: 2019-01-07
55
categories: ["Testowanie"]
66
image: testing/unit_test
77
description: "Testy jednostkowe"
8-
keywords: "testowanie, testing, testy, jednostkowe, automatyczne, lokalne, integracyjne, zaślepka, atrapa, unit test, mock, stub, przypadki testowe, czarnoskrzynkowe, białoskrzynkowe, pokrycie kodu, pokrycie instrukcji, pokrycie gałęzi, pokrycie ścieżek, code coverage, statement coverage, path coverage, branch coverage, przypadki testowe, klasy równoważności, wartości brzegowe, tabele decyzyjne, przypadki użycia, junit, roboelectric, mockito, android, programowanie, programming"
8+
keywords: "testowanie, testing, testy, jednostkowe, automatyczne, lokalne, integracyjne, zaślepka, atrapa, unit test, mock, stub, przypadki testowe, czarnoskrzynkowe, białoskrzynkowe, pokrycie kodu, pokrycie instrukcji, pokrycie gałęzi, pokrycie ścieżek, code coverage, statement coverage, path coverage, branch coverage, przypadki testowe, klasy równoważności, wartości brzegowe, tabele decyzyjne, przypadki użycia, junit, robolectric, mockito, android, programowanie, programming"
99
---
1010

1111
## Definicja
1212
`Testy jednostkowe` (`unit test`) poddają weryfikacji sposób działania różnych elementów składowych kodu takich jak `metody`, `klasy` czy `moduły`. Testy powinny być pisane w sposób `niezależny`, tzn. testowana jednostka nie jest podatna na wpływy innych elementów, w przeciwnym razie wynik testu może być niewiarygodny. Testy jednostkowe należą do `testów automatycznych` za których tworzenie i wykonywanie powinien odpowiadać programista. Warto przeprowadzać je często i regularnie przy każdym nowym przyroście dzięki czemu na wczesnym etapie tworzenia oprogramowania możliwe jest wykrycie usterki. Pozwala to na przeciwdziałanie kumulowania się błędów (jeden błąd rodzi kolejne) co w rezultacie redukuje koszty w póżniejszych etapach cyklu życia aplikacji. Tworzenie testów jednostkowych polega przede wszystkim na pisaniu `asercji` czyli porównywanie uzyskanego wyniku z oczekiwanym. Do przeprowadzania testów jednostkowych można wykorzystać np. bibliotekę `jUnit`. Przeważnie jednostki testowe wymagają do poprawnego działania obiektów różnego typu. Aby przekazywane argumenty nie wpływały na wynik testu danej jednostki (niezależne testy) należy dostarczać tzw. `atrapę` obiektu czyli naiwną implementację zależności.
1313

1414
## Testy lokalne i instrumentalne
15-
Testy (nie tylko jednostkowe), które mogą zostać wykonane na wirtualnej maszynie deweloperskiej nazywane są `testami lokalnymi`. Przeprowadzenie jednostkowych testów lokalnych charakteryzuje się niskim kosztem oraz szybkością w związku z czym powinny stanowić przeważającą część testów. Natomiast testy, które wymagają uruchomienia na fizycznym urządzeniu lub emulatorze nazywane są `testami instrumentalnymi`. Wynika to z faktu, że pewne fragmenty kodu są zależne bibliotek `Android SDK` oraz cyklu życia komponentów, którymi zarządza system. Takie testy w stosunku do testów lokalnych są dosyć kosztowne i powolne. Przykładem biblioteki realizującej instrumentalne testy jednostkowe jest `Roboelectrict`.
15+
Testy (nie tylko jednostkowe), które mogą zostać wykonane na wirtualnej maszynie deweloperskiej nazywane są `testami lokalnymi`. Przeprowadzenie jednostkowych testów lokalnych charakteryzuje się niskim kosztem oraz szybkością w związku z czym powinny stanowić przeważającą część testów. Natomiast testy, które wymagają uruchomienia na fizycznym urządzeniu lub emulatorze nazywane są `testami instrumentalnymi`. Wynika to z faktu, że pewne fragmenty kodu są zależne bibliotek `Android SDK` oraz cyklu życia komponentów, którymi zarządza system. Takie testy w stosunku do testów lokalnych są dosyć kosztowne i powolne. Przykładem biblioteki realizującej instrumentalne testy jednostkowe jest `Robolectrict`.
1616

1717
## Atrapa i zaślepka
1818
`Zaślepka` (`stub`) jest minimalną implementacją zależnego modułu używaną podczas testów innego modułu. Ma za zadanie zastępować wywoływany moduł poprzez zwracanie w prosty sposób wyniku bez dokonywania obliczeń w taki sposób, aby wykonywany test zawsze przeszedł pozytywnie. `Atrapa` (`mock`) dostarcza natomiast naiwną implementację zależności, która umożliwia rejestrowanie interakcji z implementowanym interfejsem (np. ilość wywołań i parametry) i w przeciwieństwie do zaślepki bierze udział w procesie testowania. Atrapa jest determinowana w momencie działania programu i reprezentuje instancje oczekiwanego obiektu. Posługując się fachową nomenklaturą można wyróżnić jeszcze szerszy podział obiektów zastępczych jednakże ważniejsze od teoretycznego podziału jest właściwa implementacja. Biblioteka `Mockito` ułatwia tworzenie i zarządzanie naiwnymi implementacjami.
@@ -58,9 +58,9 @@ fun calculate(a: Boolean, b: Boolean, c: Boolean) {
5858
`Pokrycie instrukcji` (`statement coverage`) zwane również `pokryciem linii` obejmuje tylko rzeczywiste warunki, gdzie każda linia kodu jest analizowana. Sprawdza przepływ ścieżek oraz weryfikuje poprawność realizacji (czy robi to co jest oczekiwane). Nie weryfikuje natomiast fałszywych wyników, jest zależna od struktury kodu, pomija operatory logiczne i nie zgłasza warunku zakończenia pętli. Wynikiem pokrycia instrukcji jest iloczyn ilości linii kodu uruchomionych na skutek testów do wszystkich linii (z pominięciem instrukcji niewykonywalnych).
5959

6060
>Dla podanych argumentów pokrycie instrukcji wynosi:
61-
>- **a**=true, **b**=true, **c**=true -> **statement coverage**=7/11
62-
>- **a**=false, **b**=true, **c**=false -> **statement coverage**=8/11
63-
>- **a**=true, **b**=false, **c**=false -> **statement coverage**=9/11
61+
>- **a**=true, **b**=true, **c**=true -> **statement coverage**=6/7
62+
>- **a**=false, **b**=true, **c**=false -> **statement coverage**=5/7
63+
>- **a**=true, **b**=false, **c**=false -> **statement coverage**=6/7
6464
>
6565
>Aby uzyskać całkowite pokrycie instrukcji należy przygotować 2 testy jednostkowe.
6666

_drafts/2019-01-14-junit.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
layout: post
3+
title: "JUnit"
4+
date: 2019-01-14
5+
categories: ["Testowanie"]
6+
image: testing/junit
7+
description: "JUnit"
8+
keywords: "testowanie, testing, testy, jednostkowe, automatyczne, lokalne, zaślepka, atrapa, unit test, mock, stub, przypadki testowe, pokrycie kodu, code coverage, przypadki testowe, junit, roboelectric, mockito, android, programowanie, programming"
9+
---
10+
11+
## Integracja
12+
`Android Studio` ułatwia proces testowania dzięki integracji z bibliotekami wspomagającymi testowanie oraz dostarczeniu dedykowanych narzędzi. Dodając odpowiednie zależności `AndroidX` do projektu już za pomocą kilku kliknięć można wykorzystać możliwości takich bibliotek jaki: `JUnit`, `Mockito`, `Espresso`, `Robolectric` czy `UI Automator`. Lokalne testy jednostkowe uruchamiane na maszynie lokalnej `JVM` znajdują się w lokalizacji: `moduleName/src/test/java/` natomiast instrumentalne testy jednostkowe przeznaczone do uruchamiania na urządzeniu lub emulatorze znajdują się w: `moduleName/src/androidTest/java/`. W przypadku testów instrumentalnych przeznaczonych dla różnych wariantów budowania aplikacji ścieżka zmienia się na: `moduleName/src/androidTestBuildVariantName/java/`.
13+
14+
//TODO photo
15+
16+
## Tworzenie i uruchamianie
17+
`Testy jednostkowe` można tworzyć dodając klasy do odpowiednich folderów lub za pomocą skrótu `Ctrl+Shift+T` kierując kursor na klasę lub metodę. Uruchamianie i analiza następuje z poziomu narzędzia GUI lub konsoli w Android Studio, które umożliwia m.in. eksport wyników testów, przeglądanie statystyk oraz pokrycie kodu.
18+
19+
//TODO photo
20+
21+
## Motywacja
22+
Podstawą procesu testowania jest tworzenie i wykonywanie testów jednostkowych, które odpowiednio napisane w łatwy i wiarygodny sposób weryfikują poprawności logiki jednostki testowanej. Wykonywanie testów jednostkowych przy każdym przyroście ułatwia szybkie wyłapanie błędu. Należy jednak pamiętać o izolacji testowanej jednostki od pozostałych zależności. `JUnit` w Android jest wykorzystywany przede wszystkim do pisania `lokalnych testów` jednostkowych lub prostych `testów instrumentalnych` dla których można dostarczyć zależności (własne lub przy pomocy biblioteki np. Mockito). W pozostałych sytuacjach należy wykorzystać bibliotekę dostarczają zależności środowiska uruchomieniowego np. `Robolectric`. Tworzenie asercji może zostać usprawnione przez wykorzystanie `Hamcrest`. Alternatywą dla implementacji JUnit dla Android jest wykorzystanie biblioteki `Truth` we współpracy z asercjami Android.
23+
24+
## Dobre praktyki
25+
Tworząc metody testowe należy przede wszystkim pamiętać o wykluczeniu wszelkich zależności w taki sposób, aby na wynik testu testowanej jednostki nie miały wpływu inne zależności. Klasy testowe powinny znajdować się w pakiecie o tej samej nazwie co klasy implementacji, a nazwy klas testowych powinny być podobne do klas testowanych. Metody opisowe powinny być nazywane w sposób opisowy i jednoznaczny w nawiązaniu do celu testu nawet jeśli z tego powodu nazwa metody jest długa. W tym celu można posłużyć się konwencją `BDD: Given/When/Then`. Ponadto należy dążyć do minimalizacji asercji, czasu wykonywania testów oraz zwiększać pokrycie kodu. Testy powinny być krótkie, proste i ściśle dotyczyć jednej jednostki. Jeśli sytuacja tego wymaga należy wykorzystywać metody cyklu życia testów, aby zapewnić odpowiednią inicjalizację i czyszczenie środowiska.
26+
27+
## Klasa testowa
28+
Testy w JUnit (metody) zawierają się w `klasie testowej`, które z kolei mogą być częścią `zestawu klas testowych`. Aby klasa była klasą testową w JUnit4 musi zawierać deklarację przynajmniej jednej metody testowej oznaczonej adnotacją `@Test`. Podstawowym elementem testów są asercje sprawdzające wartość logiczną, równość wartości czy referencji.
29+
30+
//TODO klasa z jedna metoda i roznymi asercjami
31+
32+
## Cykl życia
33+
Klasy testowe poza metodami testowymi mogą składać się także z metod inicjalizacyjnych i końcowych. Metoda oznaczona adnotacją `@Before` wykonywana jest przed każdym testem i służy przygotowaniu środowiska testowego, natomiast z adnotacją `@After` po każdym teście co wykorzystywane jest do czyszczenia środowiska. W analogiczny sposób działają metody oznaczone jako `@BeforeClass` oraz `@AfterClass`, które wykonują się kolejno przed i po uruchomieniu wszystkich testów. Jeśli metoda testowa ma zostać wyłączona z testów należy użyć adnotacji `@Ignore`. Adnotacja `@Test` może zostać wzbogacona o maksymalny czas wykonania (`timeout`) lub oczekiwany typ wyjątku.
34+
35+
//TODO klasa z calym cyklem i ignore i test
36+
37+
## Parametry
38+
Klasa testowa może posiadać także jedną metodę generującą zestawy danych dla metod testowych. Klasa ta musi być oznaczona adnotacją `@RunWith(Parameterized.class)` natomiast metoda zwracająca kolekcje danych oraz pola przyjmujące wstrzyknięte wartości są oznaczone jako `@Parameter`. Pola mogą przyjmować wstrzykniętą wartość również za pomocą konstruktora.
39+
40+
//TODO przyklad z parametrami
41+
42+
## Zasady
43+
JUnit umożliwia dodawanie zachowania do każdego testu za pomocą adnotacji `@Rule` oraz tworzenie nowych zasad. Aby stworzyć własną zasadę należy w klasie zasady implementować interfejs `TestRule`.
44+
45+
//TODO przyklad z tworzeniem i uzyciem wlasnej zasady
46+
47+
`AndroidX Test` zawiera zestaw gotowych zasad dla JUnit, które zwiększają elastyczność, redukują powtarzający się kod oraz wspomagają testowanie komponentów Android. Wykorzystywane są przede wszystkim testach UI przy użyciu `Espresso`. `ActivityTestRule` dostarcza do klasy testowej żądanej Aktywności (`Activity`), która jest dostępna w całym cyklu życia klasy testowej, `ServiceTestRule` dostarcza Usługę (`Service`) natomiast `IntentsTestRule` dostarcza Intencję (`Intent`).
48+
49+
## Filtry
50+
`AndroidJUnitRunner` umożliwia stosowanie adnotacji w celach czysto informacyjnych. Adnotacja `@RequiresDevice` mówi, że test powinien zostać przeprowadzony tylko na urządzeniu fizycznym, `@SdkSupress` określa minimalne API natomiast `@SmallTest`, `@MediumTest` i `@LargeTest` mówią o wielkości testu co przekłada się na czas jego wykonania.
51+
52+
//TODO example

_posts/kotlin/2018-12-10-klasy.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ var listener = OnClickListener()
305305
button.setOnClickListener(listener)
306306

307307
//object expression passed with modify action
308-
button.setOnClickListener(object : OnClickListener() {
308+
button.setOnClickListener(object: OnClickListener() {
309309
override fun onClick() { print("click modified") }
310310
})
311311
{% endhighlight %}

assets/img/posts/testing/junit.jpg

770 KB
Loading
21.8 KB
Loading
68.6 KB
Loading

0 commit comments

Comments
 (0)