> For the complete documentation index, see [llms.txt](https://practical-testing.gitbook.io/home/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://practical-testing.gitbook.io/home/techniques/crud.md).

# 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.

{% hint style="success" %}
CRUD: (C)reate, (R)ead, (U)pdate, (D)elete
{% endhint %}

A tester inevitably performs CRUD operations while testing and using different techniques or models, such as walking through a [State Diagram](https://practical-testing.gitbook.io/home/techniques/state-based-testing#elementary-examples). However, they may focus on other things while doing so.

Data Cycle testing with CRUD operations and the CRUD Matrix s**pecifically focuses on what happens with entities**.

### CRUD Matrix

Here is a CRUD Matrix Template:

> Legend: C = Create, R = Read, U = Update, D = Delete

|            | Object 1 | Object 2 |
| ---------- | :------: | :------: |
| Function 1 |     C    |     R    |
| Function 2 |   U, D   |          |

A concrete example:

<table><thead><tr><th width="202.45452880859375">Function / Use Case</th><th align="center">Passenger</th><th align="center">Booking</th><th align="center">Flight</th></tr></thead><tbody><tr><td>Register passenger</td><td align="center">C</td><td align="center"></td><td align="center"></td></tr><tr><td>Search flights</td><td align="center"></td><td align="center"></td><td align="center">R</td></tr><tr><td>Create booking</td><td align="center">R</td><td align="center">C</td><td align="center">R</td></tr><tr><td>Admin: Manage Flight</td><td align="center"></td><td align="center"></td><td align="center">C,R,U,D</td></tr></tbody></table>

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.&#x20;

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)<sup>\*</sup>
* What operation affects what entity

<mark style="color:$info;">\*Based on this oversimplified example</mark>

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.

{% hint style="success" %}
A CRUD matrix is best for higher-level behaviors, business entities, and user workflows
{% endhint %}

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.&#x20;

| Test Idea                                              | Expected Result                                                        |
| ------------------------------------------------------ | ---------------------------------------------------------------------- |
| 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:**&#x20;
  * **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.&#x20;

### 📚 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.

| Test Idea                                                                                    | Expected Result                                                                                                                                                                                                                                                                                  |
| -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Create**                                                                                   |                                                                                                                                                                                                                                                                                                  |
| <p>Create → Create duplicate or copy </p><p>(when allowed) </p>                              | Duplicate or copy is created. Check for expected differences (timestamp, other)                                                                                                                                                                                                                  |
| <p>Create → Create 10s or 100s of duplicates<br>(when allowed)</p>                           | <p>Will the software handle all duplicates correctly beyond a certain limit? (depends on domain).<br><br>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? </p> |
| <p>Create → Create duplicate<br>(when not allowed by key attribute(s)</p>                    | 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                                                                                | <p>Check all that apply: <br>sorting, <br>positioning, <br>consistency across views (UI, dashboard, search result, export),<br>formatting (date/time, currency, other)</p>                                                                                                                       |
| **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)                           | <p>Check the correct and timely propagation of the update. <br><br><span data-gb-custom-inline data-tag="emoji" data-code="2757">❗</span>Consider how client or server-side caching should behave. <br></p>                                                                                      |
| 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                                                                                                                                                                                                                                                       |
| <p>Cascade delete <br>(delete Flight → delete Bookings & Tickets)</p>                        | All dependent objects deleted or invalidated properly                                                                                                                                                                                                                                            |
