Testing Fundamentals
Database Testing Interview Questions & Answers
Database testing interview questions on data integrity, constraints, transactions and ACID, migrations, UI vs DB validation and test data management.
Interview Questions
Showing 15 of 50 questions
Database testing verifies that data is stored, updated and retrieved correctly, and that the schema, constraints, triggers, stored procedures and transactions behave as expected. It ensures what the application shows matches what is actually persisted.
The UI can show success while the backend saves wrong, duplicate or partial data. Checking the database catches silent data corruption, wrong defaults and missing audit records that UI tests cannot see.
Data integrity means data stays accurate and consistent over its lifecycle. The main types are entity integrity via primary keys, referential integrity via foreign keys, and domain integrity via data types, CHECK, NOT NULL and default constraints.
I validate PRIMARY KEY, FOREIGN KEY, UNIQUE, NOT NULL, CHECK and DEFAULT constraints by trying to insert invalid data and confirming the database rejects it, and by inserting without optional values to confirm defaults apply.
A primary key uniquely identifies each row and cannot be null, with one per table. A unique key also prevents duplicates but a table can have many and most databases allow NULLs. A foreign key references a primary or unique key in another table to enforce relationships.
For each operation performed in the UI or API, I query the relevant tables to confirm the row was created, updated with the right values, soft- or hard-deleted, and that related tables and audit columns like updated_at changed correctly.
A transaction is a group of operations treated as a single unit of work. COMMIT makes all changes permanent, and ROLLBACK undoes every change since the transaction began, so data never stays half-updated.
ACID stands for Atomicity, Consistency, Isolation and Durability. In a bank transfer, atomicity means both debit and credit happen or neither does, consistency keeps balances valid, isolation stops concurrent transfers from seeing partial state, and durability keeps the committed transfer after a crash.
The levels are Read Uncommitted, Read Committed, Repeatable Read and Serializable. Higher levels prevent more anomalies: dirty reads, non-repeatable reads and phantom reads, at the cost of concurrency.
I capture the values from the UI using the automation tool, run the equivalent SQL query through JDBC or a DB library, and compare them field by field, normalizing formats like dates, currency and rounding before asserting.
I add the JDBC driver dependency, create a connection with DriverManager or a pooled DataSource such as HikariCP, use PreparedStatement for parameterized queries, and close resources with try-with-resources.
I use a DB-API driver such as psycopg for PostgreSQL or PyMySQL for MySQL, often wrapped in a pytest fixture, and run parameterized queries with placeholders instead of string formatting.
I create test data per test through APIs or seed scripts, use unique identifiers to avoid collisions, clean up in teardown or roll back transactions, and use masked or synthetic data instead of raw production data.
For stored procedures I call them with valid, invalid, null and boundary parameters and verify output parameters, result sets and table changes. For triggers I perform the triggering insert, update or delete and confirm the expected side effect, such as an audit row, happened exactly once.
I run the migration on a copy of production-like data, verify the schema changes, compare row counts and checksums before and after, validate transformed values, confirm the application works on the new schema, and test the rollback script.