Rodzaje i poziomy testów oprogramowania. Dlaczego wykonujemy testy i czy są konieczne? Znaczenie testowania kodu. Ścieżki kariery testera.
Testowanie oprogramowania jest kluczowym etapem w procesie jego tworzenia, pozwalającym na wykrywanie błędów, poprawę jakości oraz zapewnienie zgodności z wymaganiami użytkowników. Istnieje wiele rodzajów testów, które są stosowane na różnych etapach cyklu życia oprogramowania.
Podstawowy podział testów na manualne i automatyczne
Testy oprogramowania można podzielić na dwa główne rodzaje: testy manualne oraz testy automatyczne. Zazwyczaj na początku kariery i wyboru sposobu nauki stajemy właśnie przed wyborem czy najpierw chcemy zostać testerem manualnym, a może od razu rzucamy się na głęboką wodę i przygotowujemy się do rekrutacji na testera automatycznego. Najistotniejszymi różnicami między tymi dwoma ścieżkami kariery, jest próg wejście (ilość posiadanej wiedzy) i związany z tym czas przygotowań do podjęcia pracy oraz zarobki początkowe (widełki płacy). Często wybieraną drogą rozwoju jest też połączenie tych dwóch specjalizacji: początek jako tester manualny i stopniowe pięcie się po stanowiskach w górę i późniejsze przekształcenie w testera automatycznego. Jeżeli chodzi o zawód tester oprogramowania i jego zarobki to zależą przede wszystkim od lat doświadczenia. Na praktykach czy stażu zarobki nie różnią się od innych branży - nieinformatycznych. Jednak w branży IT zarobki wzrastają znacznie szybciej, zwłaszcze jeżeli znamy języki obce. Język angielski w tym zawodzie jest niezbędny, chociażby do czytania dokumentacji technicznej. Często też pracujemy w zespołach międzynarodowych, gdzie angielski jest głównym językiem komunikacji.
Co to są testy manualne, jak wyglądają?
– wykonywane ręcznie przez testerów, polegają na interakcji z aplikacją, analizie wyników i raportowaniu błędów. Są stosowane głównie w testach eksploracyjnych i akceptacyjnych.
Co to są testy automatyczne - jak wykonujemy?
– testy automatyczne realizowane przy użyciu skryptów i narzędzi do testowania, pozwalają na szybkie i powtarzalne sprawdzanie funkcjonalności. Używane w testach jednostkowych, integracyjnych, regresyjnych i wydajnościowych.
Jakie są typy testów oprogramowania?
W zależności od obszaru działania oraz zastosowania wyróżniamy następujące typy testów oprogramowania:
Testy funkcjonalne
– jednostkowe, integracyjne, systemowe, akceptacyjne
Testy niefunkcjonalne
– sprawdzają np. wydajność, bezpieczeństwo, użyteczność, kompatybilność, możliwość przeniesienia aplikacji na inne środowisko
Testy strukturalne
– testy białoskrzynkowe, polegają na analizie wewnętrznej struktury kodu i jego logiki. W przeciwieństwie do testów funkcjonalnych, które sprawdzają zachowanie aplikacji z punktu widzenia użytkownika, testy strukturalne badają, jak kod został napisany i czy pokrywa wszystkie możliwe ścieżki wykonania. Rodzaje testów strukturalnych: Testy pokrycia kodu – sprawdzają, czy wszystkie instrukcje, gałęzie warunkowe i ścieżki w kodzie zostały przetestowane. Testy przepływu danych – analizują, jak dane są przekazywane i wykorzystywane w różnych częściach kodu. Testy mutacyjne – wprowadzają drobne modyfikacje w kodzie (mutacje) i sprawdzają, czy testy jednostkowe wykrywają te zmiany.
Testy regresywne (potwierdzające)
– mają na celu sprawdzenie, czy wprowadzenie nowych zmian w kodzie (np. dodanie nowych funkcji, poprawek błędów) nie spowodowało problemów w już działających częściach aplikacji. Testy regresywne są wykonywane regularnie, zwłaszcza po każdej aktualizacji systemu.
Jakie są poziomy testów oprogramowania?
Rodzaje testów oprogramowania:
Testy jednostkowe
– testy jednostkowe zostały opisane szczegółowo w dalszej części artykułu.
Testy integracyjne
– testy integracyjne zostały opisane szczegółowo w dalszej części artykułu.
Testy funkcjonalne
– sprawdzają czy poszczególne funkcje systemu działają zgodnie z określonymi wymaganiami.
Testy kompleksowe (systemowe)
– testy systemowe zostały opisane szczegółowo w dalszej części artykułu.
Testy akceptacyjne
– testy akceptacyjne zostały opisane szczegółowo w dalszej części artykułu.
Testy wydajności
– testy wydajności zostały opisane szczegółowo w dalszej części artykułu.
Testy smoke
– przeprowadzane na bardzo wczesnym etapie procesu testowania, zaraz po zbudowaniu nowej wersji aplikacji. Ich głównym celem jest upewnienie się, że aplikacja działa w sposób podstawowy i że nie występują poważne problemy, które uniemożliwiałyby dalsze testowanie.
Testy jednostkowe (Unit Tests)
Testy jednostkowe są najniższym poziomem testowania i obejmują sprawdzanie pojedynczych jednostek kodu, takich jak funkcje, metody lub klasy. Celem tych testów jest zapewnienie, że każdy element działa zgodnie z oczekiwaniami.
Zastosowanie i znaczenie testów jednotkowych:
- Wczesne wykrywanie błędów,
- Ułatwienie refaktoryzacji kodu,
- Automatyzacja i powtarzalność testów.
Przykład testu jednostkowego: Testowanie funkcji obliczającej sumę dwóch liczb, aby sprawdzić, czy zwraca poprawny wynik.
import unittest
def add(a, b):
return a + b
class TestMathOprarations(unittest.TestCase):
def test_add(self):
self.assertEgual(add(2, 3), 5):
if'_name_ == _main_':
unittest.main()
Testy integracyjne (Integration Tests)
Testy integracyjne sprawdzają poprawność współpracy między różnych modułami oprogramowania. Celem jest wykrycie problemów wynikających z ich wzajemnej interakcji.
Zastosowanie, znaczenie i przykład testów integracyjnych:
- Identyfikacja błędów komunikacji między modułami,
- Zapewnienie poprawnej wymiany danych,
- Sprawdzenie zgodności interfejsów API.
Przykład testu integracyjnego: Sprawdzenie, czy moduł logowania poprawnie przekazuje dane użytkownika do bazy danych.
import unittest
from autehentication import login
def mock.database():
return ('user1': 'password123')
class TestIntegration(unittest.TestCase):
def test_login(self):
db = mock_database()
self.assertTrue(login('user1', 'password123', db))
if '_name_ == _main_':
unittest.main()
Testy systemowe (System Tests)
Testy systemowe badają cały system jako jednolitą całość, testując jego funkcjonalność zgodnie ze specyfikacją.
Zastosowanie, znaczenie i przykład testów systemowych:
- Weryfikacja całościowej działalności oprogramowania,
- Symulacja rzeczywistych warunków pracy,
- Testowanie zgodności z wymaganiami.
Przykład testu systemowego: Testowanie aplikacji e-commerce, aby sprawdzić, czy proces zakupu działa poprawnie od dodania produktu do koszyka po finalizację transakcji.
import unittest
from ecommerce importadd_to_cart , checkout
class TestSystem(unittest.TestCase):
def test_checkout(self):
cart = []
add_to_cart(cart, 'Laptop')
self.assertTrue(checkout(cart))
if _name_ == '_main_':
unittest.main()
Testy regresyjne (Regression Tests)
Testy regresyjne polegają na ponownym testowaniu funkcjonalności oprogramowania po wprowadzeniu zmian, aby upewnić się, że nie wprowadziły one nowych błędów.
Zastosowanie, znaczenie i przykład testów regresyjnych:
- Zapobieganie ponownemu wystąpieniu błędów,
- Automatyzacja testów,
- Utrzymanie stabilności systemu.
Przykład testu regresyjnego: Po dodaniu nowej funkcji w aplikacji mobilnej sprawdzenie, czy dotychczasowa funkcjonalność logowania nadal działa poprawnie.
import unittest
from authentication import login
def test_regression():
assert login("user1", "password123") == True
Testy wydajnościowe (Performance Tests)
Testy wydajnościowe oceniają szybkość, stabilność i skalowalność systemu pod obciążeniem.
Zastosowanie, znaczenie i przykład testów regresyjnych:
- Identyfikacja wąskich gardeł w wydajności,
- Określenie maksymalnej wydajności systemu,
- Optymalizacja czasu odpowiedzi.
Przykład testu wydajnościowego: Testowanie serwera WWW poprzez symulację tysięcy użytkowników jednocześnie odwiedzających stronę.
import time
def performance_test():
start_time = time.time()
for _ in range(1000):
#symulacja zapytań do serwera
pass
end_time = time.time()
print("Czas wykonania:", end_time - start_time)
Testy akceptacyjne (Acceptance Tests)
Testy akceptacyjne są ostatnim etapem testowania, mającym na celu sprawdzenie, czy oprogramowanie spełnia wymagania biznesowe i jest gotowe do wdrożenia.
Zastosowanie, znaczenie i przykład testów regresyjnych:
- Potwierdzenie zgodności z oczekiwaniami użytkowników,
- Ocena gotowości do produkcji,
- Testowanie w rzeczywistym środowisku.
Przykład testu regresyjnego: Klient testuje aplikację CRM, aby sprawdzić, czy spełnia wszystkie jego wymagania biznesowe przed wdrożeniem.
import unittest
from crm import generate_report
class TestAcceptance(unittest.TestCase):
def test_generate_report(self):
self.assertEqual(generate_report(), "Raport wygenerowany poprawnie")
if _name_ == '_main_':
unittest.main()
Testy E2E (End-to-End)
Testy E2E sprawdzają cały przepływ działania aplikacji od początku do końca, uwzględniając interakcje między wszystkimi komponentami systemu. Testy E2E (End-to-End) zaliczamy do testów systemowych oraz testów akceptacyjnych, ponieważ sprawdzają pełny przepływ działania aplikacji w rzeczywistych warunkach użytkowania.
Zastosowanie, znaczenie i przykład testów regresyjnych:
- Testowanie rzeczywistych ścieżek użytkownika,
- Sprawdzenie integracji wszystkich warstw aplikacji (frontend, backend, bazy danych, API),
- Symulacja warunków produkcyjnych,
- Wykrywanie błędów interakcji między modułami.
Przykład testu regresyjnego: Testowanie rejestracji nowego użytkownika, logowania, dodania produktu do koszyka i dokonania płatności w jednej sesji testowej.
from selenium import webdriver
def test_e2e():
driver = webdriver.Chrome()
driver.get("https://shop.exaple.com")
driver.find_element("id", "register").click()
driver.find_element("id", "username").send_keys("testuser")
driver.find_element("id", "password").send_keys("testpass")
driver.find_element("id", "submit").click()
driver.quit()
W czym piszemy testy automatyczne? Jaki język programowania wybrać i jakie narzędzia?
Testy automatyczne można pisać w wielu językach programowania i przy użyciu różnych frameworków, w zależności od: technologii aplikacji (frontend/backend/web/mobile/etc.), rodzaju testów (unit/integration/system/e2e/performance/etc.), preferencji zespołu i ekosystemu projektu,
Przykłady narzędzi, freameworków i języków dla różnych typów testów automatycznych
Poniżej przedstawiamy przykłady języków oprogramowania wraz z odpowiednimi (najczęściej używanymi) narzędziami.
Testy jednostkowe (unit tests) przykłady freameworków stosowanych wraz z różnymi językami programowania
Język programowania - Python: narzędzia do testowania - unittest, pytest
Język programowania - Java: narzędzia do testowania - JUnit, TestNG
Język programowania - JavaScript/TypeScript: narzędzia do testowania - Jest, Mocha, Vitest
Język programowania - C#/.NET: narzędzia do testowania - xUnit, NUnit
Język programowania - Ruby: narzędzia do testowania - RSpec
Testy integracyjne / systemowe przykłady freameworków stosowanych wraz z różnymi językami programowania
Te same narzędzia co do testów jednostkowych, z dodatkami np. do mockowania baz danych, API itp.
Dodatkowo używamy: Spring Boot + JUnit/Testcontainers w języku Java, Django + pytest-django w języku Python.
Testy E2E (end-to-end) przykłady freameworków stosowanych wraz z różnymi językami programowania
Testy E2E najczęściej są stosowane w aplikacjach webowych, do testowania stron internetowych.
Język progrmowania - JavaScript/TypeScript: narzędzia do testowania - Cypress Playwright Selenium WebDriver (można pisać w różnych językach: Java, Python, JS, C#)
Język rogramowania - Python: narzędzia do testowania - Selenium, Playwright, Robot Framework
Język programowania - Java: narzędzia do testowania - Selenium, Selenide, TestNG
Język programowania - C#: narzędzia do testowania - Selenium, SpecFlow
Testy API przykłady freameworków stosowanych wraz z różnymi językami programowania
Postman – kolekcje + Newman do CI Python: requests + pytest, HTTPX + pytest JavaScript: supertest, axios + Jest Java: RestAssured
Testy wydajnościowe przykłady freameworków stosowanych wraz z różnymi językami programowania
JMeter Gatling (Scala/Java) Locust w języku Python, k6 w języku JavaScript
Testy mobilne przykłady freameworków stosowanych wraz z różnymi językami programowania
Appium (Android/iOS – multi-language)
Detox (React Native – JavaScript)
Espresso (Android – Java/Kotlin)
XCUITest (iOS – Swift)
Podsumowanie testów
Testowanie oprogramowania jest kluczowym elementem zapewnienia jakości i niezawodności systemów informatycznych. Każdy z wymienionych rodzajów testów odgrywa ważną rolę w procesie tworzenia oprogramowania, przyczyniając się do minimalizacji ryzyka wystąpienia błędów oraz poprawy ogólnej wydajności i stabilności systemu. Dzięki odpowiednio zaplanowanemu i przeprowadzonemu testowaniu możliwe jest dostarczenie produktów wysokiej jakości, spełniających oczekiwania użytkowników i biznesu. Życzymy samych sukcesów w nauce i w zawodowym rozwoju!
#pracaTestera #książka #elektronika
Przykłady:
Autor: Patrycja Mamrzeczy.pl