How to Write Test Cases for Filters And Sorting (With Examples)

How to Write Test Cases for Filters And Sorting (With Examples)

February 08, 2026 · 13 min read · How-To Guides

How to Write Test Cases for Filters And Sorting (With Examples)

Understanding Filters and Sorting in Applications

Filters and sorting are two of the most common interaction patterns in modern software. Users rely on them to narrow large data sets, locate specific records, and impose a meaningful order on results. Because these features touch data retrieval, UI state, and often backend services, defects in filtering or sorting can cascade into missed business opportunities, compliance issues, or poor user experience.

A filter typically presents a set of criteria—checkboxes, dropdowns, date pickers, free‑text search—that the user can enable or disable. When a criterion changes, the application must recompute the visible subset and reflect the change instantly (or after a short debounce). Sorting, on the other hand, lets the user choose one or more columns and a direction (ascending/descending) to reorder the same subset.

From a testing perspective, the challenge is twofold:

  1. Functional correctness – Does the output match the logical expression of the selected filters and the sort order?
  2. Performance and stability – Does the operation remain responsive under realistic data volumes, and does it handle malformed input without crashing or hanging?

The following sections break down how to translate these concerns into concrete, high‑signal test cases that can be executed manually, automated with scripts, or reinforced by autonomous exploration tools.

Anatomy of a Test Case for Filters and Sorting

A well‑structured test case contains six essential elements that make it reproducible, traceable, and easy to maintain.

ElementDescriptionExample for a filter test
IDUnique identifier (e.g., FT-001)FT-001
TitleShort, readable summary“Verify that selecting ‘Active’ status shows only active users”
PreconditionsState that must exist before execution“User is logged in; the user list page displays 150 records with mixed statuses”
StepsOrdered actions the tester performs1. Click the Status filter dropdown.
2. Check the ‘Active’ checkbox.
3. Click Apply.
Expected ResultObservable outcome that determines pass/fail“Only users whose status = Active are displayed; count matches backend query.”
Postconditions (optional)System state after test, useful for chaining“Filter panel shows ‘Active’ selected; no error messages.”

When writing test cases, keep each step atomic and avoid bundling multiple assertions into a single step. This makes failure diagnosis straightforward and enables parallel execution in automated suites.

Positive Test Cases

Positive tests validate that the feature works as intended under normal conditions. They form the baseline confidence that the implementation satisfies the functional requirement.

#### FT‑001 – Single‑Value Filter

  1. Open the Category filter.
  2. Select “Electronics”.
  3. Press Apply.

#### FT‑002 – Multi‑Value Filter (AND Logic)

  1. Select Category → Electronics.
  2. Select Price Range → $100‑$500.
  3. Apply.

#### FT‑003 – Multi‑Value Filter (OR Logic)

  1. Enable “Show tickets with Priority = High OR Status = Closed”.
  2. Apply.

#### FT‑004 – Text Search Filter

  1. Enter “Sm” in the search box.
  2. Press Enter.

#### FT‑005 – Date Range Filter

  1. Set From date to 2023‑06‑01.
  2. Set To date to 2023‑08‑31.
  3. Apply.

#### ST‑001 – Single‑Column Sort Ascending

  1. Click the Price column header once.

#### ST‑002 – Single‑Column Sort Descending

  1. Click the Price column header twice (or click after ascending).

#### ST‑003 – Multi‑Column Sort (Primary + Secondary)

  1. Shift‑click Department header (ascending).
  2. Click Last Name header (ascending).

#### ST‑004 – Sort with Null Values

  1. Sort DueDate ascending.

#### ST‑005 – Sort Stability

  1. Sort by Priority ascending.

Negative Test Cases

Negative tests verify that the system behaves correctly when presented with invalid, unexpected, or malicious input. They guard against crashes, security bypasses, and confusing UI states.

#### FT‑N01 – Empty Filter Selection

  1. Click Apply without selecting any option.

#### FT‑N02 – Conflicting Date Range

  1. Set From date to 2024‑01‑01.
  2. Set To date to 2023‑12‑31 (earlier than From).
  3. Apply.

#### FT‑N03 – Special Characters in Text Search

  1. Enter ' OR '1'='1.
  2. Submit.

#### FT‑N04 – Filter Value Beyond Data Type Limits

  1. Enter 999999 (outside realistic human age).
  2. Apply.

#### FT‑N05 – Rapid Toggle (Debounce Failure)

  1. Rapidly check and uncheck a checkbox 10 times within 200 ms.

#### ST‑N01 – Sorting on Non‑Comparable Column

  1. Click the column header to sort ascending.

#### ST‑N02 – Sort with Extremely Large Dataset

  1. Initiate a sort on any column.

