---
feature_story: FS_66_17_43_42
feature_title: test infra
feature_status: PARTIAL
---

# Intro into test modes

All tests run both (obviously):
*   test code
*   prod code

*   For test code, it is:
    *   a test scenario
*   For prod code, it is either:
    *   client
    *   server

All three (test scenario, client, server) can run:
*   `in`: in the same process (OS process with same PID) sharing same memory and using direct func invocation
*   `out`: in separate processes (from test scenario OS process POV) using some form of IPC
*   `none`: when that prod code part (either client or server) is not invoked in tests anyhow

This gives us 9 test modes (3 x 3 combinations).

And 3 of them are special = particularly useful to have extra support from the framework:

| # | client   | server   | special | description                                                                                                                    |
|---|----------|----------|---------|--------------------------------------------------------------------------------------------------------------------------------|
| 1 | c-`in`   | s-`in`   | yes     | Client and server code is invoked directly (no IPC). This allows maximum internal mocking and data inspection in tests.        |
| 2 | c-`in`   | s-`out`  | yes     | Client code is invoked directly. Server code is invoked via IPC. Useful to intercept server responses in tests for inspection. |
| 3 | c-`in`   | s-`none` |         | Trivial case - might be used to test client code, but client is very thin to be tested alone.                                  |
| 4 | c-`out`  | s-`in`   |         | Impossible: all server actions are initiated via client but test scenario OS process runs server.                              |
| 5 | c-`out`  | s-`out`  | yes     | Client code is invoked via CLI. Server code is invoked via IPC. This is the fattest test possible, but has the least control.  |
| 6 | c-`out`  | s-`none` |         | Trivial case - might be used to test client code only, but client is very thin to be worth tested alone.                       |
| 7 | c-`none` | s-`in`   | nah     | No client code is invoked. Test scenario simulates client. Server code is invoked directly.                                    |
| 8 | c-`none` | s-`out`  |         | No client code is invoked. Test scenario simulates client. Server code is invoked via IPC.                                     |
| 9 | c-`none` | s-`none` |         | No client or server code is invoked. It is used to test assumptions (e.g. about MongoDB), for example: `MongoClientTestClass`. |

# Special test modes

## 1: client-`in` server-`in`

Both client and server code runs `in` the same process with test scenario allowing full internal control.

Pros:
*   Virtually anything can be mocked for client and server.
*   Convenient to assert data inside `InterpContext` (internal to server).<br/>
    Otherwise, effects on data inside `InterpContext` might be hardly observable.

Cons:
*   Code marshalling data over the network (in normal client-server operation) is not tested.

See usage/examples of:
*   Client-side mocking support: `LocalClientEnvMockBuilder`
*   Case test class: `LocalTestClass`

## 2: client-`in` server-`out`

See usage/examples of:

*   Client-side mocking support: `LiveServerEnvMockBuilder`
*   Case test class: `RemoteTestClass`

## 5: client-`out` server-`out`

See usage/examples of:

*   There is no way to mock anything - tests can only assert proc invocation results (exit code, stdout, stderr).
*   Case test classes:
    *   `End2EndTestClass`
    *   `CypressTestClass`

## 7: client-`out` server-`in`

Initially, it was thought of as the best option to start server with mocked config to run GUI tests against that.
But due to unknown ways to control such server (to re-spawn), this option is very limited - see `ServerOnlyTestClass`.

To test GUI, use special test mode #5 instead.

See usage/examples of:
*   Server-side mocking support: `ServerOnlyEnvMockBuilder`
*   Case test class: `ServerOnlyTestClass`

