Skip to main content
Version: Next

Testing Framework Integration

This guide covers basic testing configuration for Merobox and integration with Python testing frameworks.

Basic Testing Setup

Configure Merobox for testing scenarios:

Basic Testing Setup

# conftest.py
import pytest
import subprocess
import time

@pytest.fixture(scope="session")
def merobox_cluster():
"""Basic Merobox cluster for testing."""
# Start nodes
subprocess.run(['merobox', 'run', '--count', '2'])
time.sleep(10) # Wait for nodes to start

yield

# Cleanup
subprocess.run(['merobox', 'stop', '--all'])

@pytest.fixture(scope="function")
def test_environment():
"""Test environment for each test."""
# Start fresh nodes for each test
subprocess.run(['merobox', 'run', '--count', '1'])
time.sleep(5)

yield

# Cleanup
subprocess.run(['merobox', 'stop', '--all'])

Basic Test Examples

# test_basic.py
import pytest
import subprocess

def test_merobox_health(merobox_cluster):
"""Test that Merobox nodes are healthy."""
result = subprocess.run(['merobox', 'health'], capture_output=True, text=True)
assert result.returncode == 0
assert "healthy" in result.stdout.lower()

def test_merobox_list(merobox_cluster):
"""Test that we can list running nodes."""
result = subprocess.run(['merobox', 'list'], capture_output=True, text=True)
assert result.returncode == 0
assert "calimero-node" in result.stdout

def test_workflow_execution(test_environment):
"""Test basic workflow execution."""
# Create a simple workflow
workflow_content = """
description: Test workflow
name: Test Workflow
nodes:
chain_id: testnet-1
count: 1
image: ghcr.io/calimero-network/merod:edge
steps:
- name: Test Step
type: script
script: echo "Hello from test workflow"
stop_all_nodes: true
"""

with open("test_workflow.yml", "w") as f:
f.write(workflow_content)

try:
result = subprocess.run(
['merobox', 'bootstrap', 'run', 'test_workflow.yml'],
capture_output=True,
text=True
)
assert result.returncode == 0
finally:
import os
os.remove("test_workflow.yml")

Test Helper Classes

Basic Test Helper

# test_helpers.py
import subprocess
import time
import tempfile
import os

class MeroboxTestHelper:
def __init__(self):
self.nodes = []
self.workflow_files = []

def start_nodes(self, count=2):
"""Start Merobox nodes for testing."""
result = subprocess.run(
['merobox', 'run', '--count', str(count)],
capture_output=True,
text=True
)
if result.returncode == 0:
self.nodes = [f"calimero-node-{i+1}" for i in range(count)]
time.sleep(10) # Wait for nodes to start
return True
return False

def stop_nodes(self):
"""Stop all test nodes."""
subprocess.run(['merobox', 'stop', '--all'])
self.nodes = []

def check_health(self):
"""Check health of all nodes."""
result = subprocess.run(
['merobox', 'health'],
capture_output=True,
text=True
)
return result.returncode == 0

def create_workflow(self, workflow_config):
"""Create a temporary workflow file."""
with tempfile.NamedTemporaryFile(mode='w', suffix='.yml', delete=False) as f:
import yaml
yaml.dump(workflow_config, f)
self.workflow_files.append(f.name)
return f.name

def run_workflow(self, workflow_file):
"""Run a Merobox workflow."""
result = subprocess.run(
['merobox', 'bootstrap', 'run', workflow_file],
capture_output=True,
text=True
)
return result

def cleanup(self):
"""Clean up all resources."""
self.stop_nodes()
for file in self.workflow_files:
if os.path.exists(file):
os.unlink(file)
self.workflow_files = []

# Usage in tests
@pytest.fixture
def merobox_helper():
helper = MeroboxTestHelper()
yield helper
helper.cleanup()

def test_with_helper(merobox_helper):
"""Test using the helper class."""
assert merobox_helper.start_nodes(2)
assert merobox_helper.check_health()

# Create and run a workflow
workflow_config = {
'description': 'Test workflow',
'name': 'Test Workflow',
'nodes': {
'chain_id': 'testnet-1',
'count': 1,
'image': 'ghcr.io/calimero-network/merod:edge'
},
'steps': [
{
'name': 'Test Step',
'type': 'script',
'script': 'echo "Hello from test"'
}
],
'stop_all_nodes': True
}

workflow_file = merobox_helper.create_workflow(workflow_config)
result = merobox_helper.run_workflow(workflow_file)
assert result.returncode == 0

Best Practices

Error Handling

# Always handle errors properly
def safe_merobox_command(command):
"""Run Merobox command with proper error handling."""
try:
result = subprocess.run(
['merobox'] + command,
capture_output=True,
text=True,
check=True
)
return result.stdout
except subprocess.CalledProcessError as e:
print(f"Command failed: {e}")
print(f"Error output: {e.stderr}")
return None
except FileNotFoundError:
print("Merobox not found. Please install it first.")
return None

Resource Cleanup

# Always clean up resources
def test_with_cleanup():
"""Test with proper cleanup."""
try:
# Start nodes
subprocess.run(['merobox', 'run', '--count', '2'])

# Run tests
result = subprocess.run(['merobox', 'health'])
assert result.returncode == 0

finally:
# Always cleanup
subprocess.run(['merobox', 'stop', '--all'])

Test Isolation

# Use different prefixes for different tests
def test_isolated():
"""Test with isolated environment."""
try:
# Start nodes with unique prefix
subprocess.run(['merobox', 'run', '--count', '1', '--prefix', 'test-isolated'])

# Run test
result = subprocess.run(['merobox', 'health'])
assert result.returncode == 0

finally:
# Cleanup
subprocess.run(['merobox', 'stop', '--all'])

Running Tests

Basic Test Execution

# Run all tests
pytest

# Run specific test file
pytest test_merobox.py

# Run with verbose output
pytest -v

# Run with coverage
pytest --cov=my_app

Continuous Integration

# .github/workflows/test.yml
name: Test with Merobox

on: [push, pull_request]

jobs:
test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.9'

- name: Install dependencies
run: |
pip install -r requirements.txt
pip install merobox

- name: Run tests
run: |
pytest tests/ -v

Next Steps

Now that you understand basic testing integration:

Was this page helpful?
Need some help? Check Support page