Exporting awareness and continuous building
Exporting awareness and continuous building

Subscribe to Cognitive

Subscribe to Cognitive
Share Dialog
Share Dialog
<100 subscribers
<100 subscribers
编写单元测试首先需要我们在测试钩子中编写发布合约的代码,这意味着,我们需要在每次 beforeEach 钩子中重新发布我们的合约并使其从零状态开始运行。
即使 hardhat 支持在内存中运行区块链并整合了单元测试流程,但这样反复的发布合约也会极大拖慢测试速度。
因此,就单元测试的最佳实践,我向大家推荐 hardhat-deploy 插件。
hardhat-deploy 插件支持使用 evm_snapshot 快速地跳转到某个高度的区块链状态,因此,我们可以使用它在单元测试中维护测试前、中、后以及各种特定高度状态,极大地加快测试速度。
https://github.com/wighawag/hardhat-deploy
注意,引入
hardhat-deploy插件,需要修改对应的@nomiclabs/hardhat-ethers插件来源,这可能会导致在未来的npm install中带来版本冲突,如果你遇到了版本冲突,可以使用npm install --force跳过版本依赖检查,强制安装两者。
"devDependencies": {
"@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers",
"hardhat-deploy": "^0.11.2",
...
}
简单来说,在单元测试中,我们可以使用:
await deployments.fixture(['SomeContractName']);
来确保在测试执行前跳回某个状态。如果你需要更加复杂和自定义的 fixture(而非直接跳回某个合约发布后的干净状态)可以使用 deployments.createFixture 来创建自定义 fixture,具体的范例代码和指南可以在这里寻找到:
https://github.com/CodeforDAO/contracts/blob/main/utils/helpers.js#L42
https://github.com/wighawag/hardhat-deploy#creating-fixtures
值得注意的是,使用 hardhat-deploy 插件会同时改变我们发布合约的代码逻辑(正如其名)它支持在 ./deploy 文件夹下编写每个合约的发布脚本。事实上,默认的 deployments.fixture 正会退回这些发布脚本所叙述的合约状态。
不同于 hardhat 默认的发布脚本(使用 npx hardhat run)我们可以使用 hardhat-deploy 插件提供的功能在发布脚本中做更多工作,例如使用 execute 函数立即修改发布后的合约状态,这会在对权限敏感的合约当中非常有用:
const { deploy, execute } = deployments;
const shareGovernor = await deploy('ShareGovernor', {
contract: 'TreasuryGovernor',
from: deployer,
args: [name + '-ShareGovernor', share.address, treasury.address, settings.share.governor],
log: true,
});
// Setup governor roles
// Both membership and share governance have PROPOSER_ROLE by default
await execute(
'Treasury',
{ from: deployer },
'grantRole',
PROPOSER_ROLE,
membershipGovernor.address
);
除此之外,hardhat-deploy 插件还提供了非常多的 HRE 实用函数,例如getNamedAccounts 能帮助我们命名本地测试账户,而非使用数组下标访问它们。你可以参考该插件的 GitHub 主页了解这些实用功能。
当合约的单元测试编码到一定程度之后,我们会希望这些合约被发布到某个测试或生产环境(例如测试网络或 ETH 主网)时是否是健壮和低成本的,在此时,我向你推荐两个 hardhat 插件 hardhat-gas-reporter 与 solidity-coverage

