Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
sojinkim-icon committed May 13, 2019
1 parent 8a2ca39 commit 7a2355e
Show file tree
Hide file tree
Showing 6 changed files with 1,838 additions and 0 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Documents that merged into the master branch are published on the developers por
- [account-management](./howto/account-management.md)
- [how-to-change-network-in-iconex-chrome](./howto/how-to-change-network-in-iconex-chrome.md)
- [how-to-generate-a-transaction-signature](./howto/how-to-generate-a-transaction-signature.md)
- [how-to-write-score-integration-test](./howto/how-to-write-score-integration-test.md)
- [how-to-write-score-unit-test](./howto/how-to-write-score-unit-test.md)
- [icon-development-network-on-aws-marketplace](./howto/icon-development-network-on-aws-marketplace.md)
- icon-key-concepts
- [accounts](./icon-key-concepts/accounts.md)
Expand All @@ -30,6 +32,9 @@ Documents that merged into the master branch are published on the developers por
- [swift-api-reference](./references/swift-api-reference.md)
- [swift-sdk](./references/swift-sdk.md)
- [t-bears-reference](./references/t-bears-reference.md)
- sample-scores
- [multi-signature-wallet](./sample-scores/multi-signature-wallet.md)
- [token-crowdsale](./sample-scores/token-crowdsale.md)
- score
- [audit-checklist](./score/audit-checklist.md)
- [score-audit](./score/score-audit.md)
Expand Down
192 changes: 192 additions & 0 deletions howto/how-to-write-score-integration-test.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
---
title: "How to write SCORE integration test"
---

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

## Purpose

Understand how to write SCORE integration test

## Prerequisite

* [SCORE Overview](score-overview)
* [T-Bears Overview](tbears-overview)
* [ICON Python SDK](python-sdk)

## 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

```python
# 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)
```



#### 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

```python
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"
```

#### score_tests/test_score_test.py

```python
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)
```

#### Run test code

```bash
$ tbears test score_test
..
----------------------------------------------------------------------
Ran 2 tests in 0.172s

OK
```

## References

* [ICON Python SDK](python-sdk)
* [ICON SCORE samples](sample-scores)

Loading

0 comments on commit 7a2355e

Please sign in to comment.