十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

基于 gtest 的 Xcode 工程集成指南(miniblink49 仓库 gtest 文档解读)

基于 gtest 的 Xcode 工程集成指南(miniblink49 仓库 gtest 文档解读) 基于 gtest 的 Xcode 工程集成指南miniblink49 仓库 gtest 文档解读【免费下载链接】miniblink49a lighter, faster browser kernel of blink to integrate HTML UI in your app. 一个小巧、轻量的浏览器内核用来取代wke和libcef项目地址: https://gitcode.com/GitHub_Trending/mi/miniblink49导读本篇文章以仓库中随附的 XcodeGuide.md 为核心完整讲解如何在 Mac OS X 的 Xcode 工程中使用 Google Testing Frameworkgtest搭建 C/C 单元测试环境。文章将带你走完「获取源码 → 构建 gtest.framework → 建立测试 Target → 配置运行环境 → 编译执行」的完整链路并结合 miniblink49 仓库中实际携带的 gtest 源码树、Xcode 工程文件与示例widget_test.cc逐层印证每一步的底层细节让你既能照做也能理解每一步为什么。miniblink49 作为一个跨平台集成的浏览器内核项目在 v8_5_7/testing/gtest 目录下完整携带了 Google Test 的源码、测试用例、构建脚本以及 Xcode 集成所需的全部工程文件。这意味着无论你是要在 Xcode 中为 Mac 端组件编写 gtest 单测还是想理解这套框架在 Xcode 下的构建与链接机制这份文档与仓库源码都是可直接对照的实操蓝本。一、先读仓库gtest 在 miniblink49 中的落位在动手之前先看清楚这份指南对应的真实工程结构。仓库中 gtest 的完整代码树位于 v8_5_7/testing/gtest其中与本指南直接相关的三个目录是目录/文件作用xcode/gtest.xcodeproj/project.pbxprojGoogle Test 自带的 Xcode 工程可一键构建出gtest.frameworkxcode/Config/*.xcconfig工程/目标的构建设置文件Debug、Release、Framework、Static Library、Test 等xcode/Samples/FrameworkSample/一个名为Widget的完整示例被测类 单元测试 独立 Xcode 工程 运行脚本此外include/gtest/gtest.h 是框架的核心头文件src/gtest.cc、src/gtest_main.cc 是框架实现与默认main入口后续集成时都会用到。本文以仓库实际内容为准。指南中描述的svn checkout等命令与链接属于该文档编写时代gtest 早期 trunk 阶段的原始流程仓库内已携带全部源码实际操作时可直接复用仓库文件无需联网检出。二、快速上手七个步骤总览原文档开篇给出一套面向有经验开发者的极简流程共 7 步是整篇指南的骨架完整保留如下下载源码svn checkout http://googletest.googlecode.com/svn/trunk/ googletest-read-only打开googletest-read-only/xcode/目录下的gtest.xcodeproj构建出gtest.framework在你的 Xcode 工程中新建一个名为UnitTests可自定义的 Shell Tool Target将gtest.framework加入工程并添加到UnitTests的 Link Binary with Libraries 构建阶段把你的单元测试源码添加到UnitTests的 Compile Sources 构建阶段编辑UnitTests可执行文件添加名为DYLD_FRAMEWORK_PATH的环境变量其值设为编译产物所在目录到「包含 gtest.framework 的目录」的相对或绝对路径Build and Go跑起来原文档强调The following sections further explain each of the steps listed above in depth——接下来的各小节正是对上述 7 步的逐条深入拆解。下面按原文档顺序展开并同步给出仓库源码层面的印证。三、获取源码检出与svn:externals两种方式3.1 直接检出 trunk原文档指出指南所讨论的gtest.framework在当时并未随 tagged release 发布只存在于 trunk 中因此推荐用匿名 SVN 检出svn checkout http://googletest.googlecode.com/svn/trunk/ googletest-read-only3.2 作为svn:externals外部依赖挂接如果你自己的代码库本身使用 Subversion可以把 Google Test 作为外部依赖挂到自己的 SVN 仓库里。这样所有检出你仓库的同事都会自动拿到一份可以锁定到特定版本Google Test无需显式单独检出工程初始化更简单也减少仓库内的代码拷贝。原文档给出的关键操作要点选址可以放在 trunk 内部发布分支时随分支一起走也可以放在 trunk 之外、以版本号命名的目录如third-party/googletest/1.0.1。设置属性在仓库中某个目录上执行svn propedit svn:externals _directory_该目录本身不含代码而是作为被外部代码挂载的版本化父目录。锁定版本svn:externals支持用-r_##_指定 trunk 的特定 revision例如externals/src/googletest -r60 http://googletest.googlecode.com/svn/trunk。检出版本分支换成对应 tag URL 即可例如http://googletest.googlecode.com/svn/tags/release-1.0.1。原文档给出的实际示例通过svn propget查看 trunk 上的 externals 属性[Computer:svn] user$ svn propget svn:externals trunk externals/src/googletest http://googletest.googlecode.com/svn/trunk该配置的效果是把一份 Google Test 检出到trunk/externals/src/googletest/目录。仓库对照miniblink49 采用的是直接内置源码路线——整个 gtest 树被完整收纳在 v8_5_7/testing/gtest其下还保留了Makefile.am、configure.ac、CMakeLists.txt、msvc/等各平台构建入口可见其作为测试基础设施被固定版本化使用的定位与指南中锁定版本、随仓库分发的思路一致。四、把 gtest.framework 加进你的工程两种方案构建并添加 framework 有两种常见做法原文档分别称之为 Option 1 与 Option 2。Option 1手动构建 framework一次性导入最简单打开 gtest trunk 的xcode/目录下的gtest.xcodeproj手动构建出 framework在你自己工程的上下文菜单选 Add-Existing Framework...或主菜单 Project-Add...把构建产物gtest.framework加进工程gtest.framework是**可重定位relocatable**的内部已包含编写测试所需的头文件与目标代码代价每次升级 Google Test 后都需要手动重新构建并替换 framework。Option 2直接挂入gtest.xcodeproj跟随源码更新适合 trunk 常驻开发者如果你的单测需要紧跟 trunk 的最新特性或者你本身就是 gtest 开发者应把gtest.xcodeproj工程文件而不是 framework 产物加入你自己的 Xcode 工程通过工程显示三角disclosure triangle展开 build products找到其中的gtest.framework再把它挂到你的 Target 上具体挂法见下一节。仓库里的构建设置佐证xcode/Config/*.xcconfig无论是哪种方案framework 的构建参数都由 xcode/Config 下的一组 xcconfig 文件控制原文档虽未展开但仓库源码完整保留了这些设置可直接对照理解General.xcconfig全局默认。关键项包括ARCHS i386 x86_64 ppc ppc64同时构建 PPC 与 Intel、32/64 位WARNING_CFLAGS -Wall -Werror -Wendif-labels -Wnewline-eof -Wno-sign-compare -Wshadow极严格警告策略GCC_C_LANGUAGE_STANDARD c99MACOSX_DEPLOYMENT_TARGET 10.4、GCC_VERSION 4.0指南写作时代的 SDK 基线GCC_DYNAMIC_NO_PIC YES默认位置相关代码个别目标会覆盖。DebugProject.xcconfigGCC_OPTIMIZATION_LEVEL 0不优化、GCC_GENERATE_DEBUGGING_SYMBOLS YES保留调试符号、OTHER_CFLAGS $(OTHER_CFLAGS) -DDEBUG1并刻意关闭 STL 兼容性检查宏避免与客户代码的 STL 冲突。ReleaseProject.xcconfigGCC_OPTIMIZATION_LEVEL s按 Apple 建议优化体积、DEAD_CODE_STRIPPING YES、OTHER_CFLAGS $(OTHER_CFLAGS) -DNDEBUG1 -Wno-unused-variable、STRIP_STYLE all。FrameworkTarget.xcconfig动态库需位置无关代码GCC_DYNAMIC_NO_PIC NO、不剥离外部符号STRIP_STYLE non-global、允许通过$DSTROOT指定安装目录SKIP_INSTALL NO。StaticLibraryTarget.xcconfig对应静态库libgtest.a的构建STRIP_STYLE debugging。TestTarget.xcconfig测试目标专属PRODUCT_NAME $(TARGET_NAME)、HEADER_SEARCH_PATHS ../include——这正是测试代码能#include gtest/gtest.h找到头文件的原因。从源码结构看gtest 的 Xcode 集成同时支持 framework动态与静态库libgtest.a两条产物路径分别由FrameworkTarget.xcconfig与StaticLibraryTarget.xcconfig承载对应下面第 5.2 节中链接 framework与链接静态库两种链接方式。五、创建测试 TargetShell Tool 与两种链接方式5.1 新建 Shell Tool 目标编写测试的第一步是新建一个 Shell Tool Target该模板在 BSD、Cocoa、Carbon 类别下均可用并把你的单元测试源码加入其 Compile Sources 构建阶段。之所以用 Shell Tool 而不是带 bundle 的应用模板是因为 gtest 的测试可执行文件不需要Contents/Frameworks目录结构纯命令行即可运行。5.2 按方案选择链接方式Option 1手动 framework编译期需要让 Xcode 知道你要链接gtest.framework——把它加入测试 Target 的 Link Binary with Libraries 构建阶段即可。这一步同时完成两件事把 gtest 头文件纳入头文件搜索路径并告诉链接器去哪里找库。Option 2源码常驻 trunk除了同样把gtest.framework加入 Link Binary with Libraries还需要把gtest.framework作为**依赖dependency**加到单元测试 Target 上保证每次构建测试目标时 Xcode 都会先确认 gtest.framework 是最新的如果你们与 Google Test 不共享 build 目录还必须用一个 Run Script 构建阶段把gtest.framework拷贝进你自己的 build products 目录。仓库示例印证FrameworkSample/widget_test.cc仓库在 xcode/Samples/FrameworkSample/widget_test.cc 给出了一个完整的测试源文件正好演示了第 5 步往 Compile Sources 里放什么#include string #include gtest/gtest.h #include Widget/widget.h // This test verifies that the constructor sets the internal state of the // Widget class correctly. TEST(WidgetInitializerTest, TestConstructor) { Widget widget(1.0f, name); EXPECT_FLOAT_EQ(1.0f, widget.GetFloatValue()); EXPECT_EQ(std::string(name), widget.GetStringValue()); } // This test verifies the conversion of the float and string values to int and // char*, respectively. TEST(WidgetInitializerTest, TestConversion) { Widget widget(1.0f, name); EXPECT_EQ(1, widget.GetIntValue()); size_t max_size 128; char buffer[max_size]; widget.GetCharPtrValue(buffer, max_size); EXPECT_STREQ(name, buffer); }配套的被测类 widget.cc 实现了一个极简Widget内部存number_与name_测试分别验证了构造器状态EXPECT_FLOAT_EQ/EXPECT_EQ与类型转换EXPECT_EQ/EXPECT_STREQ。文件末尾的注释还揭示了 gtest 默认 main 的等价实现// int main(int argc, char** argv) { // testing::InitGoogleTest(argc, argv); // return RUN_ALL_TESTS(); // }这对应框架自带的 src/gtest_main.cc当你链接的是完整 framework 时无需自己写main框架已内置了初始化与批量运行逻辑。六、配置可执行文件运行环境DYLD_FRAMEWORK_PATH这是整套流程中最容易踩坑的一步原文档专门用一节阐述。由于单元测试可执行文件是 Shell Tool没有bundle 的Contents/Frameworks目录来安放 gtest.framework因此必须在运行时告知动态链接器去别处搜索 framework。做法是在 Edit Active Executable ... 对话框的 Arguments 页签中于 Variables to be set in the environment: 里设置DYLD_FRAMEWORK_PATH环境变量其值为包含 gtest.framework 的目录路径相对或绝对均可。典型报错与修复如果DYLD_FRAMEWORK_PATH没配好运行时会得到类似这样的 dyld 报错[Session started at 2008-08-15 06:23:57 -0600.] dyld: Library not loaded: loader_path/../Frameworks/gtest.framework/Versions/A/gtest Referenced from: /Users/username/Documents/Sandbox/gtestSample/build/Debug/WidgetFrameworkTest Reason: image not found修复方法原文档原话思路进入报错信息中 Referenced from: 所指向的可执行文件所在目录用终端在该位置算出「到包含 gtest.framework 目录」的相对路径把该路径设为DYLD_FRAMEWORK_PATH的值。仓库脚本印证runtests.sh中的等价做法仓库中的两个运行脚本都验证了这条路径配置的等价实现xcode/Scripts/runtests.sh在脚本开头直接export DYLD_FRAMEWORK_PATH$BUILT_PRODUCTS_DIR export DYLD_LIBRARY_PATH$BUILT_PRODUCTS_DIR然后依次执行gtest_unittest-framework、gtest_unittest、sample1_unittest-framework、sample1_unittest-static四个测试可执行文件统计成功/失败个数并以失败数作为进程退出码exit $failed。xcode/Samples/FrameworkSample/runtests.sh逻辑相同只是待运行的可执行文件由命令行参数$传入。可见无论是 IDE 里手填环境变量还是用构建脚本export本质都是让动态链接器在运行gtest.framework所在的 build products 目录里找到它。七、Build and Go跑通并读懂测试输出一切就绪后点击 Build and Go测试即可执行。原文档给出的标准输出如下[Session started at 2008-08-06 06:36:13 -0600.] [] Running 2 tests from 1 test case. [----------] Global test environment set-up. [----------] 2 tests from WidgetInitializerTest [ RUN ] WidgetInitializerTest.TestConstructor [ OK ] WidgetInitializerTest.TestConstructor [ RUN ] WidgetInitializerTest.TestConversion [ OK ] WidgetInitializerTest.TestConversion [----------] Global test environment tear-down [] 2 tests from 1 test case ran. [ PASSED ] 2 tests. The Debugger has exited with status 0.对照上一节的widget_test.cc可以完整对上WidgetInitializerTest这一 test case 下跑TestConstructor与TestConversion两个用例全部通过后以状态码 0 退出。输出中[ RUN ]/[ OK ]的用例级日志、[]的汇总行、Global test environment set-up/tear-down的环境钩子全部来自 src/gtest.cc 的测试运行器实现。仓库还自带海量可复用的测试样例位于 v8_5_7/testing/gtest/samplessample1_unittest.cc~sample10_unittest.cc以及 v8_5_7/testing/gtest/test 下覆盖框架自身的完整回归测试集如gtest_unittest.cc、gtest-death-test_test.cc、gtest-options_test.cc等可作为学习断言 API 与框架行为的现成教材。八、从这份指南继续深入仓库内配套文档这份 Xcode 指南只是 gtest 文档体系中的一环。仓库在 v8_5_7/testing/gtest/docs 下还随附了成套资料可按需衔接文档主题Primer.mdgtest 入门断言、TEST 宏、测试夹具、运行方式AdvancedGuide.md高级特性death test、参数化测试、类型测试、测试环境等Samples.md10 个示例程序的导读与samples/目录一一对应FAQ.md常见问题DevGuide.mdgtest 自身开发指南PumpManual.md模板代码生成器 Pump 的使用说明另外docs/下还保留了V1_5_、V1_6_、V1_7_等历史版本的文档副本含对应的V1_x_XcodeGuide.md可用于版本演进对照。九、总结单元测试是在快速迭代与重构中守住数据模型/接口契约的有效手段。Google Testing Framework 作为 C 与 C 的单元测试框架与 Xcode 开发环境可以良好协同。本指南梳理的完整链路——获取源码 → 构建 gtest.framework → 新建 Shell Tool 测试目标 → 链接 framework含可选依赖与拷贝脚本→ 配置DYLD_FRAMEWORK_PATH→ Build and Go——在 miniblink49 仓库的 xcode/ 目录下均有可直接对照的工程文件、xcconfig 配置与可运行示例支撑。实操时可直接复用仓库自带的 gtest.xcodeproj 构建 framework再参照 FrameworkSample 的Widget示例组织你自己的被测类与测试文件若测试可执行文件在运行时报告dyld: image not found优先检查DYLD_FRAMEWORK_PATH是否指向了包含gtest.framework的目录。【免费下载链接】miniblink49a lighter, faster browser kernel of blink to integrate HTML UI in your app. 一个小巧、轻量的浏览器内核用来取代wke和libcef项目地址: https://gitcode.com/GitHub_Trending/mi/miniblink49创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表