测试与部署 #
一、测试策略 #
1.1 测试层次 #
| 测试类型 | 说明 |
|---|---|
| 单元测试 | 测试单个函数 |
| 集成测试 | 测试合约交互 |
| 端到端测试 | 测试完整流程 |
| 模糊测试 | 随机输入测试 |
1.2 测试原则 #
- 测试所有公共函数
- 测试边界条件
- 测试错误情况
- 测试权限控制
二、单元测试 #
2.1 Hardhat测试 #
javascript
const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("Token", function () {
let token;
let owner;
let addr1;
beforeEach(async function () {
[owner, addr1] = await ethers.getSigners();
const Token = await ethers.getContractFactory("Token");
token = await Token.deploy("MyToken", "MTK", 1000000);
});
describe("Deployment", function () {
it("Should set correct name", async function () {
expect(await token.name()).to.equal("MyToken");
});
it("Should assign supply to owner", async function () {
const balance = await token.balanceOf(owner.address);
expect(balance).to.equal(ethers.utils.parseEther("1000000"));
});
});
describe("Transfers", function () {
it("Should transfer tokens", async function () {
await token.transfer(addr1.address, 100);
expect(await token.balanceOf(addr1.address)).to.equal(100);
});
it("Should fail if insufficient balance", async function () {
await expect(
token.connect(addr1).transfer(owner.address, 100)
).to.be.reverted;
});
});
});
2.2 Foundry测试 #
solidity
contract TokenTest is Test {
Token public token;
address public owner;
address public user;
function setUp() public {
owner = address(this);
user = address(0x1);
token = new Token("MyToken", "MTK", 1000000);
}
function test_Name() public {
assertEq(token.name(), "MyToken");
}
function test_Transfer() public {
token.transfer(user, 100);
assertEq(token.balanceOf(user), 100);
}
function testFail_InsufficientBalance() public {
token.transfer(user, 1000000000); // 应该失败
}
function testRevert_InsufficientBalance() public {
vm.expectRevert("ERC20: transfer amount exceeds balance");
token.transfer(user, 1000000000);
}
}
三、模糊测试 #
3.1 Foundry模糊测试 #
solidity
contract FuzzTest is Test {
Token public token;
function setUp() public {
token = new Token("Test", "TST", 1000000);
}
function testFuzz_Transfer(uint256 amount) public {
vm.assume(amount <= token.balanceOf(address(this)));
address user = address(0x1);
uint256 balanceBefore = token.balanceOf(user);
token.transfer(user, amount);
assertEq(token.balanceOf(user), balanceBefore + amount);
}
function testFuzz_Approve(address spender, uint256 amount) public {
token.approve(spender, amount);
assertEq(token.allowance(address(this), spender), amount);
}
}
四、部署流程 #
4.1 部署前检查 #
| 检查项 | 说明 |
|---|---|
| 合约审计 | 确保代码安全 |
| 测试覆盖 | 确保测试完整 |
| Gas估算 | 估算部署成本 |
| 参数准备 | 准备构造函数参数 |
4.2 Hardhat部署 #
javascript
// scripts/deploy.js
const hre = require("hardhat");
async function main() {
const [deployer] = await ethers.getSigners();
console.log("Deploying contracts with account:", deployer.address);
console.log("Account balance:", (await deployer.getBalance()).toString());
const Token = await hre.ethers.getContractFactory("Token");
const token = await Token.deploy("MyToken", "MTK", 1000000);
await token.deployed();
console.log("Token deployed to:", token.address);
// 验证合约
if (network.name !== "hardhat") {
await hre.run("verify:verify", {
address: token.address,
constructorArguments: ["MyToken", "MTK", 1000000],
});
}
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
4.3 Foundry部署 #
solidity
// script/Deploy.s.sol
contract DeployScript is Script {
function run() external {
uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
vm.startBroadcast(deployerPrivateKey);
Token token = new Token("MyToken", "MTK", 1000000);
vm.stopBroadcast();
}
}
bash
forge script script/Deploy.s.sol --rpc-url $RPC_URL --broadcast --private-key $PRIVATE_KEY
五、CI/CD #
5.1 GitHub Actions #
yaml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm ci
- name: Compile contracts
run: npx hardhat compile
- name: Run tests
run: npx hardhat test
- name: Run coverage
run: npx hardhat coverage
六、总结 #
测试与部署要点:
| 类别 | 要点 |
|---|---|
| 测试 | 单元测试、集成测试、模糊测试 |
| 部署 | 检查、脚本、验证 |
| CI/CD | 自动化测试和部署 |
接下来,让我们学习DeFi应用!
最后更新:2026-03-27