Write SCORE integration test
This document explains how to write SCORE integration test using IconIntegrateTestBase.

Purpose

Understand how to write SCORE integration test

Prerequisite

How to Write SCORE Integration Test Code

The SCORE integration test code works as follows.
    1.
    Deploy the SCORE to be tested
    2.
    Create an ICON JSON-RPC API request for the SCORE API you want to test
    3.
    If necessary, sign an ICON JSON-RPC API request
    4.
    Invoke an ICON JSON-RPC API request and get the result
    5.
    Check the result

Packages and modules

ICON Python SDK
You can create and sign an ICON JSON-RPC API request using the ICON Python SDK
1
# create key wallet
2
self._test = KeyWallet.create()
3
​
4
# Generates an instance of transaction for deploying SCORE.
5
transaction = DeployTransactionBuilder() \
6
.from_(self._test.get_address()) \
7
.to(to) \
8
.step_limit(100_000_000_000) \
9
.nid(3) \
10
.nonce(100) \
11
.content_type("application/zip") \
12
.content(gen_deploy_data_content(self.SCORE_PROJECT)) \
13
.build()
14
​
15
# Returns the signed transaction object having a signature
16
signed_transaction = SignedTransaction(transaction, self._test)
IconIntegrateTestBase in T-Bears
Every SCORE integration test class must inherit IconIntegrateTestBase. IconIntegrateTestBase class provides three functions
    1.
    Support Python unittest 1. You can write and run the test method with prefix 'test_' 2. You can initialize and finalize the test by override setUp and tearDown method
    2.
    Emulate ICON service for test 1. Initialize ICON service and confirm genesis block 2. Create accounts for test 1. self._test1 : Account with 1,000,000 ICX 2. self._wallet_array[] : 10 empty accounts in list
    3.
    Provide API for SCORE integration test 1. process_transaction() Invoke transaction and return transaction result 2. process_call() Calls SCORE's external function which is read-only and returns result

examples

You can get the source code with tbears init score_test ScoreTest command.
score_test.py
1
from iconservice import *
2
​
3
TAG = 'ScoreTest'
4
​
5
class ScoreTest(IconScoreBase):
6
​
7
def __init__(self, db: IconScoreDatabase) -> None:
8
super().__init__(db)
9
​
10
def on_install(self) -> None:
11
super().on_install()
12
​
13
def on_update(self) -> None:
14
super().on_update()
15
​
16
@external(readonly=True)
17
def hello(self) -> str:
18
Logger.debug(f'Hello, world!', TAG)
19
return "Hello"
score_tests/test_score_test.py
1
import os
2
​
3
from iconsdk.builder.transaction_builder import DeployTransactionBuilder
4
from iconsdk.builder.call_builder import CallBuilder
5
from iconsdk.libs.in_memory_zip import gen_deploy_data_content
6
from iconsdk.signed_transaction import SignedTransaction
7
​
8
from tbears.libs.icon_integrate_test import IconIntegrateTestBase, SCORE_INSTALL_ADDRESS
9
​
10
DIR_PATH = os.path.abspath(os.path.dirname(__file__))
11
​
12
​
13
class TestScoreTest(IconIntegrateTestBase):
14
TEST_HTTP_ENDPOINT_URI_V3 = "http://127.0.0.1:9000/api/v3"
15
SCORE_PROJECT= os.path.abspath(os.path.join(DIR_PATH, '..'))
16
​
17
def setUp(self):
18
super().setUp()
19
​
20
self.icon_service = None
21
# If you want to send request to network, uncomment next line and set self.TEST_HTTP_ENDPOINT_URI_V3
22
# self.icon_service = IconService(HTTPProvider(self.TEST_HTTP_ENDPOINT_URI_V3))
23
​
24
# deploy SCORE
25
self._score_address = self._deploy_score()['scoreAddress']
26
​
27
def _deploy_score(self, to: str = SCORE_INSTALL_ADDRESS) -> dict:
28
# Generates an instance of transaction for deploying SCORE.
29
transaction = DeployTransactionBuilder() \
30
.from_(self._test1.get_address()) \
31
.to(to) \
32
.step_limit(100_000_000_000) \
33
.nid(3) \
34
.nonce(100) \
35
.content_type("application/zip") \
36
.content(gen_deploy_data_content(self.SCORE_PROJECT)) \
37
.build()
38
​
39
# Returns the signed transaction object having a signature
40
signed_transaction = SignedTransaction(transaction, self._test1)
41
​
42
# process the transaction in local
43
tx_result = self._process_transaction(signed_transaction)
44
​
45
# check transaction result
46
self.assertTrue('status' in tx_result)
47
self.assertEqual(1, tx_result['status'])
48
self.assertTrue('scoreAddress' in tx_result)
49
​
50
return tx_result
51
​
52
def test_score_update(self):
53
# update SCORE
54
tx_result = self._deploy_score(self._score_address)
55
​
56
self.assertEqual(self._score_address, tx_result['scoreAddress'])
57
​
58
def test_call_hello(self):
59
# Generates a call instance using the CallBuilder
60
call = CallBuilder().from_(self._test1.get_address()) \
61
.to(self._score_address) \
62
.method("hello") \
63
.build()
64
​
65
# Sends the call request
66
response = self._process_call(call, self.icon_service)
67
​
68
# check call result
69
self.assertEqual("Hello", response)
Run test code
1
$ tbears test score_test
2
..
3
----------------------------------------------------------------------
4
Ran 2 tests in 0.172s
5
​
6
OK

References