GenLayer Testing Suite
Project description
GenLayer Testing Suite
About
The GenLayer Testing Suite is a powerful testing framework designed to streamline the development and validation of intelligent contracts within the GenLayer ecosystem. Built on top of pytest and genlayer-py, this suite provides developers with a comprehensive set of tools for deploying, interacting with, and testing intelligent contracts efficiently in a simulated GenLayer environment.
🚀 Quick Start
Installation
pip install genlayer-test
Basic Usage
from gltest import get_contract_factory, default_account, create_account
from gltest.assertions import tx_execution_succeeded
factory = get_contract_factory("MyContract")
# Deploy a contract with default account
contract = factory.deploy() # This will be deployed with default_account
assert contract.account == default_account
# Deploy a contract with other account
other_account = create_account()
contract = factory.deploy(account=other_account)
assert contract.account == other_account
# Interact with the contract
result = contract.get_value() # Read method
tx_receipt = contract.set_value(args=["new_value"]) # Write method
assert tx_execution_succeeded(tx_receipt)
📋 Table of Contents
- About
- Quick Start
- Prerequisites
- Installation and Usage
- Key Features
- Examples
- Best Practices
- Troubleshooting
- Contributing
- License
- Support
Prerequisites
Before installing GenLayer Testing Suite, ensure you have the following prerequisites installed:
- Python (>=3.12)
- GenLayer Studio (Docker deployment)
- pip (Python package installer)
Installation and Usage
Installation Options
- Install from PyPI (recommended):
$ pip install genlayer-test
- Install from source:
$ git clone https://github.com/yeagerai/genlayer-testing-suite
$ cd genlayer-testing-suite
$ pip install -e .
Running Tests
- Run all tests:
$ gltest
- Run specific test file:
$ gltest tests/test_mycontract.py
- Run tests with specific markers:
$ gltest -m "integration"
- Run tests with verbose output:
$ gltest -v
- Run tests in specific contracts directories, by default
<path_to_contracts>is set tocontracts/
$ gltest --contracts-dir <path_to_contracts>
🚀 Key Features
- Pytest Integration – Extends pytest to support intelligent contract testing, making it familiar and easy to adopt.
- Account & Transaction Management – Create, fund, and track accounts and transactions within the GenLayer Simulator.
- Contract Deployment & Interaction – Deploy contracts, call methods, and monitor events seamlessly.
- CLI Compatibility – Run tests directly from the command line, ensuring smooth integration with the GenLayer CLI.
- State Injection & Consensus Simulation – Modify contract states dynamically and simulate consensus scenarios for advanced testing.
- Prompt Testing & Statistical Analysis – Evaluate and statistically test prompts for AI-driven contract execution.
- Scalability to Security & Audit Tools – Designed to extend into security testing and smart contract auditing.
📚 Examples
Project Structure
Before diving into the examples, let's understand the basic project structure:
genlayer-example/
├── contracts/ # Contract definitions
│ └── storage.gpy # Example storage contract
└── test/ # Test files
└── test_contract.py # Contract test cases
Storage Contract Example
Let's examine a simple Storage contract that demonstrates basic read and write operations:
# { "Depends": "py-genlayer:test" }
from genlayer import *
# contract class
class Storage(gl.Contract):
# State variable to store data
storage: str
# Constructor - initializes the contract state
def __init__(self, initial_storage: str):
self.storage = initial_storage
# Read method - marked with @gl.public.view decorator
# Returns the current storage value
@gl.public.view
def get_storage(self) -> str:
return self.storage
# Write method - marked with @gl.public.write decorator
# Updates the storage value
@gl.public.write
def update_storage(self, new_storage: str) -> None:
self.storage = new_storage
Key features demonstrated in this contract:
- State variable declaration
- Constructor with initialization
- Read-only method with
@gl.public.viewdecorator - State-modifying method with
@gl.public.writedecorator - Type hints for better code clarity
Contract Deployment
Here's how to deploy the Storage contract:
from gltest import get_contract_factory, default_account
def test_deployment():
# Get the contract factory for your contract
# it will search in the contracts directory
factory = get_contract_factory("Storage")
# Deploy the contract with constructor arguments
contract = factory.deploy(
args=["initial_value"], # Constructor arguments
account=default_account, # Account to deploy from
consensus_max_rotations=3, # Optional: max consensus rotations
leader_only=False, # Optional: whether to run only on leader
)
# Contract is now deployed and ready to use
assert contract.address is not None
Read Methods
Reading from the contract is straightforward:
from gltest import get_contract_factory, default_account
def test_read_methods():
# Get the contract factory and deploy the contract
factory = get_contract_factory("Storage")
contract = factory.deploy(account=default_account)
# Call a read-only method
result = contract.get_value(args=[])
# Assert the result matches the initial value
assert result == "initial_value"
Write Methods
Writing to the contract requires transaction handling:
from gltest import get_contract_factory
from gltest.assertions import tx_execution_succeeded
def test_write_methods():
# Get the contract factory and deploy the contract
factory = get_contract_factory("Storage")
contract = factory.deploy()
# Call a write method with arguments
tx_receipt = contract.update_storage(
args=["new_value"], # Method arguments
value=0, # Optional: amount of native currency to send
consensus_max_rotations=3, # Optional: max consensus rotations
leader_only=False, # Optional: whether to run only on leader
wait_interval=1, # Optional: seconds between status checks
wait_retries=10, # Optional: max number of retries
)
# Verify the transaction was successful
assert tx_execution_succeeded(tx_receipt)
# Verify the value was updated
assert contract.get_storage() == "new_value"
📝 Best Practices
-
Test Organization
- Keep tests in a dedicated
testsdirectory - Use descriptive test names
- Group related tests using pytest markers
- Keep tests in a dedicated
-
Contract Deployment
- Always verify deployment success
- Use appropriate consensus parameters
- Handle deployment errors gracefully
-
Transaction Handling
- Always wait for transaction finalization
- Verify transaction status
- Handle transaction failures appropriately
-
State Management
- Reset state between tests
- Use fixtures for common setup
- Avoid test dependencies
🔧 Troubleshooting
Common Issues
-
Deployment Failures
- Problem: Contract deployment fails due to various reasons like insufficient funds, invalid contract code, or network issues.
- Solution: Implement proper error handling
try: contract = factory.deploy(args=["initial_value"]) except DeploymentError as e: print(f"Deployment failed: {e}")
-
Transaction Timeouts
- Problem: Transactions take too long to complete or fail due to network congestion or consensus delays.
- Solution: Adjust timeout parameters and implement retry logic:
tx_receipt = contract.set_value( args=["new_value"], wait_interval=2, # Increase wait interval between status checks wait_retries=20, # Increase number of retry attempts )
-
Consensus Issues
- Problem: Transactions fail due to consensus-related problems like network partitions or slow consensus.
- Solution: Adjust consensus parameters and try different modes:
# Try with increased consensus parameters contract = factory.deploy( consensus_max_rotations=5, # Increase number of consensus rotations leader_only=True, # Try leader-only mode for faster execution ) # For critical operations, use more conservative settings contract = factory.deploy( consensus_max_rotations=10, # More rotations for better reliability leader_only=False, # Full consensus for better security wait_interval=3, # Longer wait between checks wait_retries=30 # More retries for consensus )
-
Contracts Directory Issues
- Problem:
get_contract_factorycan't find your contract files. - Solution: Ensure proper directory structure and configuration:
# Default structure your_project/ ├── contracts/ # Default contracts directory │ └── my_contract.gpy # Your contract file └── tests/ └── test_contract.py # Your test file # If using a different directory structure gltest --contracts-dir /path/to/your/contracts
- Problem:
-
Contract File Naming and Structure
- Problem: Contracts aren't being recognized or loaded properly.
- Solution: Follow the correct naming and structure conventions:
# Correct file: contracts/my_contract.gpy # Correct structure: from genlayer import * class MyContract(gl.Contract): # Contract code here pass # Incorrect file: contracts/my_contract.py # Wrong extension # Incorrect structure: class MyContract: # Missing gl.Contract inheritance pass
-
Environment Setup Issues
- Problem: Tests fail due to missing or incorrect environment setup.
- Solution: Verify your environment:
# Check Python version python --version # Should be >= 3.8 # Check GenLayer Studio status docker ps # Should show GenLayer Studio running # Verify package installation pip list | grep genlayer-test # Should show installed version
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create your feature branch
- Commit your changes
- Push to the branch
- Create a Pull Request
📄 License
This project is licensed under the MIT License - see the LICENSE file for details.
💬 Support
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file genlayer_test-0.1.0b5.tar.gz.
File metadata
- Download URL: genlayer_test-0.1.0b5.tar.gz
- Upload date:
- Size: 12.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
65a7e94a2e83f3c4c75959c7a26b102ed7376905f574e7e024c715f0b91b5acc
|
|
| MD5 |
3c2c92d3c471a7aebac3ec5e673e2c0d
|
|
| BLAKE2b-256 |
98860bc7c1ea9039351a850a6bbd3b845e2e381378c1a0987d4b185cf7d50fe5
|
File details
Details for the file genlayer_test-0.1.0b5-py3-none-any.whl.
File metadata
- Download URL: genlayer_test-0.1.0b5-py3-none-any.whl
- Upload date:
- Size: 16.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
713ca1646f63d1031df9dd4267b189addad6d1815a5bcdd706fda7b14e5cf97e
|
|
| MD5 |
95f44fa2ab624b49c756882fb7f124b7
|
|
| BLAKE2b-256 |
b69257ed55c37e703be5ec3774fa28d06c7e654bc24b58f50f20a9a72ec2dce7
|