恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

Solidity 属性测试与模糊测试指南:基于 Google FuzzTest 的 PROPERTY_BASED_TESTS 配置与实战

  • 首页
  • 资讯中心
  • /
  • Solidity 属性测试与模糊测试指南:基于 Google FuzzTest 的 PROPERTY_BASED_TESTS 配置与实战

相关资讯

ai-engineering-from-scratch 如何用 GrowthBook 与 Statsig 对 LLM 功能做 A/B 测试? 2026/9/12 16:40:09
LeetCode-Go 题解 1300. Sum of Mutated Array Closest to Target:二分搜索逼近目标和的“截断数组”问题 2026/9/12 16:35:09
LayaAir AI客服系统:开发者智能助手的技术解析 2026/9/12 16:35:09

最新资讯

AI引擎驱动游戏出海:买量与本地化的自动化实践
Claude Cowork:AI协作工作台的架构解析与实践
在 ESP-IDF 上使用 Slint C++ 组件构建嵌入式 GUI:组件结构、初始化配置与渲染原理
Argo CD 文档站点构建与测试指南:基于 MkDocs 的文档开发工作流
LunaTranslator:从捕获到朗读,视觉小说翻译工具的使用全解
99mV纹波实战溯源:叠加定理的工程化拆解与PI/EMC协同治理

今日推荐

MATLAB仿生优化框架:长鼻浣熊算法多策略融合实现
【JAVA毕设源码分享】基于 JavaWeb 的校园一卡通管理系统的设计与实现 基于 JavaWeb 的校园卡业务管理系统(程序+文档+代码讲解+一条龙定制)
【JAVA毕设源码分享】基于 Java 的图书馆借阅管理平台的搭建与实现 基于 Java 的图书馆综合管理系统(程序+文档+代码讲解+一条龙定制)

本周热门

超人会飞不算本事:系统稳定依赖清晰规则与边界设计
超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论
基于CNN的调制信号识别:MATLAB实现时频图分类实战

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

Solidity 属性测试与模糊测试指南:基于 Google FuzzTest 的 PROPERTY_BASED_TESTS 配置与实战

