View all services
Talk to QA Advisor
Browse the Knowledge Hub56 resources
/Test Cases/Database and data integrity test cases

Test cases

Data integrity test cases, because a constraint in code is not a constraint

Twenty eight cases covering uniqueness under concurrency, orphaned rows and cascade rules, transaction rollback, lost updates and counter races, negative balances, deadlock retries, numeric and timestamp types, migration and backfill safety, soft delete leaks, tenant scoping, replica lag and verified restores.

28cases/8coverage types/9concurrency cases/FreeCSV download

All 28 test cases, ready to copy

Free to use and adapt, no sign-up. Download as CSV or Markdown, or copy it straight into your own tooling.

Last updated

28 worked examples

DB-01

Enforce uniqueness at the database rather than in code

TypeBoundaryPriorityHigh
Test data
Two concurrent inserts of the same logically unique value
Expected result
One succeeds and one fails on a constraint. A check followed by an insert in application code lets both through under concurrency.
DB-02

Apply the intended case and whitespace rule to uniqueness

TypeNegativePriorityHigh
Test data
The same email differing only in case, and one with trailing whitespace
Expected result
Treated as duplicates if that is the intent, enforced by the constraint definition rather than by a normalisation step the application might skip.
DB-03

Prevent orphaned rows through foreign keys

TypeNegativePriorityHigh
Test data
Insert a child row referencing a missing parent, then delete a parent with children present
Expected result
Both refused or handled by a declared cascade rule. Referential integrity maintained only by application code degrades with every new code path.
DB-04

Verify the delete behaviour on every relationship

TypeStatePriorityHigh
Test data
Delete a parent under each configured rule: cascade, restrict and set null
Expected result
Each behaves as documented, and no cascade deletes further than intended, which is how an unrelated audit history disappears with one record.
DB-05

Reject data that violates a business constraint

TypeNegativePriorityHigh
Test data
A negative quantity, an end date before a start date, and a status value outside the permitted set
Expected result
Refused by a database constraint as well as by validation, so a direct write, a migration or an admin tool cannot introduce invalid rows.
DB-06

Roll back completely when a transaction fails

TypeStatePriorityHigh
Test data
A multi table write forced to fail on the last statement
Expected result
No partial state remains. A half applied change is worse than a clean failure because nothing reports it and the data looks plausible.
DB-07

Keep a write and its side effects consistent

TypeStatePriorityHigh
Test data
A commit followed by a failing message publish or cache invalidation
Expected result
Either both happen or the inconsistency is detected and repaired, rather than a committed row that no downstream consumer ever hears about.
DB-08

Prevent lost updates on concurrent writes

TypeBoundaryPriorityHigh
Test data
Two users editing different fields of the same record and saving simultaneously
Expected result
Both changes survive, or the later write is refused with a conflict. A read modify write cycle silently discards the first change.
DB-09

Increment a counter correctly under concurrency

TypeBoundaryPriorityHigh
Test data
One hundred concurrent increments of the same counter
Expected result
Final value is exactly one hundred higher. A value read into the application and written back loses increments in proportion to concurrency.
DB-10

Prevent a balance or stock level going negative

TypeBoundaryPriorityHigh
Test data
Concurrent decrements that individually fit within the available amount but together exceed it
Expected result
One succeeds and one is refused, enforced by a conditional update or a constraint rather than by an application check.
DB-11

Handle a deadlock without losing the request

TypeStatePriorityHigh
Test data
Two transactions acquiring the same rows in opposite order
Expected result
One is chosen as the victim, the failure is retried safely, and the retry does not apply the same change twice.
DB-12

Behave correctly under the configured isolation level

TypeBoundaryPriorityHigh
Test data
A read repeated inside one transaction while another commits a change to those rows
Expected result
Behaviour matches the documented isolation level, and any logic that assumes a stronger guarantee than is configured is identified.
DB-13

Store numeric values in an appropriate type

TypeNegativePriorityHigh
Test data
A monetary total summed across many rows, and a value at the maximum for its column type
Expected result
Money is stored as an exact decimal or integer minor units rather than a floating point type, and an overflow is refused rather than silently wrapping.
DB-14

Store timestamps with an unambiguous timezone

TypeBoundaryPriorityHigh
Test data
A record written from two server timezones, and one at a daylight saving transition
Expected result
Timestamps are stored with an offset or in a single documented timezone, and a calendar date is stored as a date rather than converted through an instant.
DB-15

Preserve character encoding and collation

