1. Installation & Setup ๐Ÿ› ๏ธ

Before you start creating tests, you need to install VIPENTIUM. This step is crucial because it sets up all the necessary tools and libraries to discover and run your tests automatically.

Why?

Installing via pip ensures you get the latest stable version, compatibility with your environment, and access to updates.

Command:

pip install vipentium

Once this command runs successfully, VIPENTIUM is installed globally (or in your virtual environment) and is ready for use in your projects.

๐Ÿ” 2. Detailed Commandโ€‘Line Options for Vipentium

Vipentium supports a number of commandโ€‘line options so you can customize how tests are discovered, executed, and reported. Below is an inโ€‘depth explanation for each option, including when to use it, what it does, and sample commands. ๐Ÿš€

๐Ÿ“ <test_path>

The <test_path> specifies the relative or absolute path to your test files, directories, or modules. Vipentium automatically discovers tests that start with test_, so using the correct path is key. โœ…

# Running tests in a directory:
vipentium-runner tests/

# Running tests in a specific file:
vipentium-runner tests/test_example.py

# Running tests in a module:
vipentium-runner tests.my_module
        

โฉ --parallel

Use --parallel to enable parallel execution (via threads) of your tests. This option can dramatically reduce test runtime for large suites. โšก

# Run tests in parallel:
vipentium-runner tests/ --parallel
        

Note: Parallel execution works best when tests don't share mutable state. ๐Ÿ”’

๐Ÿ–ฅ๏ธ --process (Experimental)

The --process option runs tests in separate processes rather than threads. This gives you better isolation, useful if tests might interfere with each other or if you need to bypass the GIL. ๐Ÿ”„

# Run tests in separate processes for isolation:
vipentium-runner tests/ --parallel --process
        

Tip: Use --process together with --parallel for maximum isolation. ๐Ÿ‘Œ

๐Ÿ“ฃ --verbose

The --verbose option provides detailed output for each test, which can help with debugging and analysis. More information is printed about the execution process. ๐Ÿ”

vipentium-runner tests/ --verbose
        

๐Ÿ“ฃ --trello

The --trello option automatically transforms test failures into detailed Trello cards. When a test fails, error messages and tracebacks are sent directly to your configured Trello boardโ€”making it easy to track and resolve issues in real time. ๐Ÿš€

vipentium-runner tests/ --trello
    
Important Notes:
- The --trello option works only in standalone mode.
- It cannot be used alongside other command-line options.

๐Ÿ“„ --report-json <filename>

The --report-json <filename> option produces a JSON report summarizing your test run, including test counts, pass/fail statistics, and execution details. Perfect for CI/CD integration. ๐Ÿค–

vipentium-runner tests/ --report-json report.json
        

๐Ÿ–ฅ๏ธ --report-html <filename>

The --report-html <filename> option outputs a humanโ€‘readable HTML report summarizing your test run. This report makes it easy to visually review and share results with your team. ๐ŸŽจ

vipentium-runner tests/ --report-html report.html
        

๐Ÿ”– --mark <marker>

The --mark <marker> option filters tests based on a custom marker, specified using the @mark decorator. It allows you to run only tests with certain tags (e.g., "integration", "critical"). ๐Ÿ”

# Run tests marked as "integration":
vipentium-runner tests/ --mark integration

# Run tests with multiple markers:
vipentium-runner tests/ --mark database --mark critical
        

Selecting specific markers saves time and helps in targeted debugging. ๐ŸŽฏ

Trello Environment Variable Setup โš™๏ธ

Configure your Trello credentials using environment variables for seamless integration with Vipentium. Follow the steps below for setup in Command Prompt or PowerShell.

Step 1: Setup in Command Prompt ๐Ÿ’ป

Run the following commands in **Command Prompt** to set Trello credentials:

set TRELLO_TOKEN=your_trello_api_token_here
set TRELLO_KEY=your_trello_api_key_here
set TRELLO_LIST_ID=your_trello_list_id_here
      

To **verify** the stored values, run:

echo %TRELLO_TOKEN%
echo %TRELLO_KEY%
echo %TRELLO_LIST_ID%
      

