メインコンテンツまでスキップ

テストガイド

テスト戦略​

ERC20コントラクトのテストは、以下の観点で実施することを推奨します。

単体テスト​

基本機能テスト​

テストケース説明
初期状態コンストラクタ後の状態が正しいか
name()トークン名が正しく返されるか
symbol()シンボルが正しく返されるか
decimals()小数点桁数が正しいか(デフォルト: 18)
totalSupply()総供給量が正しいか

転送テスト​

テストケース説明
正常転送残高十分な場合に転送成功
残高不足ERC20InsufficientBalanceエラー
ゼロアドレス送付先ERC20InvalidReceiverエラー
ゼロ量転送成功(イベント発行)

許可テスト​

テストケース説明
許可設定許可量が正しく設定されるか
許可上書き許可量が上書きされるか
無限許可type(uint256).maxの動作
ゼロアドレスspenderERC20InvalidSpenderエラー

transferFromテスト​

テストケース説明
正常転送許可・残高十分な場合に成功
許可不足ERC20InsufficientAllowanceエラー
無限許可での転送許可量が減少しないか

Foundryテスト例​

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import "forge-std/Test.sol";
import "../src/MyToken.sol";

contract ERC20Test is Test {
MyToken token;
address alice = address(0x1);
address bob = address(0x2);

function setUp() public {
token = new MyToken();
token.transfer(alice, 1000 ether);
}

function test_Transfer() public {
vm.prank(alice);
token.transfer(bob, 100 ether);

assertEq(token.balanceOf(alice), 900 ether);
assertEq(token.balanceOf(bob), 100 ether);
}

function test_TransferInsufficientBalance() public {
vm.prank(alice);
vm.expectRevert();
token.transfer(bob, 2000 ether);
}

function test_Approve() public {
vm.prank(alice);
token.approve(bob, 500 ether);

assertEq(token.allowance(alice, bob), 500 ether);
}

function test_TransferFrom() public {
vm.prank(alice);
token.approve(bob, 500 ether);

vm.prank(bob);
token.transferFrom(alice, bob, 200 ether);

assertEq(token.balanceOf(bob), 200 ether);
assertEq(token.allowance(alice, bob), 300 ether);
}
}

テストカバレッジ​

推奨カバレッジ目標:

種類目標
行カバレッジ100%
ブランチカバレッジ100%
関数カバレッジ100%
# Foundryでカバレッジを確認
forge coverage

インテグレーションテスト​

実際のDeFiプロトコルとの統合をテスト:

  1. DEXでのスワップ
  2. レンディングプロトコルでの担保
  3. ブリッジでのクロスチェーン転送