Testing and Debugging
Configuring the Debugger
Neo3-Boa is compatible with the Neo Debugger. Debugger launch configuration example:
{
//Launch configuration example for Neo3-Boa.
//Make sure you compile your smart-contract before you try to debug it.
"version": "0.2.0",
"configurations": [
{
"name": "example.nef",
"type": "neo-contract",
"request": "launch",
"program": "${workspaceFolder}\\example.nef",
"operation": "main",
"args": [],
"storage": [],
"runtime": {
"witnesses": {
"check-result": true
}
}
}
]
}
It’s necessary to generate the nef debugger info file to use Neo Debugger.
Using CLI
$ neo3-boa compile path/to/your/file.py -d|--debug
Using Python Script
from boa3.boa3 import Boa3
Boa3.compile_and_save('path/to/your/file.py', debug=True)
Neo Test Runner
Downloading
Install Neo-Express and Neo Test Runner.
Testing
Before writing your tests, make sure you have a Neo-Express network for local tests.
If you do not yet have a local network, open a terminal and run neoxp create
.
Please refer to Neo-Express documentation
for more details of how to configure your local network.
Create a Python Script, import the NeoTestRunner class, and define a function to test your smart contract. In this function you’ll need a NeoTestRunner object, which takes the path of your Neo-Express network configuration file as an argument to set up the test environment.
You’ll have to call the method call_contract()
to interact with your smart contract. Its parameters are the path of
the compiled smart contract, the smart contract’s method, and the arguments if necessary.
This call doesn’t return the result directly, but includes it in a queue of invocations. To execute all the invocations
set up, call the method execute()
. Then assert the result of your invoke to see if it’s correct.
Note that invoke.result
won’t be set if the execution fails, so you should also assert if runner.vm_state
is valid
for your test case.
Your Python Script should look something like this:
from boa3.builtin.interop.blockchain.vmstate import VMState
from boa3_test.test_drive.testrunner.neo_test_runner import NeoTestRunner
def test_hello_world_main():
neoxp_config_file = '{path-to-neo-express-config-file}'
project_root_folder = '{path-to-project-root-folder}'
path = f'{project_root_folder}/boa3_test/examples/hello_world.nef'
runner = NeoTestRunner(neoxp_config_file)
invoke = runner.call_contract(path, 'main')
runner.execute()
assert runner.vm_state is VMState.HALT
assert invoke.result is None
Alternatively you can change the value of env.NEO_EXPRESS_INSTANCE_DIRECTORY
to the path of your .neo-express
data file:
from boa3.builtin.interop.blockchain.vmstate import VMState
from boa3_test.test_drive.testrunner.neo_test_runner import NeoTestRunner
from boa3.internal import env
env.NEO_EXPRESS_INSTANCE_DIRECTORY = '{path-to-neo-express-config-file}'
def test_hello_world_main():
root_folder = '{path-to-project-root-folder}'
path = f'{root_folder}/boa3_test/examples/hello_world.nef'
runner = NeoTestRunner() # the default path to the Neo-Express is the one on env.NEO_EXPRESS_INSTANCE_DIRECTORY
invoke = runner.call_contract(path, 'main')
runner.execute()
assert runner.vm_state is VMState.HALT
assert invoke.result is None