Step 2: Setup in PowerShell โšก

Run these commands in **PowerShell** to set environment variables:

$env:TRELLO_TOKEN = "your_trello_api_token_here"
$env:TRELLO_KEY = "your_trello_api_key_here"
$env:TRELLO_LIST_ID = "your_trello_list_id_here"
      

To **verify** stored values, run:

echo $env:TRELLO_TOKEN
echo $env:TRELLO_KEY
echo $env:TRELLO_LIST_ID
      

Step 3: Reset Trello Variables ๐Ÿ”„

If you need to **clear** the stored Trello credentials, run the following:

Command Prompt:

set TRELLO_TOKEN=
set TRELLO_KEY=
set TRELLO_LIST_ID=
      

PowerShell:

Remove-Item Env:TRELLO_TOKEN
Remove-Item Env:TRELLO_KEY
Remove-Item Env:TRELLO_LIST_ID
      

To **confirm removal**, run the verification commands from earlier.

You're all set! Trello credentials are configured for Vipentium. ๐Ÿš€

3. Writing Test Cases โœ๏ธ

Step 3.1: Test File Naming ๐Ÿ“

What to Do: Name your test files with the test_ prefix (e.g., test_utils.py).

Why? This naming convention signals VIPENTIUM to automatically discover and collect tests during the execution phase.

Example File Names:
- test_calculator.py
- test_string_methods.py

Step 3.2: Test Class Definition ๐Ÿ—๏ธ

What to Do: Create a test class that inherits from the TestCase base class provided by VIPENTIUM.

Why? Inheriting from TestCase gives your class builtโ€‘in assertion methods and a standardized testing interface.

from vipentium import TestCase

class TestArithmetic(TestCase):
    # This class now has access to VIPENTIUM's assertion methods.
    pass

Step 3.3: Test Method Definition ๐Ÿ“

What to Do: Within your test class, define methods to test specific functionalities. Each method must begin with test_ (e.g., test_addition).

Why? The prefix test_ tells VIPENTIUM that the method is a test case to be executed.

class TestArithmetic(TestCase):
    def test_addition(self):
        # Tests a simple addition operation.
        pass

Step 3.4: Assertions โœ…

What to Do: Within your test methods, use assertions to compare expected outcomes with actual results. VIPENTIUM provides the assert_equal(a, b) method.

Why? Assertions ensure that your code behaves as expected and provide consistent error reporting integrated with VIPENTIUM.

class TestArithmetic(TestCase):
    def test_addition(self):
        self.assert_equal(1 + 1, 2)

    def test_division(self):
        # You can also use Python's builtโ€‘in assert.
        assert 10 / 2 == 5

4. Decorators for Enhanced Testing ๐Ÿ’Ž

4.1: @parameters ๐ŸŽฏ

What it Does: Runs a test method with multiple sets of input values.

Why? It minimizes code repetition and tests a function under various scenarios.

from vipentium import TestCase, parameters

class TestArithmeticParameterized(TestCase):
    @parameters(
        (5, 2, 7),
        (10, -3, 7),
        (0, 0, 0)
    )
    def test_add(self, a, b, expected):
        self.assert_equal(a + b, expected)

4.2: @timeout โฐ

What it Does: Enforces that a test completes within a specified time.

Why? This helps catch performance issues or infinite loops by failing tests that take too long.

from vipentium import TestCase, timeout

class TestTimeout(TestCase):
    @timeout(2)  # Test must complete within 2 seconds.
    def test_long_running(self):
        self.assert_equal(sum(range(1000000)), 499999500000)

4.3: @retry ๐Ÿ”

What it Does: Automatically retries a test if it fails.

Why? It is useful for tests with intermittent issues, reducing the chance of false negatives.

from vipentium import TestCase, retry

class TestRetry(TestCase):
    @retry(3)  # Retry up to 3 times if test fails.
    def test_flaky(self):
        self.assert_equal(2 * 2, 4)

4.4: @mark ๐Ÿท๏ธ

What it Does: Tags tests or classes so you can filter and organize them.

Why? Markers help run specific groups of tests, especially as the test suite grows.

