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:
- Node Management - Complete node management guide
- Workflows - Workflow system and automation
- Environment Variables - Configuration options
- Troubleshooting - Common issues and solutions
Was this page helpful?