EP and BVA for Dates, Strings, Enumerations and File Uploads

Most EP and BVA examples use numeric fields because numbers have obvious boundaries. But real applications are full of non-numeric inputs โ€” dates, strings, dropdown selections, file uploads, and enumeration types. Each of these data types has its own partition patterns and boundary characteristics. Knowing how to apply EP and BVA to non-numeric inputs is what separates a tester who can only handle age fields from one who can design tests for any input type in any application.

EP and BVA Beyond Numbers โ€” Dates, Strings, Enums and Files

Every data type has equivalence partitions and boundaries. The trick is recognising what constitutes a “boundary” for each type.

# EP and BVA for non-numeric data types

# โ”€โ”€ DATES โ”€โ”€
# Requirement: Booking date must be between tomorrow and 365 days from today
date_partitions = {
    "EP1": {"range": "Past dates",                "valid": False, "example": "2025-01-01"},
    "EP2": {"range": "Today",                     "valid": False, "example": "today"},
    "EP3": {"range": "Tomorrow to today+365",     "valid": True,  "example": "today+30"},
    "EP4": {"range": "Beyond 365 days",           "valid": False, "example": "today+400"},
    "EP5": {"range": "Invalid format",            "valid": False, "example": "31/13/2026"},
    "EP6": {"range": "Leap day (Feb 29)",         "valid": "Depends", "example": "2028-02-29"},
}
date_boundaries = [
    "Yesterday (invalid) โ†’ Today (invalid) โ†’ Tomorrow (first valid day)",
    "Day 364 (valid) โ†’ Day 365 (valid) โ†’ Day 366 (invalid)",
    "Month boundaries: Jan 31 โ†’ Feb 1, Feb 28/29 โ†’ Mar 1",
    "Year boundary: Dec 31 โ†’ Jan 1 (year rollover)",
]

# โ”€โ”€ STRINGS โ”€โ”€
# Requirement: Username 3-20 alphanumeric characters, starting with a letter
string_partitions = {
    "EP1": {"range": "Length < 3",           "valid": False, "example": "ab"},
    "EP2": {"range": "Length 3-20, valid",   "valid": True,  "example": "alice123"},
    "EP3": {"range": "Length > 20",          "valid": False, "example": "a" * 21},
    "EP4": {"range": "Starts with number",  "valid": False, "example": "1alice"},
    "EP5": {"range": "Contains spaces",     "valid": False, "example": "alice bob"},
    "EP6": {"range": "Special characters",  "valid": False, "example": "alice@!"},
    "EP7": {"range": "Unicode / emoji",     "valid": False, "example": "alice\U0001f600"},
    "EP8": {"range": "Empty string",        "valid": False, "example": ""},
}
string_boundaries = [
    "Length: 2 chars (invalid) โ†’ 3 chars (valid) โ†’ 4 chars (valid)",
    "Length: 19 chars (valid) โ†’ 20 chars (valid) โ†’ 21 chars (invalid)",
    "Character: 'z' (last letter, valid) โ†’ '0' (first digit, valid) โ†’ '!' (invalid)",
    "First char: 'a' (letter, valid) โ†’ '1' (digit, starts with number, invalid)",
]

# โ”€โ”€ ENUMERATIONS / DROPDOWNS โ”€โ”€
# Requirement: Country selection from a list of 195 countries
enum_partitions = {
    "EP1": {"range": "Valid selection",      "valid": True,  "example": "United States"},
    "EP2": {"range": "No selection (empty)", "valid": False, "example": "(none)"},
    "EP3": {"range": "Injected value",       "valid": False, "example": "XSS