Configuring and Testing the Project for Test Mode in Pytest and adding some tests for config.py
Published: 2023-06-27 15:11:50

Title: Ensuring Test Mode with Pytest: Configuration and Testing Guide

Table of Contents:
1. Introduction
2. Modifying conftest.py
3. Creating test_general.py
4. Creating test_config.py
5. Test Cases
6. Conclusion

Introduction:
To ensure that our project runs in test mode each time we use Pytest, we need to configure it accordingly. In this section, we'll walk through the necessary steps to set up the project for test mode and create tests to verify its behavior. Let's get started!

Modifying conftest.py:
In the conftest.py file located at the root of your project, add the following code snippet. This code sets the RUN_MODE environment variable to "test" whenever Pytest is run, ensuring that our project runs in test mode during testing.

```python
import os

def pytest_configure(config):
    os.environ["RUN_MODE"] = "test"
```

Creating test_general.py:
Create a new file called test_general.py in the tests folder and add the provided code snippet. This test verifies that the project is running in test mode by checking the value of the RUN_MODE environment variable.

```python
import os

def test_run_mode_value_at_run_time():
    assert os.environ["RUN_MODE"] == "test"
```

Creating test_config.py:
Create another file called test_config.py in the tests folder and add the following code snippets. This file includes multiple test cases to validate different aspects of the Config class:

```python
import os
from config import Config

def test_config_singleton():
    config1 = Config()
    config2 = Config()
    assert config1 is config2


def test_config_default_values():
    os.environ.pop("RABBITMQ_HOST", None)
    os.environ.pop("RABBITMQ_PORT", None)
    os.environ.pop("RABBITMQ_USER", None)
    os.environ.pop("RABBITMQ_PASSWORD", None)
    os.environ.pop("RABBITMQ_VHOST", None)
    os.environ.pop("RUN_MODE", None)

    config = Config(load_from_file=False, override=True)
    assert config.RABBITMQ_HOST == "localhost"
    assert config.RABBITMQ_PORT == 5672
    assert config.RABBITMQ_USER == "admin"
    assert config.RABBITMQ_PASSWORD == "admin"
    assert config.RABBITMQ_VHOST == "localhost"
    assert config.RUN_MODE == "debug"

    os.environ["RUN_MODE"] = "test"


def test_is_test_mode():
    config = Config(override=True)

    config.RUN_MODE = "test"
    assert config.is_test_mode() is True

    config.RUN_MODE = "debug"
    assert config.is_test_mode() is False

    config.RUN_MODE = "prod"
    assert config.is_test_mode() is False

    config.RUN_MODE = "test"


def test_is_debug_mode():
    config = Config(override=True)

    config.RUN_MODE = "test"
    assert config.is_debug_mode() is False

    config.RUN_MODE = "debug"
    assert config.is_debug_mode() is True

    config.RUN_MODE = "prod"
    assert config.is_debug_mode() is False

    config.RUN_MODE = "test"


def test_waiting_factor():
    config = Config(override=True)

    config.RUN_MODE = "test"
    assert config.waiting_factor() == 0

    config.RUN_MODE = "debug"
    assert config.waiting_factor() == 2

    config.RUN_MODE = "prod"
    assert config.waiting_factor() == 2

    config.RUN_MODE = "test"
```

Test Cases:
1. Test Case: `test_config_singleton()`
   - This test verifies that the `Config` class follows the Singleton design pattern.
   - It creates two instances of the `Config` class, `config1` and `config2`, and asserts that they are the same object (`config1 is config2`).
   - By ensuring that both instances refer to the same object, we confirm that only one instance of the `Config` class exists, as expected for a Singleton.

2. Test Case: `test_config_default_values()`
   - This test checks if the default values of the `Config` class are correctly set when certain environment variables are not defined.
   - It removes specific environment variables related to RabbitMQ configuration and the `RUN_MODE` from the environment.
   - Then, it creates an instance of the `Config` class with `load_from_file` set to `False` and `override` set to `True`.
   - The test asserts that the instance's attributes (`config.RABBITMQ_HOST`, `config.RABBITMQ_PORT`, etc.) are set to their expected default values.
   - These expected default values are "localhost" for `RABBITMQ_HOST`, 5672 for `RABBITMQ_PORT`, "admin" for `RABBITMQ_USER` and `RABBITMQ_PASSWORD`, and "debug" for `RUN_MODE`.
   - Finally, it sets `RUN_MODE` to "test" in the environment for further test cases that rely on it.

3. Test Case: `test_is_test_mode()`
   - This test checks if the `is_test_mode()` method of the `Config` class correctly determines whether the project is running in test mode.
   - It creates an instance of the `Config` class with `override` set to `True`.
   - The test sets the `RUN_MODE` attribute to different values ("test", "debug", "prod") and asserts the return values of `is_test_mode()` accordingly.
   - It expects `is_test_mode()` to return `True` when `RUN_MODE` is set to "test" and `False` for other modes.

4. Test Case: `test_is_debug_mode()`
   - Similar to the previous test case, this test checks if the `is_debug_mode()` method of the `Config` class correctly determines whether the project is running in debug mode.
   - It creates an instance of the `Config` class with `override` set to `True`.
   - The test sets the `RUN_MODE` attribute to different values ("test", "debug", "prod") and asserts the return values of `is_debug_mode()` accordingly.
   - It expects `is_debug_mode()` to return `True` when `RUN_MODE` is set to "debug" and `False` for other modes.

5. Test Case: `test_waiting_factor()`
   - This test verifies the behavior of the `waiting_factor()` method of the `Config` class.
   - It creates an instance of the `Config` class with `override` set to `True`.
   - The test sets the `RUN_MODE` attribute to different values ("test", "debug", "prod") and asserts the return values of `waiting_factor()` accordingly.
   - It expects `waiting_factor()` to return 0 when `RUN_MODE` is set to "test" and 2 for other modes.

Conclusion:
With the configuration and tests in place, your project is now set up to run in test mode during Pytest execution. The added tests validate that the project is indeed running in test mode, that the Config class behaves as expected, and that the default values are correctly assigned. This ensures the reliability and correctness of your testing environment. You're now ready to run Pytest and enjoy the benefits of a well-configured and thoroughly tested project. Happy testing!