发布时间:2026/9/12 16:40:10
Solidity 属性测试与模糊测试指南:基于 Google FuzzTest 的 PROPERTY_BASED_TESTS 配置与实战 Solidity 属性测试与模糊测试指南基于 Google FuzzTest 的 PROPERTY_BASED_TESTS 配置与实战【免费下载链接】soliditySolidity, the Smart Contract Programming Language项目地址: https://gitcode.com/GitHub_Trending/so/solidity本文聚焦 Solidity 编译器仓库中的test/fuzztest目录——一套基于 Google FuzzTest 构建的**属性测试property-based testing/ 模糊测试fuzzing**基础设施。通过本文你将掌握该框架的两个核心 CMake 开关PROPERTY_BASED_TESTS与PROPERTY_BASED_TESTS_MODE的含义与取舍、unittest与fuzzing两种运行模式的区别、从零配置构建的完整命令以及如何读懂仓库中已落地的属性测试用例以 Tarjan 强连通分量算法验证为例为后续编写或扩展属性测试打下基础。什么是属性测试与传统单元测试的本质区别test/fuzztest/README.md开门见山地定义了这套测试的定位目录中存放的是基于 Google FuzzTest构建的属性测试 / 模糊测试。与传统单元测试不同属性测试不为固定输入断言固定输出而是针对某个输入域domain声明一条对域内所有输入都必须成立的属性property再由 FuzzTest 在该域内自动搜索反例counterexample。用一句话概括单元测试回答这个输入对不对属性测试回答这类输入下不变量是否永远成立。这种范式对编译器这类输入空间巨大、组合爆炸的软件尤其有价值——人工编写的用例永远无法覆盖所有合法的中间表示、AST 或数据结构的形态而属性测试可以用随机生成的输入把不变量验证铺开到远超手工用例的广度。两个核心 CMake 选项主开关与模式选择两个控制属性测试的 CMake 选项定义在 cmake/EthOptions.cmake 的configure_project宏中选项默认值可选值作用PROPERTY_BASED_TESTSOFFON/OFF总开关。为OFF时deps/fuzztest永远不会被加入构建其所有传递FetchContent依赖abseil、re2、gtest、antlr都不会被配置PROPERTY_BASED_TESTS_MODEunittestunittest/fuzzing运行模式选择器。仅当PROPERTY_BASED_TESTS为ON时才有意义源码中这两处定义值得细读# cmake/EthOptions.cmake 中的定义 eth_default_option(PROPERTY_BASED_TESTS OFF) if (NOT DEFINED PROPERTY_BASED_TESTS_MODE) set(PROPERTY_BASED_TESTS_MODE unittest CACHE STRING Property-based test mode: unittest or fuzzing) endif() set_property(CACHE PROPERTY_BASED_TESTS_MODE PROPERTY STRINGS unittest fuzzing)关键设计点PROPERTY_BASED_TESTS默认关闭意味着普通构建完全不受影响——FuzzTest 及其庞大的传递依赖链只在显式开启时才进入配置流程这保证了日常编译的开销与复杂度不因测试基础设施而增加。从 test/CMakeLists.txt 可以看到条件挂载逻辑if (PROPERTY_BASED_TESTS) add_subdirectory(fuzztest) endif()只有总开关打开test/fuzztest子目录才会被加入构建。两种运行模式的差异根据 README 与 test/fuzztest/CMakeLists.txt 中的模式翻译逻辑unittest模式每个FUZZ_TEST作为一条普通测试用例运行对每个输入做1 秒的随机输入突发burst。编译与运行都不需要特殊编译器默认的 g 构建即可工作。fuzzing模式覆盖率引导的模糊测试coverage-guided fuzzing要求使用 Clang 编译器。该模式下每个测试会持续搜索输入空间以最大化代码覆盖率为导向寻找反例。在test/fuzztest/CMakeLists.txt中本项目模式选项会被翻译成 FuzzTest 自身的内部标志if (PROPERTY_BASED_TESTS_MODE STREQUAL fuzzing) set(FUZZTEST_FUZZING_MODE ON) elseif (PROPERTY_BASED_TESTS_MODE STREQUAL unittest) set(FUZZTEST_FUZZING_MODE OFF) else() message(FATAL_ERROR PROPERTY_BASED_TESTS_MODE must be unittest or fuzzing, got ${PROPERTY_BASED_TESTS_MODE}) endif()注意这里利用了 CMake 策略CMP0077NEW下普通变量对option()的覆盖行为直接以同名普通变量改写 FuzzTest 的FUZZTEST_FUZZING_MODE而GCC fuzzing 模式的非法组合会由 FuzzTest 自身的FATAL_ERROR拦截因此仓库没有重复实现这一守卫。依赖注入与编译选项的细节同一份 CMakeLists 中还做了两件值得注意的事子模块初始化通过include(${CMAKE_SOURCE_DIR}/cmake/submodules.cmake)的initialize_submodule(fuzztest)确保子模块就绪再以EXCLUDE_FROM_ALL方式把deps/fuzztest加入构建避免其产物混入默认目标。警告抑制项目全局通过add_compile_options加了-Werror以及-Wconversion等严格标志这些标志会继承到本目录而 FuzzTest 及其依赖在这些标志下无法干净编译因此追加add_compile_options(-w)关闭警告追加在继承标志之后-w生效。配置与构建两种模式的完整命令README 给出了两组可直接复制的配置命令。单元测试模式默认 g 即可# unit-test mode (works with the default g build) cmake -S . -B build-prop -G Ninja -DPROPERTY_BASED_TESTSONPROPERTY_BASED_TESTS_MODE缺省即为unittest因此只需打开总开关此时每个FUZZ_TEST会以普通 GoogleTest 用例的身份执行 1 秒的随机输入突发适合在 CI 与日常开发中快速回归。模糊测试模式必须使用 Clang# fuzzing mode (Clang required) CCclang CXXclang cmake -S . -B build-fuzz -G Ninja -DCMAKE_TOOLCHAIN_FILEcmake/toolchains/fuzztest.cmake这里通过 cmake/toolchains/fuzztest.cmake 工具链文件完成两件事强制打开属性测试并切换到 fuzzing 模式set(PROPERTY_BASED_TESTS ON CACHE BOOL Enable FuzzTest property-based tests FORCE) set(PROPERTY_BASED_TESTS_MODE fuzzing CACHE STRING Property-based test mode FORCE)注入 ASan 覆盖率插桩标志。工具链文件在project()之前被处理因此插桩标志是全局生效的——被测的每个 solidity 库都会以 ASan coverage 构建而不仅是test/fuzztest下的翻译单元。标志取自 FuzzTest 自带的辅助脚本deps/fuzztest/cmake/FuzzTestFlagSetup.cmakefuzztest_setup_fuzzing_flags()因此要求在配置时子模块已初始化否则会报错并提示Run: git submodule update --init deps/fuzztest工具链文件还特别处理了工具链文件会被 CMake 每次 pass 重新读取的问题先重置CMAKE_CXX_FLAGS与CMAKE_EXE_LINKER_FLAGS再调用追加式辅助宏保证无论运行多少次最终插桩标志都完全一致。CI 中的实际用法仓库的 scripts/ci/build_property_tests.sh 展示了 CI 侧的标准做法以-DPROPERTY_BASED_TESTSON配置PROPERTY_BASED_TESTS_MODE保持默认的unittest注释明确说明 fuzzing 模式有意不在 CI 中使用并启用 ccache 加速然后只构建property_tests目标而非整个项目cmake --build . --target property_tests这个便利目标在test/fuzztest/CMakeLists.txt末尾定义add_custom_target(property_tests) add_dependencies(property_tests yul_fuzztest)新增的每个lib_fuzztest可执行目标都应把自己注册到这个聚合目标下。源码级实战读懂第一个属性测试用例目前仓库已落地的属性测试位于 test/fuzztest/libyul/TarjanSCCPropertyTest.cpp它验证的是 libsolutil/TarjanSCC.h 中computeStronglyConnectedComponents的实现正确性——这是 Yul 调用图分析CallGraph::recursiveFunctions()识别递归函数的底层依赖。被测属性三条不变量对随机生成的有向图测试将 Tarjan 算法结果与独立的可达性 oracle对每个源节点各做一次 DFS 得到的全对可达矩阵交叉比对断言三条属性SCC 划分完整性返回的 SCC 集合恰好划分0, n)——每个节点恰好出现在一个范围内in-range的 SCC 中不多不少。SCC 等价于双向可达两个节点属于同一 SCC 当且仅当它们互相可达这正是 SCC 的定义。递归分类一致性仿照CallGraph::recursiveFunctions()由 SCC 推导递归分类非平凡 SCC 或自环边的方式与独立的节点位于有向环上oracle 比对。这一条专门锻炼了纯 SCC 划分无法钉死的自环粘合逻辑——自环节点与孤立节点都是单元素 SCC仅靠划分无法区分二者。输入域的构造FlatMap PairOf 组合测试使用 FuzzTest 的域组合 API 生成输入值得仔细解读FUZZ_TEST(TarjanSCCProperty, SCCMatchesReachability) .WithDomains( fuzztest::FlatMap( [ { return fuzztest::PairOf( fuzztest::Just(_numNodes), fuzztest::VectorOf( fuzztest::StructOfEdge( fuzztest::InRangeNodeID(0, _numNodes - 1), fuzztest::InRangeNodeID(0, _numNodes - 1) ) ).WithMaxSize(maxEdges) ); }, fuzztest::InRangeNodeID(1, maxNodes) ) );生成逻辑为先用InRangeNodeID(1, maxNodes)采样节点数上限 128再通过FlatMap依赖该节点数生成(节点数, 边列表)对——每条边由StructOfEdge生成端点约束在[0, numNodes-1]内以保证稠密编号边数上限maxEdges 256。这种先生成规模、再依赖规模生成结构的依赖式域组合正是 FuzzTest 处理结构化复杂输入的标准手法。从实现看验证价值libsolutil/TarjanSCC.h中的实现是**迭代式显式工作栈**的 Tarjan 算法而非教科书常见的递归版workStack上的帧记录(node, childIdx)入栈时预先进位childIdx出栈时向父节点回传 lowlink。这类手写迭代版本极易在先推进边再递归、lowlink 回传时机等细节上出错而递归版本在深层图上还有栈溢出风险。属性测试恰好能以海量随机图含自环、重边、稠密/稀疏、强连通/非强连通系统性轰击这些边界这正是该测试用例存在的价值。运行属性测试配置完成后在build-prop或build-fuzz构建目录中运行对应的可执行文件即可。unittest模式下每个FUZZ_TEST表现为普通 gtest 用例可用 gtest 的过滤参数如--gtest_filter定向执行fuzzing模式下可执行文件则是一个覆盖率引导的模糊器可持续运行直至发现反例或达到资源上限FuzzTest 会在发现反例时输出最小化后的复现输入。小结test/fuzztest是 Solidity 仓库中一套设计干净、侵入性低的属性测试基础设施总开关默认关闭普通构建零负担开启后由 cmake/EthOptions.cmake 统一管理两个选项两种模式覆盖不同场景unittest适合日常与 CI 的快速回归fuzzing需要 Clang 且通过 cmake/toolchains/fuzztest.cmake 全局注入 ASan 覆盖率插桩新增测试的扩展路径清晰在 test/fuzztest 下为各库添加lib_fuzztest可执行目标参考TarjanSCCPropertyTest.cpp的域组合写法并注册进property_tests聚合目标即可。对于希望为 Solidity 的 Yul 优化、类型系统、图算法等复杂逻辑补充不变量验证的开发者这套框架提供了开箱即用的入口——从读懂SCCMatchesReachability这个用例开始就是最好的起点。【免费下载链接】soliditySolidity, the Smart Contract Programming Language项目地址: https://gitcode.com/GitHub_Trending/so/solidity创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号