TypeNegativePriorityHigh
Test data
Accented characters, emoji, right to left text and a value at the maximum column length
Expected result
Stored and returned byte identical with no truncation or substitution, and sorting follows the intended collation rather than a byte order.
DB-16

Handle null distinctly from empty and zero

TypeBoundaryPriorityHigh
Test data
A null, an empty string and a zero in the same column, then filter, sort and aggregate over them
Expected result
Each is distinguishable, aggregates treat null as documented, and a filter for not equal to a value does not silently exclude null rows.
DB-17

Run a migration forwards without data loss

TypeStatePriorityHigh
Test data
A migration adding a column, narrowing a type and renaming a field, against production scale data
Expected result
Data is preserved and transformed correctly, and rows that cannot be transformed are reported rather than dropped or silently defaulted.
DB-18

Roll a migration back safely

TypeStatePriorityHigh
Test data
Apply a migration, write new data, then roll back
Expected result
Rollback is possible or is documented as irreversible before deployment, and the consequences for data written in the meantime are stated.
DB-19

Keep a migration safe against a running application

TypeBoundaryPriorityHigh
Test data
A migration executed while the previous application version is still serving traffic
Expected result
Old and new code both work against the intermediate schema, and the migration does not hold a lock long enough to cause an outage.
DB-20

Make a data backfill safely rerunnable

TypeStatePriorityHigh
Test data
Interrupt a backfill partway, then run it again
Expected result
Rerunning completes the remainder without reprocessing or double applying rows already handled, and progress is recorded durably.
DB-21

Enforce soft delete consistently

TypeSecurityPriorityHigh
Test data
A soft deleted record requested through search, a report, an export and a direct identifier lookup
Expected result
Excluded from all four and from any uniqueness check that should ignore it, since a filter applied in one query and forgotten in another resurrects the record.
DB-22

Scope every query by tenant

TypeSecurityPriorityHigh
Test data
Requests for records belonging to another tenant through the interface, a report and an export
Expected result
Refused everywhere, enforced by a mechanism that cannot be forgotten in a new query rather than by remembering to add a condition each time.
DB-23

Restore from backup within the stated objectives

TypeStatePriorityHigh
Test data
A restore into a clean environment, timed and verified
Expected result
Restore completes within the recovery time objective with data loss inside the recovery point objective, verified by an actual restore rather than by the backup job reporting success.
DB-24

Recover a single record or table without a full restore

TypeStatePriorityMedium
Test data
An accidental delete or update of one table
Expected result
A documented path exists to recover that data alone, since a full restore to fix one table means discarding every change since the backup.
DB-25

Read consistently from a replica

TypeBoundaryPriorityHigh
Test data
A write followed immediately by a read routed to a replica under replication lag
Expected result
The user sees their own write, through read after write consistency or by routing that read to the primary rather than showing stale data.
DB-26

Verify indexes support the real query patterns

TypePerformancePriorityHigh
Test data
Execution plans for the most frequent and slowest queries against production volume data
Expected result
No unexpected full scan on a large table, and no unused index adding write cost, evaluated at real volume rather than on a seeded sample.
DB-27

Mask or exclude personal data in non production copies

TypeSecurityPriorityHigh
Test data
A refreshed test database taken from production
Expected result
Personal data is masked or synthetic while preserving referential integrity and realistic distribution, and no unmasked copy remains reachable.
DB-28

Reconcile aggregates against the underlying rows

TypeStatePriorityHigh
Test data
A stored total, a cached count and a reporting figure compared against a direct calculation
Expected result
All agree exactly. A denormalised total maintained by application code drifts, and nothing detects it until somebody adds the rows up by hand.

What goes in each field

ID

Required

Stable identifier, prefixed by module.

Test case

Required

What is being verified, in one line.

Type

Functional, negative, boundary, security, state, performance, accessibility or compatibility. Use it to check coverage is spread rather than clustered on the happy path.

Priority

Risk based, weighted by whether the damage is silent and permanent. Anything that allows duplicate or orphaned rows, loses a committed write, or corrupts a numeric total is High.

Test data

The specific values, including the invalid and boundary ones.

Expected result

Required

The precise observable outcome, including message text where the wording itself is the requirement.

How To Use This

Insert the same row twice at once

Data defects are the quietest failures in software: nothing errors, the rows look plausible, and the damage is permanent. These four conditions expose them.

Fire two identical inserts simultaneously

A check followed by an insert in application code lets both through. Only a constraint at the database refuses the second, and the difference only shows under concurrency.

