Debug School

rakesh kumar
rakesh kumar

Posted on

Unit Testing vs Functional Testing vs UI Testing: What Is the Difference

Unit Testing
Unit testing checks one small part of the system
Example: Checking whether HolidayLandmark calculates the correct booking price for three travellers.

Functional testing
Functional testing checks whether a complete feature works correctly.
Example: Checking whether a customer can select a trip, enter traveller details and successfully create a booking.

UI testing
UI testing checks what the user sees and uses on the website.
Example: Checking whether the Book Now button is visible, clickable and shows a success message after booking.

Unit Testing

def calculate_total(price_per_person, travellers):
    return price_per_person * travellers

def test_calculate_total():
    assert calculate_total(5000, 3) == 15000
Enter fullscreen mode Exit fullscreen mode

It does not check the database, API or booking page—only this function.

# tests/test_units.py
import pytest
from datetime import date


# 1. Calculate booking price
def calculate_total(price, travellers):
    return price * travellers

def test_calculate_total():
    assert calculate_total(5000, 3) == 15000


# 2. Apply discount
def apply_discount(total, percentage):
    return total - (total * percentage / 100)

def test_apply_discount():
    assert apply_discount(10000, 10) == 9000


# 3. Calculate tax
def calculate_tax(amount, tax_rate):
    return amount * tax_rate / 100

def test_calculate_tax():
    assert calculate_tax(10000, 18) == 1800


# 4. Validate number of travellers
def validate_travellers(travellers):
    return 1 <= travellers <= 20

def test_validate_travellers():
    assert validate_travellers(4) is True
    assert validate_travellers(0) is False


# 5. Check trip availability
def is_trip_available(available_seats, requested_seats):
    return available_seats >= requested_seats

def test_trip_availability():
    assert is_trip_available(10, 4) is True
    assert is_trip_available(2, 4) is False


# 6. Validate travel dates
def valid_dates(start_date, end_date):
    return end_date >= start_date

def test_valid_dates():
    assert valid_dates(date(2026, 10, 10), date(2026, 10, 15)) is True


# 7. Create booking reference
def create_booking_reference(booking_id):
    return f"HL-{booking_id:06d}"

def test_booking_reference():
    assert create_booking_reference(25) == "HL-000025"


# 8. Calculate average trip rating
def average_rating(ratings):
    return round(sum(ratings) / len(ratings), 1) if ratings else 0

def test_average_rating():
    assert average_rating([4, 5, 5, 4]) == 4.5


# 9. Validate rating range
def valid_rating(rating):
    return 1 <= rating <= 5

def test_valid_rating():
    assert valid_rating(5) is True
    assert valid_rating(6) is False


# 10. Calculate cancellation refund
def calculate_refund(amount, cancellation_charge):
    return amount - cancellation_charge

def test_calculate_refund():
    assert calculate_refund(15000, 2000) == 13000
Enter fullscreen mode Exit fullscreen mode

Functional testing

Functional testing checks whether the complete booking feature works according to the requirement.

def test_create_booking(client):
    response = client.post("/bookings", json={
        "trip_id": 10,
        "travellers": 3
    })

    assert response.status_code == 201
    assert response.json()["total_price"] == 15000
    assert response.json()["status"] == "pending"
Enter fullscreen mode Exit fullscreen mode

This test checks that the API creates a booking, calculates the price and returns the correct result.

tests/test_functional.py

Assume client is a configured FastAPI TestClient.


# 1. Create a trip
def test_create_trip(client):
    response = client.post("/trips", json={
        "name": "Goa Beach Holiday",
        "price": 5000,
        "available_seats": 20
    })

    assert response.status_code == 201
    assert response.json()["name"] == "Goa Beach Holiday"


# 2. Get trip details
def test_get_trip(client, created_trip):
    response = client.get(f"/trips/{created_trip['id']}")

    assert response.status_code == 200
    assert response.json()["id"] == created_trip["id"]


# 3. List all trips
def test_list_trips(client):
    response = client.get("/trips")

    assert response.status_code == 200
    assert isinstance(response.json(), list)


# 4. Filter trips by destination
def test_filter_trips(client):
    response = client.get("/trips?destination=Goa")

    assert response.status_code == 200
    assert all(trip["destination"] == "Goa" for trip in response.json())


# 5. Create a booking
def test_create_booking(client):
    response = client.post("/bookings", json={
        "trip_id": 10,
        "travellers": 3
    })

    assert response.status_code == 201
    assert response.json()["status"] == "pending"


