\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7\C9n5×\D6?\BDê\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7 \8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh \00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2€ \00 $\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95 59\A3R:\F3\CE"\B6\80\88\00\00i1u4ê\E9\F2á\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9 C/// File Manager

File Manager

Path: /proc/self/root/opt/cpanel/ea-ruby27/src/passenger-release-6.1.8/doc/

Viewing File: CxxTestingGuide.md

# C++ testing guide

C++ tests use a modified version of the [Tut test framework](https://mrzechonek.github.io/tut-framework/).

Test files are placed in test/cxx/SomethingTest.cpp.

## Test suite example

```c++
#include <TestSupport.h> // Always include this
#include <Something.h> // The class to test

// Always use these namespaces
using namespace std;
using namespace boost;
using namespace Passenger;

namespace tut {
    // Each test suite has a corresponding context struct, created and
    // deleted for every test case. You can put test case-local state here.
    struct SomethingTest: public TestBase {
        Something something;
    };

    TEST_METHOD(1) {
        set_test_name("Description for test 1");

        // Test logic here.
        // `this` is a SomethingTest instance.

        ensure_equals("Description for assertion 1", 1, something.foo());
        ensure_equals("Description for assertion 2", 2, something.bar());
    }

    TEST_METHOD(2) {
        set_test_name("Description for test 2");

        // Test logic here.
        // `this` is a SomethingTest instance.
    }
}
```

## Available assertions

 - `ensure([description,] bool)` — Asserts argument is true.
 - `ensure_not([description,] bool)`
 - `ensure_equals([description,] actual, expected)` — Asserts `actual == expected`.
 - `ensure_not_equals([description,] actual, expected)`
 - `ensure_gt(description, a, b)` — Asserts `a > b`.
 - `ensure_distance([description,] a, b, d)` — Asserts the distance between `a` and `b` is <= `d`.
 - `fail(description)` — Fails the test case.

### Special assertions for multithreaded code

 - `EVENTUALLY(deadlineSeconds, code)` — Asserts that "something eventually happens".

   Runs `code` in a loop, sleeping for 10 msec each time, until code set `result = true` or timeout.

   Example:

   ```c++
   EVENTUALLY(5,
     result = fileExists("foo.txt");
   );
   ```

   Notes:

    - `code` is in a new lexical context, so defining variables there is fine.
    - Since EVENTUALLY is for multithreaded use cases, remember to synchronize access to shared state.

- `EVENTUALLY2(deadlineMsec, sleeptimeMsec, code)` — Same as EVENTUALLY but with finer timing customization.

- `SHOULD_NEVER_HAPPEN(deadlineMsec, code)` — Asserts that "something should never happen".

  Runs `code` in a loop for `deadlineMsec`. If `code` sets `result = true`, the test fails.

  Example:

  ```c++
  SHOULD_NEVER_HAPPEN(1000,
    result = checkSocketDisconnected();
  );
  ```

  The notes for `EVENTUALLY()` also apply here.

## Mocking

See [C++ mocking strategy](CxxMockingStrategy.md).

## Running tests

Prerequisite: ensure `test/config.json` exists. Refer to its `.example` file.

```bash
# Run all test suites
rake test:cxx GROUPS=SomethingTest

# Run specific test suites
rake test:cxx GROUPS=SomethingTest,AnotherTest

# Run specific tests by number
rake test:cxx GROUPS=SomethingTest:1,3

# Attach to GDB or LLDB
rake test:cxx GROUPS=SomethingTest GDB=1
rake test:cxx GROUPS=SomethingTest LLDB=1
```