Increment one counter a hundred times at once

The final value should be exactly a hundred higher. A value read into the application and written back loses increments in direct proportion to concurrency.

Fail the last statement in a transaction

Then look for partial state. A half applied change is worse than a clean failure, because nothing reports it and the resulting data is entirely believable.

Add the rows up by hand

Compare a stored total, a cached count and a reporting figure against a direct calculation. Denormalised totals maintained in code drift, and nothing notices.

What Most Sets Miss

Why data defects are permanent

The single idea running through this set is that a rule enforced only in application code is not enforced. Uniqueness checked by selecting before inserting will admit duplicates the moment two requests arrive together. Referential integrity maintained by remembering to delete children first will produce orphans as soon as a new code path forgets. A status column constrained only by validation will accept anything a migration, an admin tool or a direct write chooses to put there. Each of these is testable in one case, and each produces damage that is silent at the time and permanent afterwards, because there is no error to alert anyone and the resulting rows look entirely reasonable.

Concurrency is where the gap between intent and enforcement becomes visible. A read modify write cycle loses updates, drops counter increments and permits balances to go negative, and none of it appears in sequential testing because sequential testing never creates the overlap. The correct forms are a conditional update, an atomic increment or a constraint, and the test is to fire the operations simultaneously and then check the arithmetic rather than checking that no error was returned. Deadlocks belong in the same group: they will happen, so the requirement is that the losing transaction is retried safely and that the retry does not apply the same change twice.

Migrations are the highest risk routine activity in most systems. They need testing forwards against production scale data, they need a rollback path or an explicit acknowledgement that there is none, and they need to be safe while the previous application version is still serving traffic, which means old and new code must both work against the intermediate schema. Backfills need to be rerunnable, because they get interrupted, and a backfill that reprocesses rows on the second run is as damaging as one that skips them.

Finally, two operational cases that get assumed rather than verified. Soft delete is a filter, and a filter applied in the main query and forgotten in a report, an export or a uniqueness check brings the record back, which is a data exposure rather than a bug. And a backup is not a backup until it has been restored: a backup job reporting success proves that a file was written, not that the data in it can be recovered inside the recovery time objective. Timing an actual restore into a clean environment is the only version of that test which means anything.

Suggest an improvement

Testing a data platform or migration?

QAble tests data integrity end to end, including constraint enforcement under concurrency, migration safety at production volume, ETL validation and verified restores.

Data validation and ETL testing services

More test case sets

View all

Test cases for a login page

Test cases
25 cases across functional, negative, boundary, security, session and accessibility paths, including account enumeration and lockout.

Test cases for a registration form

Test cases
28 cases covering validation, duplicate accounts, email verification, password rules and the enumeration leak most signup forms ship with.

Test cases for search functionality

Test cases
28 cases across relevance, partial and fuzzy matching, filters, pagination, empty states, injection attempts and performance under load.

Test cases for a shopping cart

Test cases
27 cases on quantity limits, price recalculation, stock changes, coupon stacking, guest to account merge and cart persistence.

Test cases for checkout and payment

Test cases
30 cases including 3D Secure, declines, timeouts, duplicate charges, idempotency, refunds and partial captures.

Test cases for file upload

Test cases
28 cases on size and type limits, spoofed content types, malicious filenames, progress, resume, virus scanning and storage limits.

Test cases for forgot password

Test cases
26 cases on reset token expiry, single use enforcement, session invalidation and the enumeration and rate limit gaps that are routine here.

Test cases for OTP verification

Test cases
26 cases on expiry, resend throttling, attempt limits, code reuse, delivery failure and the brute force window teams forget to close.

Test cases for user roles and permissions

Test cases
26 cases on horizontal and vertical privilege checks, direct object access, role changes mid-session and permission inheritance.

Test cases for form validation

Test cases
27 rules-based cases on required fields, length and numeric boundaries, client and server parity, hidden field tampering and error accessibility.

Test cases for a date picker

Test cases
26 cases on timezone shifts, ambiguous day and month order, impossible dates, min and max limits, leap years and keyboard operation.

Test cases for pagination

Test cases
24 cases on ordering stability, records changing mid-session, page size caps, deep offset cost, permission-filtered totals and state restore.

Test cases for push notifications

Test cases
26 cases on app states, deep link routing, token release on sign out, lock screen privacy, preferences, provider failures and platform differences.

Test cases for reports and data export

Test cases
25 cases on permission filtering in the file, spreadsheet formula injection, encoding, typed numbers and dates, row limits and audit logging.

