EOS 智能合約測試框架 eosfactory

最近筆者在寫完智能合約,想要寫一些測試案例,可是 eos 自帶的單元測試用起來不是很方便。日常用 cleos 測試的體驗感其實挺不錯,因此筆者設想有一種是用 cleos 做爲與 nodeos 端互動的測試框架,去 github 上找了找, 還真有。https://github.com/tokenika/e... 。 基本能知足大體的需求,但還不是很完善,例如筆者須要用到其餘索引,不僅是主鍵索引,可是該測試框架不支持,因此作些了改動,已經提交PR, 還有其餘一些小細節,讀者能夠考慮從我先使用我改動的版本: https://github.com/superoneio...node

安裝步驟
1.首先 裝完 python 3.6 版本的環境,git clone url, 將代碼拉取到本地。
2.執行 install.sh 腳本。填入 eosio 源碼目錄,以及智能合約目錄就好了。
本章以 dice 合約做爲例子來介紹 eosfactory 在本地測試環境的使用。

eosfactory 是基於 python 的 EOS 智能合約測試框架,它的實現方式其實就是 python 去調用 cleos 來與 nodeos 端進行交互,利用 python 的 unittest 單元測試工具來作測試,unittest 的使用讀者能夠自行去了解哈,這裏筆者就不贅述了。python

測試智能合約所須要的幾個基本功能:建立帳號,執行action, 查看數據表。下面咱們經過 dice 合約的單元測試代碼來了解這一系列操做。git

進行本地環境的初始化操做
# 重置鏈,即 delete-all-blocks
reset()
# 首先獲取 eosio 帳號的,這裏的 master 指向的就是 eosio 帳號。
 create_master_account("master」);
system_contract_path = "/Users/wuyuan/Documents/study/eos/build/contracts/「
# 建立系統帳號
create_account("et",master,"eosio.token")
create_account("em",master,"eosio.msig")
create_account("er",master,"eosio.ram")
create_account("erf",master,"eosio.ramfee")
create_account("es",master,"eosio.stake」)
# 部署 token 和 msig 合約
et_contract = Contract(et,system_contract_path + "eosio.token","eosio.token.abi","eosio.token.wasm")
et_contract.deploy();
em_contract = Contract(em,system_contract_path + "eosio.msig","eosio.msig.abi","eosio.msig.wasm")
        em_contract.deploy();
// 建立 EOS 代幣
et.push_action("create",{"issuer":"eosio","maximum_supply":"100000000000.0000 EOS"},permission=(et,Permission.ACTIVE))
et.push_action("issue",{"to":"eosio","quantity":"100000000.0000 EOS","memo":"haha"},permission=(master,Permission.ACTIVE))

# 部署系統合約
contract = Contract(master,"/Users/wuyuan/Documents/study/eos/build/contracts/eosio.system","eosio.system.abi","eosio.system.wasm」)
contract.deploy()

# 建立 dice 合約須要的帳號
create_account("dice",master,"dice","","","1000","1000",None,"10000")
create_account("alice",master,"alice","","","1000","1000",None,"1000")
create_account("bob",master,"bob","","","1000","1000",None,"1000")

# 賦予代幣
et.push_action("transfer",{"from":"eosio","to":"alice","quantity":"10000.0000 EOS","memo":"hi"},permission=("eosio",Permission.ACTIVE))
et.push_action("transfer",{"from":"eosio","to":"bob","quantity":"10000.0000 EOS","memo":"hi"},permission=("eosio",Permission.ACTIVE))
環境的初始化已經完成了,接下來部署 dice 合約以及進行遊戲操做。
# init dice contract
self.deploy_contract()

# 將 alice 和 bob 帳號的 eosio.code 權限付給 dice 帳號
self.updateauth(alice.name)
self.updateauth(bob.name)

# 充值遊戲幣
self.deposit(alice.name,"100.0000 EOS")
self.deposit(bob.name,"100.0000 EOS」)

# 獲取 account 表信息。
account = self.get_account()
print(account)

# 開始遊戲
source1 = "28349b1d4bcdc9905e4ef9719019e55743c84efa0c5e9a0b077f0b54fcd84905"
commitment1 = "d533f24d6f28ddcef3f066474f7b8355383e485681ba8e793e037f5cf36e4883"
source2 = "15fe76d25e124b08feb835f12e00a879bd15666a33786e64b655891fba7d6c12"
commitment2 = "50ed53fcdaf27f88d51ea4e835b1055efe779bb87e6cfdff47d28c88ffb27129"
self.offerbet("3.0000 EOS",alice.name,commitment1)
offer = self.get_offer_by_commitment(commitment1)
print(offer)

self.offerbet("3.0000 EOS",bob.name,commitment2)
offer2 = self.get_offer_by_commitment(commitment2)
print(offer2)

game = self.get_game_by_id(offer2["gameid"])
print(game)

self.reveal(commitment1,source1,alice.name)
game = self.get_game_by_id(offer2["gameid"])
print(game)

self.reveal(commitment2,source2,bob.name)

# 查看 account 表信息,看看是否贏了錢
account = self.get_account()
print(account)

# show global value
print(self.get_global_dice())
OK ,上面說了獲取表信息,接下來介紹如何獲取表數據
# account_object 帳戶類,無需傳入, table_name 表名, scope , binary 是否顯示二進制數據, limit 篩選條數, key 目前無做用, lower 篩選下限,upper 篩選上限, index 索引名 默認主鍵, key_type 索引類型
table(account_object, table_name, scope="", binary=False, limit=10, key="", lower="", upper="",index="first",key_type="i64")
1.直接獲取, table( [ 表名 ],[ scope ],[ 條數,默認爲10 ])
def get_account(self):
   try:
       account = dice.table("account」,dice.name,100).json["rows"]
       return account
   except errors.Error as e:
       print("except errors.Error as e: ",e)
   return None

2.經過 lower_bound 和主鍵索引篩選
def get_offer_by_id(self, id):
    try:
        offer = dice.table("offer",dice.name,False,1,"",id).json["rows"]
        if len(offer) != 0:
            self.assertEqual( offer[0]["id"] , id, "not this game id")
            return offer[0]
    except errors.Error as e:
        print("except errors.Error as e: ",e)
    return None

3.經過 lower_bound 和 非主鍵索引篩選
def get_offer_by_commitment(self, commitment):
    try:
        # ter 表示 第三個索引 索引類型爲 sha256
        offer = dice.table("offer",dice.name,False,1,"",commitment,"","ter","sha256").json["rows"]
        if len(offer) != 0:
        self.assertEqual( offer[0]["commitment"] , commitment, "not this game id")
        return offer[0]
    except errors.Error as e:
        print("except errors.Error as e: ",e)
    return None

從代碼咱們能夠看出,其實就是跟咱們平時用 cleos 差很少,只是它將其封裝起來供咱們調用,這樣能夠節約咱們很多時間,也方便咱們調試,寫自動化測試腳本。github

文中的例子: https://github.com/superoneio...json

你們若是之後遇到更好用的測試框架,請務必介紹給我哈。框架

轉載請註明來源: https://eos.live/detail/17418工具

相關文章
相關標籤/搜索