|
| 1 | +# An example of integration tests. |
| 2 | +I recommend this approach because it’s independent of the application’s |
| 3 | + architecture and allows you to test your application in a realistic way. |
| 4 | + |
| 5 | +When testing with a real database, one important problem needs to be |
| 6 | +solved - ensuring data isolation between tests. |
| 7 | + |
| 8 | +There are basically two approaches: |
| 9 | + |
| 10 | + |
| 11 | +1. Separate sessions |
| 12 | + |
| 13 | +The test has its own session that it uses to prepare data and verify |
| 14 | +results after execution. |
| 15 | +The application also has its own session. |
| 16 | +Data isolation is achieved by clearing all tables at the end of each test |
| 17 | +(and once before running all tests). |
| 18 | + |
| 19 | +2. Shared session and transaction |
| 20 | +The test and the application share the same session and transaction. |
| 21 | +Data isolation is achieved by rolling back the transaction at |
| 22 | +the end of the test. |
| 23 | + |
| 24 | +Personally, I prefer the first option, because it is a more "honest" way |
| 25 | +to test the application. |
| 26 | +We can verify how it handles sessions and transactions on its own. |
| 27 | +It’s also convenient to inspect the database state when a test is paused. |
| 28 | + |
| 29 | +Sometimes, there are complex session management scenarios (for example, |
| 30 | +concurrent query execution) where other types of testing are either |
| 31 | +impossible or very difficult. |
| 32 | + |
| 33 | +The main disadvantage of this approach is the slower execution speed. |
| 34 | +Since we clear all tables after each test, this process takes additional time. |
| 35 | + |
| 36 | +This is where the second approach comes in - its main advantage is speed, |
| 37 | +as rolling back a transaction is very fast. |
| 38 | + |
| 39 | +In my projects, I use both approaches at the same time: |
| 40 | + |
| 41 | +- For most tests with simple or common logic, I use a shared transaction |
| 42 | +for the test and the application |
| 43 | +- For more complex cases, or ones that cannot be tested this way, |
| 44 | +I use separate transactions. |
| 45 | + |
| 46 | + |
| 47 | +This combination allows for both good performance and convenient testing. |
| 48 | + |
| 49 | +The library provides several utilities that can be used in tests - for |
| 50 | +example, in fixtures. |
| 51 | +They help create tests that share a common transaction between the test |
| 52 | +and the application, so data isolation between tests is achieved through |
| 53 | +fast transaction rollback. |
| 54 | + |
| 55 | +You can see these capabilities in the examples: |
| 56 | + |
| 57 | +[Here are tests with a common transaction between the |
| 58 | +application and the tests.](transactional) |
| 59 | + |
| 60 | + |
| 61 | +[And here's an example with different transactions.](non_transactional) |
0 commit comments