CRUD
CRUD for Data Lifecycle Testing
Most software has data: a registered user, an account, flight, booking, past transactions. This data may also be referred to as objects or entities.
Such objects typically have a lifecycle - they are created, changed, and optionally, eventually deleted. Changes in data are typically done with CRUD operations: Create, Read, Update, Delete.
CRUD: (C)reate, (R)ead, (U)pdate, (D)elete
A tester inevitably performs CRUD operations while testing and using different techniques or models, such as walking through a State Diagram. However, they may focus on other things while doing so.
Data Cycle testing with CRUD operations and the CRUD Matrix specifically focuses on what happens with entities.
CRUD Matrix
Here is a CRUD Matrix Template:
Legend: C = Create, R = Read, U = Update, D = Delete
Function 1
C
R
Function 2
U, D
A concrete example:
Register passenger
C
Search flights
R
Create booking
R
C
R
Admin: Manage Flight
C,R,U,D
What do we see in this table? Among other things:
When we register a passenger, Booking and Flight are not affected (or should not be).
That booking a flight (Create booking) relies on Read operations from other entities.
This minimalistic table can become a basis for test cases, but it also makes it clear:
That some entities are fundamental and independent (passenger, flight), and others are composed of those entities (booking is composed of Passenger and Flight)*
What operation affects what entity
*Based on this oversimplified example
What are the benefits of a CRUD matrix?
High-level overview: helps verify that each entity in the system supports all relevant CRUD operations.
Identify gaps: helps with identifying gaps where an operation is missing, incomplete, or inconsistent across entities.
Example: Airline staff can create and cancel flights, but cannot update flight time once bookings exist
Data integrity: highlights dependencies between entities, leading to better tests
Example: Updating flight departure time should affect corresponding details on all relevant bookings, but this doesn't happen, or unrelated flights are affected.
CRUD matrix at different levels
In theory, a CRUD matrix can be used at any level, including for white-box unit tests. However, code changes frequently, and such matrices are likely to become outdated quickly.
A CRUD matrix is best for higher-level behaviors, business entities, and user workflows
Matrices and higher (more abstract) level:
Less maintenance, less frequent changes
Help seeing inconsistencies across lower-level entities or code functions
π Simple Testing with CRUD
Here is a simple list of basic CRUD tests as a warm-up.
Create object β Read object
Object is created and can be retrieved correctly
Update object β Read object
Updates are saved and visible when reading
Delete object β Read object
Deleted object is no longer available. A clear message is displayed.
Create multiple objects at once if possible β Read all
All created objects are listed correctly
Update multiple objects at once if possible β Read all
Updates are saved and visible when reading.
Delete multiple objects at once if possible β Read all
Deleted objects are no longer available. A clear message is displayed.
Create with missing required fields
Creation is rejected with clear error message
Create with missing optional fields
Creation is possible
For most of the above scenarios, some or all of the following additional checks may apply:
Side-effects: Verify that no other objects are affected (e.g., Deletion or update of A does not cause unintended side-effects on other objects)
Refresh: After C, U, or D - does the UI or other refresh the view automatically, or does it require a manual refresh? (The need for manual refresh may be unintuitive and confusing)
Caching: if there's caching at any layer of the SUT, should it be updated? Double-check. How does it affect the "refresh" behavior?
Update or Deletion effects:
Failure to propagate changes everywhere and promptly (e.g., after an update, one view reflects the change immediately, another only minutes or hours later, when not expected).
Failure to hide deleted or archived data from reads.
π Advanced Testing with CRUD
Here is a non-exhaustive list of more advanced tests. Consider that many actions may be done via UI, API, or other means.
Create
Create β Create duplicate or copy
(when allowed)
Duplicate or copy is created. Check for expected differences (timestamp, other)
Create β Create 10s or 100s of duplicates (when allowed)
Will the software handle all duplicates correctly beyond a certain limit? (depends on domain). Example: when creating a file copy, a "copy" may be appended. What happens when so many copies are made that the file name length is exceeded or the software exhausts disk space?
Create β Create duplicate (when not allowed by key attribute(s)
2nd creation not allowed with a clear message of why (without leaking sensitive information to unauthorized user)
Partial failure during create (multi-step)
Either full rollback or consistent recovery, no half-created object
Read
Update β Read
Check all that apply: sorting, positioning, consistency across views (UI, dashboard, search result, export), formatting (date/time, currency, other)
Update
Create β Create allowed duplicate or copy β Update duplicate key attribute to match original
Update should not be allowed
Update β Read from multiple sources if applicable (UI, API, other)
Check the correct and timely propagation of the update. βConsider how client or server-side caching should behave.
Delete β Update
System shows relevant error
Concurrent updates to same object
System resolves conflict (last write wins, or error shown)
Cross-entity integrity (update Flight β Bookings)
Related entities update consistently
Delete
Create β Delete β Delete
2nd deletion attempt is handled gracefully
Cascade delete (delete Flight β delete Bookings & Tickets)
All dependent objects deleted or invalidated properly
Last updated