بنقرة واحدة
create-test-from-prod
Download state from a running trade executor and scaffold an acceptance test case
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Download state from a running trade executor and scaffold an acceptance test case
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
| name | create-test-from-prod |
| description | Download state from a running trade executor and scaffold an acceptance test case |
Download the state file from a running trade-executor instance and scaffold a pytest acceptance test module.
https://executor.example.com)my_new_test); will be normalised to snake_case and any leading test_ prefix is stripped for the directory nameRun these two curl commands to gather information about the running executor:
curl -s <url>/metadata | python -m json.tool
curl -s <url>/source
From the /metadata JSON response, extract:
name — strategy name (used in the test module docstring)on_chain_data.chain_id — blockchain chain ID; map to the appropriate environment variable name:
1 → JSON_RPC_ETHEREUM137 → JSON_RPC_POLYGON8453 → JSON_RPC_BASE42161 → JSON_RPC_ARBITRUM56 → JSON_RPC_BNB43114 → JSON_RPC_AVALANCHEon_chain_data.asset_management_mode — one of enzyme, hot_wallet, lagoon, etc.on_chain_data (include whichever are present):
vault → VAULT_ADDRESSgeneric_adapter → VAULT_ADAPTER_ADDRESSpayment_forwarder → VAULT_PAYMENT_FORWARDER_ADDRESSdeployment_block → VAULT_DEPLOYMENT_BLOCK_NUMBERCompare the source code from /source against local strategy files:
strategies/ and strategies/test_only/AskUserQuestion and ask them to select the correct one or provide a pathRecord whether the strategy is in strategies/ or strategies/test_only/ and its filename.
mkdir -p tests/mainnet_fork/<test_case_name>
curl -s <url>/state -o tests/mainnet_fork/<test_case_name>/state.json
Verify the download succeeded and the file is non-empty.
Create tests/mainnet_fork/<test_case_name>/test_<test_case_name>.py using the template below.
Fill all <PLACEHOLDER> values from the metadata and strategy identification steps. Only include vault-specific environment variables that are actually present in the metadata.
"""<Strategy name> acceptance test.
- Does <Chain name> mainnet fork
- Archive node needed
- State file downloaded from <url>
"""
import os.path
import secrets
from pathlib import Path
from unittest import mock
import pytest
from _pytest.fixtures import FixtureRequest
from eth_defi.provider.anvil import AnvilLaunch, launch_anvil
from tradeexecutor.cli.commands.app import app
from tradeexecutor.utils.hex import hexbytes_to_hex_str
pytestmark = pytest.mark.skipif(
not os.environ.get("<JSON_RPC_CHAIN>") or not os.environ.get("TRADING_STRATEGY_API_KEY"),
reason="Set <JSON_RPC_CHAIN> and TRADING_STRATEGY_API_KEY environment variables to run this test",
)
@pytest.fixture()
def anvil(request: FixtureRequest) -> AnvilLaunch:
"""Do <Chain name> mainnet fork."""
mainnet_rpc = os.environ["<JSON_RPC_CHAIN>"]
anvil = launch_anvil(mainnet_rpc)
try:
yield anvil
finally:
anvil.close()
@pytest.fixture()
def state_file() -> Path:
"""State file downloaded from production."""
p = Path(os.path.join(os.path.dirname(__file__), "state.json"))
assert p.exists(), f"{p} missing"
return p
@pytest.fixture()
def strategy_file() -> Path:
"""The strategy module for this executor."""
p = Path(os.path.join(
os.path.dirname(__file__), "..", "..", "..",
"strategies", "<strategies_or_test_only>", "<strategy_filename>.py",
))
assert p.exists(), f"{p.resolve()} missing"
return p
@pytest.fixture()
def environment(
anvil: AnvilLaunch,
state_file: Path,
strategy_file: Path,
persistent_test_client,
) -> dict:
"""Passed to init and start commands as environment variables."""
environment = {
"STRATEGY_FILE": strategy_file.as_posix(),
"PRIVATE_KEY": hexbytes_to_hex_str(secrets.token_bytes(32)),
"JSON_RPC_ANVIL": anvil.json_rpc_url,
"STATE_FILE": state_file.as_posix(),
"ASSET_MANAGEMENT_MODE": "<asset_management_mode>",
"UNIT_TESTING": "true",
"UNIT_TEST_FORCE_ANVIL": "true",
"LOG_LEVEL": "disabled",
"TRADING_STRATEGY_API_KEY": os.environ["TRADING_STRATEGY_API_KEY"],
"SKIP_SAVE": "true",
"CACHE_PATH": str(persistent_test_client.transport.cache_path),
}
return environment
def test_<test_case_name>(environment: dict):
"""<Description>."""
pass
If the metadata contains vault addresses, add them to the environment fixture dict. Common patterns:
Enzyme vaults (asset_management_mode: enzyme):
"VAULT_ADDRESS": "<vault>",
"VAULT_ADAPTER_ADDRESS": "<generic_adapter>",
"VAULT_PAYMENT_FORWARDER_ADDRESS": "<payment_forwarder>",
"VAULT_DEPLOYMENT_BLOCK_NUMBER": "<deployment_block>",
Lagoon vaults (asset_management_mode: lagoon):
"VAULT_ADDRESS": "<vault>",
"VAULT_ADAPTER_ADDRESS": "<generic_adapter>",
For other asset management modes, include whatever vault-related fields are present in on_chain_data.
tests/mainnet_fork/test_correct_interest_not_accrued.py, tests/mainnet_fork/test_correct_accouting_closed_position_has_ausdc.pytradeexecutor/webhook/api.py (routes: /state, /metadata, /source)persistent_test_client fixture: tests/conftest.pystrategies/ and strategies/test_only/persistent_test_client fixture is defined in tests/conftest.py and is available to all tests automaticallypass — the user will fill in the actual test logicstrategies/ (not test_only/), adjust the relative path in the strategy_file fixture accordingly (remove the test_only segment)