Test cases for a chatbot

Test cases
28 cases on paraphrased intents, context, fallback loops, human handoff, policy grounding, prompt injection and data scoping.

Test cases for net banking transactions

Test cases
28 cases on duplicate debits from a retried request, concurrent transfers against one balance, daily limits across channels, beneficiary cooling periods, second factor binding and reconciliation.

Test cases for wallet and UPI payments

Test cases
28 cases on payments that time out with no response, idempotency on retry, racing balances, caps across devices, collect request fraud, mandates and refunds.

Test cases for insurance claim submission

Test cases
28 cases on coverage at the date of loss, waiting periods, deductibles and sub limits, exclusions and riders, duplicate claims and settlement reconciliation.

Test cases for patient records in an EHR

Test cases
28 cases on duplicate detection and merge, wrong patient entry, units of measure, allergy and interaction alerting, break glass access and audit of reads.

Test cases for CRM lead management

Test cases
28 cases on duplicate leads under concurrency, routing and the unrouted fallback, round robin races, territory visibility, conversion and bulk import.

Test cases for an ERP purchase order

Test cases
28 cases on approval thresholds, amendments that must reset approval, budget commitment races, over receipt tolerance, three-way match and duplicate invoices.

Test cases for OTT video playback

Test cases
28 cases on bitrate recovery after a dip, DRM renewal mid stream, concurrent stream limits and leaked slots, resume conflicts, ad cue points and offline expiry.

Test cases for game level progression

Test cases
28 cases on save corruption during a crash write, cloud save conflicts, offline queue replay, unlock gating, currency exploits and purchase restore.

Test cases for a REST API

Test cases
28 cases on status code correctness, cross tenant resource access, mass assignment, idempotent retries, cursor pagination, rate limits and contract drift.

Test cases for SSO and social login

Test cases
28 cases on linking an account on an unverified email, state and code replay, redirect allow lists, token signature and issuer, deprovisioning and session rotation.

Test cases for subscription and billing

Test cases
28 cases on mid cycle proration, duplicate and out of order webhooks, renewal double charges, dunning and grace, trials, coupons, metered usage and tax.

Test cases for data tables, filters and sorting

Test cases
28 cases on unstable sorts across pages, filters that must reset pagination, selection surviving a filter change, bulk action scope and export fidelity.

Test cases for session timeout and concurrent login

Test cases
28 cases on tokens that survive sign out, refresh token reuse, idle against absolute lifetime, multi tab expiry, session limits and remote revocation.

Test cases for a multi step form wizard

Test cases
28 cases on values lost to back navigation, refresh and session expiry, step skipping, server side revalidation, duplicate submission and conditional branches.

Test cases for email verification

Test cases
28 cases on token reuse and expiry, invalidating earlier links, account enumeration, header injection, safe address change and mail scanner prefetching.

Test cases for dashboards and analytics widgets

Test cases
28 cases on reconciling against source rows, widgets that disagree, timezone aggregation, zero baselines, no data shown as zero and permission leaks in aggregates.

Test cases for booking and reservation

Test cases
28 cases on concurrent bookings for the last slot, inventory holds that leak, payment without a booking, cancellation boundaries and channel sync.

Test cases for mobile app install and update

Test cases
28 cases on migration chains across skipped versions, crashes during post upgrade migration, forced update lockouts, deep links and clean reinstall.

Test cases for accessibility (WCAG 2.2 AA)

Test cases
28 cases on keyboard only completion, focus management, live region announcements, contrast, reflow at 320 pixels, target size and screen reader verification.

Test cases for performance and load

Test cases
28 cases on spikes with no ramp, recovery after peak, soak and leak detection, pool exhaustion, cold caches, retry storms and data correctness under load.

Test cases for the OWASP Top 10

Test cases
28 cases on broken access control, mass assignment, injection across every input surface, credential stuffing, session invalidation, SSRF and exposed secrets.

Test cases for cross browser compatibility

Test cases
28 cases on storage that throws in private mode, blocked third party cookies, engine date parsing, mobile viewport units, in app browsers and ad blockers.

Test cases for localisation and multi language support

Test cases
28 cases on text expansion, concatenated sentences, plural rules, locale date parsing, decimal separators, right to left layout, collation and encoding.

Want your data integrity proven, not assumed?

QAble covers constraints, concurrency and migration paths with ISTQB-certified engineers. Start with a free QA audit of your data layer.

Talk to QA Advisor