#### ST‑N03 – Sort Direction Toggle Loop

  1. Click header three times quickly (asc → desc → asc).

Boundary and Edge Cases

Boundary tests focus on the limits of input domains, while edge cases explore uncommon combinations that often surface only in production.

#### FT‑B01 – Minimum Selection (One Item)

  1. Select the first item only.
  2. Apply.

#### FT‑B02 – Maximum Selection (All Items)

  1. Select all 50 items.
  2. Apply.

#### FT‑E01 – Cascading Dependent Filters

  1. Choose Country = Japan.
  2. Observe State list updates to show only Japanese prefectures.
  3. Select State = Tokyo.
  4. Observe City list updates accordingly.

#### FT‑E02 – Reset After Filter

  1. Click Clear/Reset button.

#### FT‑E03 – Persistent Filter Across Navigation

  1. Apply Category = Electronics.
  2. Click a product to open its detail page.
  3. Press Back to return to the list.

#### ST‑B01 – Sort on Empty Column

#### ST‑E01 – Locale‑Specific Sorting

  1. Sort ascending with locale set to fr-FR.

#### ST‑E02 – Reverse Sort After Pagination

  1. Navigate to page 3.
  2. Apply descending sort on a column.

Test Data Strategies

Reliable filter and sort testing hinges on realistic, controllable data. The following approaches reduce flakiness and increase coverage.

#### Synthetic Data Generation

Use scripts or libraries (e.g., faker, Mockaroo) to create datasets with known distributions:


from faker import Faker
fake = Faker()

def generate_users(n=1000):
    return [
        {
            "id": i,
            "name": fake.name(),
            "status": fake.random_element(["Active","Inactive","Suspended"]),
            "age": fake.random_int(min=18, max=80),
            "signup_date": fake.date_between(start_date="-5y", end_date="today")
        }
        for i in range(n)
    ]

Persist this set in a test database or load it into an in‑memory store (e.g., SQLite) before each test suite run.

#### Boundary Value Injection

For numeric filters, deliberately include min‑1, min, max, max+1 values to trigger boundary logic.

#### Null and Empty Injection

Insert NULL, empty strings, and whitespace‑only values into text and date fields to verify handling of missing data.

#### Data Seeding for Sorting

Create datasets where sorting outcomes are predictable:

#### Data Refresh Strategy

If the application caches results, ensure each test either bypasses the cache (via query parameters or API headers) or explicitly invalidates it before verification.

Prioritization and Traceability

Not all test cases carry equal risk. Use a simple risk‑based matrix to order execution and allocate automation effort.

PriorityCriteriaExample
P1 (Critical)Failure leads to data corruption, security breach, or major workflow blockage.FT‑N03 (SQL injection attempt)
P2 (High)Causes visible incorrect output or significant performance degradation.FT‑002 (multi‑value AND filter)
P3 (Medium)Affects edge‑case usability but does not break core flows.FT‑E01 (cascading dependent filters)
P4 (Low)Cosmetic or rare scenarios; low impact if missed.ST‑E02 (reverse sort after pagination)

Link each test case ID to a requirement artifact (e.g., user story, specification clause) in a traceability matrix:

Test IDRequirement IDRequirement Description
FT‑001REQ‑FIL‑01User can filter items by a single category.
FT‑N03REQ‑SEC‑02Input must be sanitized to prevent injection.
ST‑003REQ‑SRT‑04Multi‑column sort preserves grouping order.
ST‑N02REQ‑PERF‑01Sorting on 1M rows completes within 2 s.

Having this traceability enables impact analysis when requirements change: simply locate affected test IDs and re‑execute or update them.

Manual vs Automated Execution

#### Manual Testing

Manual exploratory testing remains valuable for discovering UX friction, unexpected interaction patterns, and visual glitches. A tester can:

A concise manual test charter for filters/sorting might look like:


Charter: Verify filter and sort behavior on the Order History page.
- Start with default view (no filters, ascending date).
- Apply each filter singly and in combination; note result count.
- Toggle sort direction on each sortable column; confirm arrow and order.
- Attempt invalid inputs (e.g., end date before start date); confirm error messages.
- Navigate away and back; ensure filter state persists.

#### Automated Testing

Automation provides repeatability and scalability. Choose the layer that matches the risk:

Below is a Playwright snippet that verifies a multi‑value filter and a sort:


// test/filter-sort.spec.js
const { test, expect } = require('@playwright/test');