from vipentium import TestCase, mark

@mark("basic")
class TestStringOperations(TestCase):
    def test_concat(self):
        self.assert_equal("hello" + "world", "helloworld")

4.5: @fixture ๐Ÿ”ง

What it Does: Defines reusable setup functions (fixtures) for initializing data or environment.

Why? Fixtures keep your tests DRY by providing consistent states, and they can be reused across tests.

from vipentium import TestCase, fixture

@fixture(scope="function")
def simple_list():
    """Provides a simple list for testing."""
    return [1, 2, 3]

class TestList(TestCase):
    def test_list_length(self, simple_list):
        self.assert_equal(len(simple_list), 3)

5. Running Your Tests ๐Ÿƒโ€โ™‚๏ธ

After writing your tests, run them using VIPENTIUMโ€™s CLI. The tool automatically discovers files starting with test_, injects fixtures, and processes decorators.

Recommended Command:

vipentium-runner test_example.py

Alternative Command:

python -m vipentium.vipentium_runner test_example.py

The console output will display the status of each test, their execution time, and a final summary.

6. Reporting ๐Ÿ“Š

VIPENTIUM can generate detailed reports for your tests.

JSON Reporting:

vipentium-runner test_example.py --report-json report.json

HTML Reporting:

vipentium-runner test_example.py --report-html report.html

JSON reports are ideal for CI/CD pipelines; HTML reports are great for sharing with your team.

7. Extending with Plugins ๐Ÿ”Œ

Extend VIPENTIUM by creating plugins to customize test behavior, add logging, send notifications, or integrate with other tools.

  1. Define a Plugin Class: Inherit from Plugin.
  2. Override Hook Methods: Customize actions such as before/after tests.
  3. Register the Plugin: Use register_plugin().
class CustomLoggerPlugin(Plugin):
    """
    A custom plugin that logs messages at various stages of the test execution.
    It implements the following methods:
      - on_start_suite: Called when the test suite starts.
      - before_test: Called right before each test is executed.
      - after_test: Called after a test completes.
      - on_end_suite: Called when the test suite completes.
    """
    def on_start_suite(self):
        print("CUSTOM PLUGIN: Starting test suite!")

    def before_test(self, test_name, test_class, method, params):
        print(f"CUSTOM PLUGIN: About to run test: {test_name}")

    def after_test(self, test_name, test_class, method, params, success, message, duration):
        status = "PASS" if success else "FAIL"
        print(f"CUSTOM PLUGIN: Finished test: {test_name} - {status} in {duration:.2f} seconds")

    def on_end_suite(self, summary):
        print("CUSTOM PLUGIN: Test suite finished.")
        print("CUSTOM PLUGIN: Summary:", summary)

# Load the plugin before running tests.
register_plugin(CustomLoggerPlugin())

8. Example Usage ๐Ÿ’ก

The example below demonstrates how to combine fixtures, decorators, and markers into a complete test suite including tests for math functions and list manipulations.

from vipentium import TestCase, Plugin, parameters, mark, fixture, timeout, retry, register_plugin
import time

# ------------------------------------------------------------------------------
# Custom Plugin Definition
# ------------------------------------------------------------------------------

class CustomLoggerPlugin(Plugin):
    """
    A custom plugin that logs messages at various stages of the test execution.
    It implements the following methods:
      - on_start_suite: Called when the test suite starts.
      - before_test: Called right before each test is executed.
      - after_test: Called after a test completes.
      - on_end_suite: Called when the test suite completes.
    """
    def on_start_suite(self):
        print("CUSTOM PLUGIN: Starting test suite!")

    def before_test(self, test_name, test_class, method, params):
        print(f"CUSTOM PLUGIN: About to run test: {test_name}")

    def after_test(self, test_name, test_class, method, params, success, message, duration):
        status = "PASS" if success else "FAIL"
        print(f"CUSTOM PLUGIN: Finished test: {test_name} - {status} in {duration:.2f} seconds")

    def on_end_suite(self, summary):
        print("CUSTOM PLUGIN: Test suite finished.")
        print("CUSTOM PLUGIN: Summary:", summary)


