title |
---|
How to write SCORE integration test |
This document explains how to write SCORE integration test using IconIntegrateTestBase
.
Understand how to write SCORE integration test
The SCORE integration test code works as follows.
- Deploy the SCORE to be tested
- Create an ICON JSON-RPC API request for the SCORE API you want to test
- If necessary, sign an ICON JSON-RPC API request
- Invoke an ICON JSON-RPC API request and get the result
- Check the result
You can create and sign an ICON JSON-RPC API request using the ICON Python SDK
# create key wallet
self._test = KeyWallet.create()
# Generates an instance of transaction for deploying SCORE.
transaction = DeployTransactionBuilder() \
.from_(self._test.get_address()) \
.to(to) \
.step_limit(100_000_000_000) \
.nid(3) \
.nonce(100) \
.content_type("application/zip") \
.content(gen_deploy_data_content(self.SCORE_PROJECT)) \
.build()
# Returns the signed transaction object having a signature
signed_transaction = SignedTransaction(transaction, self._test)
Every SCORE integration test class must inherit IconIntegrateTestBase
.
IconIntegrateTestBase class provides three functions
-
Support Python unittest
- You can write and run the test method with prefix 'test_'
- You can initialize and finalize the test by override setUp and tearDown method
-
Emulate ICON service for test
- Initialize ICON service and confirm genesis block
- Create accounts for test
- self._test1 : Account with 1,000,000 ICX
- self._wallet_array[] : 10 empty accounts in list
-
Provide API for SCORE integration test
- process_transaction() Invoke transaction and return transaction result
- process_call() Calls SCORE's external function which is read-only and returns result
You can get the source code with tbears init score_test ScoreTest
command.
from iconservice import *
TAG = 'ScoreTest'
class ScoreTest(IconScoreBase):
def __init__(self, db: IconScoreDatabase) -> None:
super().__init__(db)
def on_install(self) -> None:
super().on_install()
def on_update(self) -> None:
super().on_update()
@external(readonly=True)
def hello(self) -> str:
Logger.debug(f'Hello, world!', TAG)
return "Hello"
import os
from iconsdk.builder.transaction_builder import DeployTransactionBuilder
from iconsdk.builder.call_builder import CallBuilder
from iconsdk.libs.in_memory_zip import gen_deploy_data_content
from iconsdk.signed_transaction import SignedTransaction
from tbears.libs.icon_integrate_test import IconIntegrateTestBase, SCORE_INSTALL_ADDRESS
DIR_PATH = os.path.abspath(os.path.dirname(__file__))
class TestScoreTest(IconIntegrateTestBase):
TEST_HTTP_ENDPOINT_URI_V3 = "http://127.0.0.1:9000/api/v3"
SCORE_PROJECT= os.path.abspath(os.path.join(DIR_PATH, '..'))
def setUp(self):
super().setUp()
self.icon_service = None
# If you want to send request to network, uncomment next line and set self.TEST_HTTP_ENDPOINT_URI_V3
# self.icon_service = IconService(HTTPProvider(self.TEST_HTTP_ENDPOINT_URI_V3))
# deploy SCORE
self._score_address = self._deploy_score()['scoreAddress']
def _deploy_score(self, to: str = SCORE_INSTALL_ADDRESS) -> dict:
# Generates an instance of transaction for deploying SCORE.
transaction = DeployTransactionBuilder() \
.from_(self._test1.get_address()) \
.to(to) \
.step_limit(100_000_000_000) \
.nid(3) \
.nonce(100) \
.content_type("application/zip") \
.content(gen_deploy_data_content(self.SCORE_PROJECT)) \
.build()
# Returns the signed transaction object having a signature
signed_transaction = SignedTransaction(transaction, self._test1)
# process the transaction in local
tx_result = self._process_transaction(signed_transaction)
# check transaction result
self.assertTrue('status' in tx_result)
self.assertEqual(1, tx_result['status'])
self.assertTrue('scoreAddress' in tx_result)
return tx_result
def test_score_update(self):
# update SCORE
tx_result = self._deploy_score(self._score_address)
self.assertEqual(self._score_address, tx_result['scoreAddress'])
def test_call_hello(self):
# Generates a call instance using the CallBuilder
call = CallBuilder().from_(self._test1.get_address()) \
.to(self._score_address) \
.method("hello") \
.build()
# Sends the call request
response = self._process_call(call, self.icon_service)
# check call result
self.assertEqual("Hello", response)
$ tbears test score_test
..
----------------------------------------------------------------------
Ran 2 tests in 0.172s
OK