ape icon indicating copy to clipboard operation
ape copied to clipboard

Add `test` account for running scripts locally

Open fubuloubu opened this issue 2 years ago • 5 comments

Overview

It is handy to be able to test your scripts to run in a local or mainnet-fork context. However, in this environment you may not have access to an aliased account with any balance to be able to run your script. Thankfully, most local/fork mode providers come with a pre-set list of accounts that are pre-funded for any actions they may take, and additionally they do not require any interaction in order for them to perform signing actions.

However, these test accounts are not directly referable via ape.cli.account_option, meaning they cannot be used for testing scripts.

NOTE: This reminds me of an issue that @PatrickAlphaC raised about being difficult to test scripts because his preferred account alias did not have a balance in his local testing environment. Feel free to give us your feedback on this issue!

Specification

Add an alias named "TEST" to ape.cli.account_option that is only available in a local or fork mode environment for use in script testing. Additionally, add documentation to the scripts userguide to help people understand that this is the recommended way to test scripts in a local and/or mainnet-fork environment prior to using them live.

$ ape run deploy --account TEST 0x1C277bD41A276F87D3E92bccD50c7364aa2FFc69
SUCCESS: Contract 'SuperSig' deployed to: 0x274b028b03A250cA03644E6c578D81f019eE1323

Dependencies

n/a

fubuloubu avatar Jul 03 '22 19:07 fubuloubu

thoughts on doing --account t0 / --account t1 etc to refer to a specific test account by index?

this way, if you deploy using t6 or something, you can invoke another script with the correct account.

antazoey avatar Jul 04 '22 20:07 antazoey

or even --account 0 / --account 1 etc

antazoey avatar Jul 04 '22 20:07 antazoey

or even --account 0 / --account 1 etc

I think this works already, but you just get whatever your first account is, depending on the situation. It's not consistent behavior.

fubuloubu avatar Jul 05 '22 03:07 fubuloubu

thoughts on doing --account t0 / --account t1 etc to refer to a specific test account by index?

this way, if you deploy using t6 or something, you can invoke another script with the correct account.

I think you can access them from other aliases, but that wasn't the point.

The idea is to have one, idiomatic way to handle testing scripts by executing locally using a specific account

fubuloubu avatar Jul 05 '22 03:07 fubuloubu

Here is what I do for both brownie and ape, I create a file called helper_functions.py or something in the scripts folder, and add a function like this:

from ape import networks, accounts
LOCAL_CHAIN_NAME = "local"

def get_account(index=None, id=None):
    if index:
        return accounts[index]
    if id:
        return accounts.load(id)
    if networks.active_provider.network.name == LOCAL_CHAIN_NAME:
        return accounts.test_accounts[0]
    return accounts.load("default")

This way, my code is smart enough to switch accounts based on the network that I'm on, which I like a lot a lot a lot. I really don't like the idea of having to do:

ape run deploy --account XXX

or

ape test --account XXX

I think it should be smart enough with:

ape test

to pick the right account, and then optionally you can force it an account with --account XXX

And for ape, I'll just tell users to use a shitty private key as their default account (a "shitty private key" is a key with no real funds, only testnet funds).

Then, in my deploy & test scripts I can do:

from ape import project
from scripts.helper_functions import get_account

def deploy_my_contract():
    account = get_account()
    my_contract = account.deploy(project.MyContract)
    return my_contract

def main():
    deploy_my_contract()

My tests therefore, can reuse functions from my scripts:

from scripts.deploy.deploy_my_contract import deploy_my_contract
from ape import networks
from scripts.helper_functions import get_account

def test_deploy_my_contract():
    my_contract = deploy_my_contract()
    # Asserts...

We had some talk about adding the deploy_my_contract as fixtures in the conftest, which I agree makes sense, but I think it would make more sense that the tests use the same deploy scripts as the deploy scripts, otherwise, you might write amazing tests but deploy things differently! Optionally, you could use the deploy scripts as fixtures in conftest (probably the best of both worlds

In my notes I have this:

   # Maybe ape improvement?
    # from ape.cli import get_user_selected_account -> expand this to add test accounts

Seemed like @fubuloubu was interested in having get_user_selected_account have this built-in.

PatrickAlphaC avatar Jul 06 '22 00:07 PatrickAlphaC