register_plugin(CustomLoggerPlugin())

# ------------------------------------------------------------------------------
# Fixtures
# ------------------------------------------------------------------------------

@fixture(scope="function")
def simple_list():
    """
    Function-scoped fixture that returns a simple mutable list.
    Each test that requires this fixture gets its own fresh copy.
    """
    return [1, 2, 3]

@fixture(scope="session")
def shared_resource():
    """
    Session-scoped fixture that returns a shared resource.
    This fixture is set up only once per entire test session.
    """
    print("\nSetting up shared resource...")
    return {"message": "Hello from shared resource"}

# ------------------------------------------------------------------------------
# Test Classes and Test Cases
# ------------------------------------------------------------------------------

class TestBasicOperations(TestCase):
    """Tests for basic operations; each test is marked individually with 'basic'."""
    
    @mark("basic")
    def test_addition(self):
        self.assert_equal(2 + 2, 4)

    @mark("basic")
    def test_string_concat(self):
        self.assert_equal("hello" + "world", "helloworld")

    @mark("basic")
    def test_list_length(self, simple_list):
        self.assert_equal(len(simple_list), 3)

    @mark("basic")
    def test_shared_message(self, shared_resource):
        self.assert_equal(shared_resource["message"], "Hello from shared resource")

class TestMathFunctions(TestCase):
    """Tests for math functions; each test is marked individually with 'math'."""
    
    @parameters((5, 2, 7), (10, -3, 7), (0, 0, 0))
    @mark("math")
    def test_add_parameterized(self, a, b, expected):
        self.assert_equal(a + b, expected)

    @mark("math")
    def test_division(self):
        self.assert_equal(10 / 2, 5)

    @mark("math")
    def test_float_equality(self):
        self.assert_equal(3.14, 3.14)

class TestListManipulation(TestCase):
    """Tests for list manipulation; each test is marked individually with 'list_operations'."""
    
    @mark("list_operations")
    def test_append(self, simple_list):
        simple_list.append(4)
        self.assert_equal(simple_list, [1, 2, 3, 4])

    @mark("list_operations")
    def test_pop(self, simple_list):
        popped_item = simple_list.pop()
        self.assert_equal(popped_item, 3)
        self.assert_equal(simple_list, [1, 2])

    @mark("list_operations")
    def test_contains(self, simple_list):
        self.assert_equal(2 in simple_list, True)
        self.assert_equal(5 in simple_list, False)

class TestTimeoutExample(TestCase):
    """
    Test demonstrating the timeout feature.
    This test is individually marked with 'advanced' and 'timeout',
    and it intentionally exceeds the allowed duration.
    """
    @mark("advanced")
    @mark("timeout")
    @timeout(1)  # The test must complete in 1 second.
    def test_sleep_timeout(self):
        time.sleep(2)
        self.assert_equal(True, True)

class TestRetryMechanism(TestCase):
    """
    Test demonstrating the retry mechanism.
    It is marked individually with 'retry' and designed to pass after a retry.
    """
    retry_counter = 0

    @mark("retry")
    @retry(2)    # Retry up to 2 times upon failure.
    @timeout(2)  # The test must complete within 2 seconds overall.
    def test_retry_example(self):
        TestRetryMechanism.retry_counter += 1
        if TestRetryMechanism.retry_counter < 2:
            self.assert_equal(1, 2, "Intentional failure to trigger retry")
        else:
            self.assert_equal(1, 1)

# ------------------------------------------------------------------------------
# Test Runner Entry Point
# ------------------------------------------------------------------------------

if __name__ == "__main__":
    import sys
    from vipentium.starter.startz import *
    sys.exit(0)
  

To run these tests, simply execute:

vipentium-runner test_example.py

9. Conclusion ๐ŸŽ‰

VIPENTIUM simplifies writing, running, and extending tests. By following these detailed steps, your test files are automatically discovered, structured, and enriched with powerful featuresโ€”ensuring consistent and maintainable tests.

You are now ready to build, run, and extend your test suite with VIPENTIUM. Happy testing and happy coding! ๐Ÿค“๐Ÿ‘