hardhat-gas-reporter 插件帮助你了解运行单元测试中部署和执行合约方法消耗的 gas 费用,如果在本地环境变量中提供 COINMARKETCAP_API_KEY,它会自动将这些成本折算为美元或其他法币计价。
https://github.com/cgewecke/hardhat-gas-reporter
solidity-coverage 插件提供单元测试覆盖率报告,这有助于开发团队理解合约是否得到了应有的测试。
https://github.com/sc-forks/solidity-coverage
如前所述,hardhat 并不需要以来太多的插件就可以正常工作,满足大部分合约开发团队的需求,我在这里推荐两个其他的使用插件,他们是 @nomiclabs/hardhat-etherscan 和 @tenderly/hardhat-tenderly
这些插件都是可选的,并依赖第三方服务的 API Key,各位读者可以根据自己的情况选择是否使用他们。
hardhat-etherscan 插件将 etherscan 网站的源码 verify 功能整合到发布工作流中,能够将所发布合约的源码和 ABI 都展示在合约地址页面。
https://github.com/NomicFoundation/hardhat
hardhat-tenderly 插件整合了 Tenderly 工作流,后者是一个新兴的 CI/监控 平台,能够帮助我们监控线上合约的状态并提供 debug 建议。
编写单元测试首先需要我们在测试钩子中编写发布合约的代码,这意味着,我们需要在每次 beforeEach 钩子中重新发布我们的合约并使其从零状态开始运行。
即使 hardhat 支持在内存中运行区块链并整合了单元测试流程,但这样反复的发布合约也会极大拖慢测试速度。
因此,就单元测试的最佳实践,我向大家推荐 hardhat-deploy 插件。
hardhat-deploy 插件支持使用 evm_snapshot 快速地跳转到某个高度的区块链状态,因此,我们可以使用它在单元测试中维护测试前、中、后以及各种特定高度状态,极大地加快测试速度。
https://github.com/wighawag/hardhat-deploy
注意,引入
hardhat-deploy插件,需要修改对应的@nomiclabs/hardhat-ethers插件来源,这可能会导致在未来的npm install中带来版本冲突,如果你遇到了版本冲突,可以使用npm install --force跳过版本依赖检查,强制安装两者。
"devDependencies": {
"@nomiclabs/hardhat-ethers": "npm:hardhat-deploy-ethers",
"hardhat-deploy": "^0.11.2",
...
}
简单来说,在单元测试中,我们可以使用:
await deployments.fixture(['SomeContractName']);
来确保在测试执行前跳回某个状态。如果你需要更加复杂和自定义的 fixture(而非直接跳回某个合约发布后的干净状态)可以使用 deployments.createFixture 来创建自定义 fixture,具体的范例代码和指南可以在这里寻找到:
https://github.com/CodeforDAO/contracts/blob/main/utils/helpers.js#L42
https://github.com/wighawag/hardhat-deploy#creating-fixtures
值得注意的是,使用 hardhat-deploy 插件会同时改变我们发布合约的代码逻辑(正如其名)它支持在 ./deploy 文件夹下编写每个合约的发布脚本。事实上,默认的 deployments.fixture 正会退回这些发布脚本所叙述的合约状态。
不同于 hardhat 默认的发布脚本(使用 npx hardhat run)我们可以使用 hardhat-deploy 插件提供的功能在发布脚本中做更多工作,例如使用 execute 函数立即修改发布后的合约状态,这会在对权限敏感的合约当中非常有用:
const { deploy, execute } = deployments;
const shareGovernor = await deploy('ShareGovernor', {
contract: 'TreasuryGovernor',
from: deployer,
args: [name + '-ShareGovernor', share.address, treasury.address, settings.share.governor],
log: true,
});
// Setup governor roles
// Both membership and share governance have PROPOSER_ROLE by default
await execute(
'Treasury',
{ from: deployer },
'grantRole',
PROPOSER_ROLE,
membershipGovernor.address
);
除此之外,hardhat-deploy 插件还提供了非常多的 HRE 实用函数,例如getNamedAccounts 能帮助我们命名本地测试账户,而非使用数组下标访问它们。你可以参考该插件的 GitHub 主页了解这些实用功能。
当合约的单元测试编码到一定程度之后,我们会希望这些合约被发布到某个测试或生产环境(例如测试网络或 ETH 主网)时是否是健壮和低成本的,在此时,我向你推荐两个 hardhat 插件 hardhat-gas-reporter 与 solidity-coverage

hardhat-gas-reporter 插件帮助你了解运行单元测试中部署和执行合约方法消耗的 gas 费用,如果在本地环境变量中提供 COINMARKETCAP_API_KEY,它会自动将这些成本折算为美元或其他法币计价。
https://github.com/cgewecke/hardhat-gas-reporter
solidity-coverage 插件提供单元测试覆盖率报告,这有助于开发团队理解合约是否得到了应有的测试。
https://github.com/sc-forks/solidity-coverage
如前所述,hardhat 并不需要以来太多的插件就可以正常工作,满足大部分合约开发团队的需求,我在这里推荐两个其他的使用插件,他们是 @nomiclabs/hardhat-etherscan 和 @tenderly/hardhat-tenderly
这些插件都是可选的,并依赖第三方服务的 API Key,各位读者可以根据自己的情况选择是否使用他们。
hardhat-etherscan 插件将 etherscan 网站的源码 verify 功能整合到发布工作流中,能够将所发布合约的源码和 ABI 都展示在合约地址页面。
https://github.com/NomicFoundation/hardhat
hardhat-tenderly 插件整合了 Tenderly 工作流,后者是一个新兴的 CI/监控 平台,能够帮助我们监控线上合约的状态并提供 debug 建议。
No activity yet