Database testing is the process of evaluating the accuracy, reliability, and performance of a database system. Its purpose is to ensure that the data stored there is consistent, valid, and can be correctly manipulated for business needs. The components to be tested are usually database schema, tables, and database triggers. Testers leverage SQL queries, data comparison tools, automation frameworks, or load testing tools to examine the data integrity, validity, security, performance, and structure.
These scenarios result in a misunderstanding between the two systems, causing disastrous consequences. Imagine a bug occurs in the patient record database of a healthcare billing system. When retrieving data in the patient database to calculate their billing, the wrong data field was chosen, and patients ended up receiving bills for services they never received in the first place. If this occurs at a wide enough scale, the impact will surely be costly to reverse.
Data mapping issues can also originate from issues with data accuracy and data integrity. Data accuracy is how correctly the data represents real-world scenarios, while data integrity is more about its consistency throughout the entire life cycle (from data entry to storage and retrieval). We know that data undergoes so many changes throughout its lifecycle, and those changes can totally bring in new errors that eventually lead to issues in data mapping.
There are usually 4 types of data integrity that database testers need to pay attention to:
There is no point having millions of accurate but irrelevant data points. While not a particularly technical aspect of DB testing, conformity with business requirements is still an important indicator of data quality. Testers all have a clear understanding of business requirements since they are involved in the Requirements Collection process. These requirements should be written as a checklist, then testers and stakeholders can sit together to determine how to test each item in the list through a comprehensive methodology.
Before further delving into each of these properties, we need to define the concept of a “transaction” in a database.
A transaction is a logical unit of work that consists of one or more operations performed on a database to access and modify its content. For example, in a retail inventory system, when a product is sold, the database needs to update both the available quantity of the product and the sales record. These updates are executed within a transaction.
ACID properties are a set of characteristics that ensure reliable and consistent transactions in a database system. Essentially they are the 4 major rules for a good transaction in any database, and testers can base their test plan on those rules. ACID stands for:
Every transaction in the system is treated as a single, indivisible unit, hence the term “atom-icity”. Either all of the operations in the transaction are successfully completed, or none of them are applied. There is no middle ground.
Following this property, there are only 2 outcomes for a transaction:
The correctness and integrity of the data and database’s state must be maintained before and after a transaction. In other words, the existing rules defining relationships between data fields must be kept the same when the database is brought from one state to another. The relationships, or integrity constraints , that should not be violated may include:
Suppose we have a banking application with two tables: Accounts and Transactions.
An integrity constraint states that the balance in the Accounts table should always be consistent with the sum of transaction amounts in the Transactions table for that account.
Initial State:
Transaction 1:
Transaction 2 (Concurrently):
Consistency Check:
At this point, the consistency property ensures that:
Transaction
Account Balance
(Accounts Table)
Transactions Table
(if both commit concurrently)
Sum of transaction amounts matches account balance
Isolation means ensuring that each transaction is executed in isolation from other concurrently executing transactions. Even though multiple transactions may be occurring simultaneously, each transaction should not interfere with others. This prevents issues that can arise when one transaction reads or modifies data that another transaction is in the process of modifying, such as:
Isolation levels are therefore necessary to govern how transactions in a database interact with each other, preventing such scenarios from happening.
Durability guarantees that once a transaction is committed, its changes are permanent and will survive system failures, crashes, or power outages. Even if the system restarts or fails, the database will be brought back to a consistent state by applying the committed changes from a durable storage medium.
Structural testing, also known as glass box testing or white-box testing, focuses on examining the internal structure of the system (which is the database and its components in this case). The goal is to ensure that the database schema, tables, relationships, constraints, and other structural elements are designed and implemented correctly.
Several types of structural testing include:
For database testing specifically, functional testing focuses more on the functional aspects of the database, ensuring that it can perform its intended purposes
In the scope of this type, we focus on performance testing, load testing, stress testing, security testing, and any type of testing whose scope goes beyond the core functionalities, ensuring that these non-functional aspects of the database meet the business requirements.
Here are some examples of non-functional test cases you can do on a database:
DB testing is similar to any other type of testing: it has to follow all of the stages in the software testing life cycle to ensure the highest level of test coverage. The key stages can be found in the flowchart below:
During the Requirement Analysis phase, database testers work with stakeholders involved in the development process to identify and understand test requirements. All of the information collected during this stage should be noted in a Requirement Traceability Matrix (RTM) document, which will be the foundation to build the test strategy and test plan .
Following the plan, the QA team will create test cases, set up the suitable environment for the execution , and run those tests. The results will be carefully analyzed to identify the root cause of issues found so that the development team can better address them. Finally, a report will be generated to consolidate the findings into insights and recommendations for future decision-making.
There are several excellent database testing tools available that cater to different testing needs. Here are 5 widely used and highly regarded database testing frameworks and tools:
When performing DB testing, testers must first understand SQL and database concepts. They should be comfortable writing and analyzing SQL queries for data retrieval, manipulation, and validation. Knowledge in testing, especially how to leverage automation testing tools to design test cases, is also crucial.
To write effective test cases, testers must first identify the scenarios they want to test, then define the initial state of the database for each test case. There should be clear test steps and expected results to compare against. Beside the “common” test cases, testers should also explore boundary and edge cases to ensure higher coverage.
ETL (Extract, Transform, Load) testing is a subset of database testing that focuses on verifying the data extraction, transformation, and loading processes within a data integration pipeline. ETL testing is much more specific, focusing on the data movement and transformation process, while database testing encompasses the entire range of testing activities in the database.
Yes, database testing can be automated using testing frameworks and libraries designed for database interactions. Tools like DbUnit, SQLUnit, and various scripting languages allow you to automate database testing tasks, execute SQL queries, validate results, and compare expected outcomes.
Database testing includes both functional and non-functional aspects. Functional testing ensures that the database performs its intended operations correctly, such as data retrieval, manipulation, and validation. Non-functional testing covers performance, security, scalability, and other attributes that ensure the database system's quality.
Selenium is primarily designed for web UI testing and is not the recommended tool for direct database testing. However, you can use Selenium to indirectly test database-related functionality by interacting with web applications that use databases. For instance, you can automate web UI actions that trigger database operations and validate their outcomes indirectly through the UI.
Aspect
Manual Testing
Automation Testing
Tester Involvement
Human testers execute test cases manually.
Automated tools execute test cases automatically.
Test Case Execution
Test cases executed manually without tools.
Test cases executed by automation scripts.
Suitable for
Exploratory testing, usability testing,
Regression testing, performance testing
Testing Types
ad-hoc testing, small projects.
large-scale testing, repetitive tasks.
Human Intervention
Requires human intervention for each test case.
Limited human intervention after script setup.
Error Prone
Prone to human errors and subjectivity.
Reduces human errors, increases repeatability.
Project Scale
Suitable for small projects or when test cases change frequently.
Suitable for large and complex projects with consistent requirements.
Efficiency
Time-consuming for repetitive or large-scale testing.
Efficient for repetitive tasks and regression testing.
Initial Setup
Simpler initial setup; doesn't require scripting skills.
Initial setup requires scripting skills and may take longer.
Adaptability
Offers more flexibility in adapting to changes.
Less adaptable to changes in the application.
Speed of Execution
Slower compared to automated testing.
Faster test execution once scripts are set up.