You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mocha链式智能合约测试:如何跨it块持久化Hardhat合约状态

可行方案说明

Hardhat 网络默认会在每个it测试用例执行前后自动创建、回滚EVM快照,保证每个测试用例都运行在干净的初始链状态,这也是test1里的状态变更没法被test2读取的核心原因。要实现跨it块的状态持久化,有三种常用方案,按推荐优先级从高到低排列:

  • 方案1:合并存在依赖关系的测试逻辑到同一个it块
    这是最符合单元测试隔离原则的方案,不会引入测试顺序依赖问题。你只需要把两个关联步骤的逻辑放到同一个测试用例内即可,示例:
    it('complete flow of update and use value', async () => {
      // 原test1逻辑
      await contractA.updateValue(val);
      // 原test1的其他测试断言
    
      // 原test2逻辑
      await contractA.useUpdatedValue();
      // 原test2的其他测试断言
    });
    
    注意所有合约调用必须加await等待交易确认上链,否则会出现时序错误。
  • 方案2:通过测试钩子初始化共享状态
    如果你只是需要两个测试都用到更新后的合约状态,不需要强制test1先执行完所有逻辑再跑test2,可以把状态更新的公共逻辑放到before/beforeEach钩子里执行,不需要依赖测试用例之间的执行顺序传递状态:
    describe('ContractA related tests', () => {
      // 套件内所有测试执行前先完成值更新
      before(async () => {
        await contractA.updateValue(val);
      });
    
      it('test1', () => {
        // 针对updateValue结果的断言逻辑
      });
    
      it('test2', () => {
        contractA.useUpdatedValue();
        // 其他测试逻辑
      });
    });
    
  • 方案3:关闭Hardhat默认的测试间状态回滚
    如果你确实需要保留两个独立的it块、且严格按照执行顺序传递链状态,可以修改Hardhat配置关闭自动快照回滚。在hardhat.config.js/hardhat.config.ts中添加如下配置:
    module.exports = {
      mocha: {
        // 关闭测试用例执行后的自动快照回滚
        snapshot: false
      }
    };
    

    注意:该配置会让整个测试流程共享同一份链状态,测试执行顺序、前面测试的异常都会直接影响后续所有测试的运行结果,很容易出现偶发的测试失败,非特殊场景不推荐使用。

额外提醒:不管用哪种方案,所有涉及合约状态修改的调用都必须加await等待交易被打包确认,否则会出现交易还没上链、后续逻辑已经执行的时序问题,导致测试结果不符合预期。

内容的提问来源于stack exchange,提问作者Tahlil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 15:30:48