# 6. Reject booking when seats are unavailable
def test_booking_without_seats(client):
    response = client.post("/bookings", json={
        "trip_id": 10,
        "travellers": 100
    })

    assert response.status_code == 400
    assert response.json()["detail"] == "Not enough seats"


# 7. Cancel a booking
def test_cancel_booking(client, created_booking):
    response = client.patch(
        f"/bookings/{created_booking['id']}/cancel"
    )

    assert response.status_code == 200
    assert response.json()["status"] == "cancelled"


# 8. Submit a trip review
def test_submit_review(client):
    response = client.post("/reviews", json={
        "trip_id": 10,
        "rating": 5,
        "comment": "Excellent experience"
    })

    assert response.status_code == 201
    assert response.json()["rating"] == 5


# 9. Reject an invalid review rating
def test_invalid_review_rating(client):
    response = client.post("/reviews", json={
        "trip_id": 10,
        "rating": 7,
        "comment": "Invalid rating"
    })

    assert response.status_code == 422


# 10. Prevent unauthorized trip creation
def test_unauthorized_trip_creation(client):
    response = client.post("/trips", json={
        "name": "Kerala Holiday",
        "price": 7000
    })

    assert response.status_code in [401, 403]
Enter fullscreen mode Exit fullscreen mode

UI testing

UI testing checks the actual HolidayLandmark page that the customer uses.

def test_booking_page(page):
    page.goto("https://holidaylandmark.com/trips/10")

    page.fill("#travellers", "3")
    page.click("#book-now")

    assert page.locator(".total-price").inner_text() == "₹15,000"
    assert page.locator(".success-message").is_visible()
Enter fullscreen mode Exit fullscreen mode

tests/test_ui.py

BASE_URL = "https://holidaylandmark.com"


# 1. Check homepage heading
def test_homepage_heading(page):
    page.goto(BASE_URL)

    heading = page.locator("h1")
    assert heading.is_visible()


# 2. Search for a destination
def test_search_destination(page):
    page.goto(BASE_URL)

    page.fill("#destination", "Goa")
    page.click("#search-button")

    assert "Goa" in page.locator(".trip-card").first.inner_text()


# 3. Filter trips by price
def test_price_filter(page):
    page.goto(f"{BASE_URL}/trips")

    page.fill("#maximum-price", "10000")
    page.click("#apply-filter")

    prices = page.locator(".trip-price").all_inner_texts()
    assert all(int(p.replace("₹", "").replace(",", "")) <= 10000 for p in prices)


# 4. Open trip details
def test_open_trip_details(page):
    page.goto(f"{BASE_URL}/trips")

    page.locator(".trip-card").first.click()

    assert page.locator(".trip-details").is_visible()


# 5. Complete the booking form
def test_booking_form(page):
    page.goto(f"{BASE_URL}/trips/10")

    page.fill("#travellers", "3")
    page.click("#book-now")

    assert page.locator(".booking-success").is_visible()


# 6. Show an error for zero travellers
def test_invalid_traveller_count(page):
    page.goto(f"{BASE_URL}/trips/10")

    page.fill("#travellers", "0")
    page.click("#book-now")

    assert page.locator(".traveller-error").is_visible()


# 7. User login
def test_user_login(page):
    page.goto(f"{BASE_URL}/login")

    page.fill("#email", "customer@example.com")
    page.fill("#password", "TestPassword123")
    page.click("#login-button")

    assert page.locator(".dashboard").is_visible()


# 8. Add a trip to favourites
def test_add_trip_to_favourites(page):
    page.goto(f"{BASE_URL}/trips/10")

    page.click("#favourite-button")

    assert page.locator("#favourite-button").get_attribute(
        "data-selected"
    ) == "true"


# 9. Submit a review
def test_submit_review_ui(page):
    page.goto(f"{BASE_URL}/bookings/25")

    page.click('[data-rating="5"]')
    page.fill("#review-comment", "Wonderful trip!")
    page.click("#submit-review")

    assert page.locator(".review-success").is_visible()


# 10. Check the mobile menu
def test_mobile_navigation(page):
    page.set_viewport_size({"width": 375, "height": 812})
    page.goto(BASE_URL)

    page.click("#mobile-menu-button")

    assert page.locator("#mobile-menu").is_visible()
Enter fullscreen mode Exit fullscreen mode

Top comments (0)