test.describe('Product listing filters and sort', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('https://example.com/products');
    // wait for initial load
    await page.waitForSelector('.product-item');
  });

  test('FT-002: AND filter Electronics + Price $100‑$500', async ({ page }) => {
    await page.locator('#category-filter').selectOption('Electronics');
    await page.locator('#price-min').fill('100');
    await page.locator('#price-max').fill('500');
    await page.locator('#apply-btn').click();

    // ensure all shown items match criteria
    const items = await page.$$eval('.product-item', els =>
      els.map(el => ({
        category: el.getAttribute('data-category'),
        price: parseFloat(el.getAttribute('data-price'))
      }))
    );
    expect(items.every(i => i.category === 'Electronics')).toBeTruthy();
    expect(items.every(i => i.price >= 100 && i.price <= 500)).toBeTruthy();
  });

  test('ST-003: Multi‑column sort Department then Last Name', async ({ page }) => {
    await page.locator('#dept-header').click();   // asc Dept
    await page.locator('#lname-header').click();  // asc LastName

    const rows = await page.$$eval('tbody tr', rows =>
      rows.map(r => ({
        dept: r.cells[0].innerText.trim(),
        lname: r.cells[1].innerText.trim()
      }))
    );

    // verify grouping
    let prevDept = '';
    for (const r of rows) {
      expect(r.dept).toBeGreaterThanOrEqual(prevDept);
      if (r.dept === prevDept) {
        // within same dept, lname must be non‑decreasing
        expect(r.lname).toBeGreaterThanOrEqual(prevLname);
      }
      prevDept = r.dept;
      prevLname = r.lname;
    }
  });
});

Key points in the script:

#### Combining Manual and Automated with Autonomous Exploration

Autonomous QA platforms (like SUSA) can supplement scripted tests by continuously exercising the application with varied personas. For filters and sorting, an autonomous agent will:

  1. Generate random filter combinations (including impossible ones like selecting mutually exclusive categories).
  2. Vary interaction speed to stress debounce and state‑update logic.
  3. Simulate personas: an “impatient” user may rapidly toggle filters; an “elderly” user may use keyboard navigation exclusively; an “adversarial” user may attempt to inject scripts into search boxes.
  4. Detect regressions: if a new build breaks the sort stability for duplicate keys, the agent will flag a deviation from the baseline behavior captured in earlier runs.

The output from such a run includes a coverage map showing which filter/sort permutations were exercised, which crashed, and which produced unexpected UI states. Teams can then prioritize manual review or add targeted automated cases for the gaps identified.

Checklist for Filter and Sort Testing

Use this concise checklist before signing off a feature or before a release gate.

✅ ItemDescription
Requirement CoverageEvery filter/sort requirement has at least one positive test case.
Negative & SecurityAll identified invalid inputs (empty, out‑of‑range, special chars, injection attempts) have a negative test.
Boundary ValuesMin, max, min‑1, max+1 for numeric; earliest/latest date; first/last list item tested.
Edge CasesCascading dependencies, reset behavior, persistence across navigation, empty/null columns, locale‑specific sorting.
PerformanceSorting/filtering completes within SLA on realistic data volume (e.g., 100k rows).
StabilityNo JavaScript errors, console warnings, or crash logs during rapid interaction.
AccessibilityAll filter/sort controls are keyboard operable, have appropriate ARIA labels, and convey state changes to assistive tech.
State PersistenceFilter/sort selections survive page navigation, refresh, and session restore where specified.
Automation ReadinessEach test case can be mapped to an automated script (unit, API, or UI) with stable selectors.
Review & TraceabilityTest IDs linked to requirements; any change in spec triggers a review of affected tests.

Closing Takeaways

Writing effective test cases for filters and sorting is less about checking boxes and more about understanding how users manipulate data and where the system can falter. Start by decomposing the feature into its logical primitives—single‑value filters, multi‑value Boolean logic, text search, date ranges, and sortable columns—then enumerate the happy path, the error paths, and the limits of each primitive.

A well‑maintained test matrix, like the one presented above, gives you a reusable baseline that can be expanded as new filter types (e.g., tag‑based, range sliders) or sort options (custom comparators, locale‑aware collation) appear. Pair this matrix with risk‑based prioritization, traceability to requirements, and a blend of manual exploratory checks, automated scripts, and, where available, autonomous exploration to achieve continuous confidence.

When you treat filters and sorting as first‑class citizens in your test strategy, you catch the subtle bugs that only surface under realistic data loads or unusual user behavior—turning a potential production incident into a caught‑early, fixed‑before‑release win.

---

*Feel free to copy the tables, code snippets, and checklist into your test management tool or wiki. Adjust the data‑generation scripts to match your domain, and let the autonomous agent handle the combinatorial explosion while you focus on the high‑value, scenario‑specific cases.*

Test Your App Autonomously

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.

Try SUSA Free