ARTICLE DETAIL

资讯详情

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

App-Store-Connect-CLI 的 `asc xcode test` 命令:本地 Xcode 测试的端到端设计与实现解析

App-Store-Connect-CLI 的 `asc xcode test` 命令:本地 Xcode 测试的端到端设计与实现解析 【免费下载链接】App-Store-Connect-CLIFast, scriptable CLI for the App Store Connect API. Automate TestFlight, builds, submissions, signing, analytics, screenshots, subscriptions, and more项目地址https://gitcode.com/gh_mirrors/ap/App-Store-Connect-CLI点击查看免费下载asc xcode test是 App-Store-Connect-CLI 在asc xcode本地命令组下提供的一等公民测试子命令它显式运行本机xcodebuild的测试动作通过 Xcode 命令行工具读取生成的.xcresult结果包并输出稳定的结构化 JSON、表格、Markdown 或 JUnit 报告。本文以 xcode-test-command.md 设计文档为主体骨架结合 internal/cli/xcode/test.go、internal/xcode/test.go 等源码实现与测试用例完整梳理命令的定位边界、全部 Typed 参数、结果解析原理、输出契约、失败行为与质量保障方案让你能直接把该命令接入本地 CI 与发布流水线。命令定位与职责边界asc xcode test位于本地asc xcode命令组的叶子位置见 internal/cli/xcode/xcode.go 的子命令注册表它与组内的build、archive、export、install等命令共享同一套本地进程与渲染基础设施但职责边界被严格限定只运行本地xcodebuild测试动作并通过当前激活的 Xcode 命令行工具读取.xcresult结果包绝不调用 App Store Connect不上传任何产物也不修改 Xcode 工程文件Xcode 可能会根据--destination启动或拉起所选模拟器/真机但命令本身不做任何宿主相关的隐式选择不需要任何 App Store Connect 凭证也不需要网络访问。也就是说它是纯本地的编译 测试 结构化汇总工具输出可以直接喂给后续的asc upload、asc publish等发布命令而测试本身不产生任何远程副作用。三种测试动作与选择器约束命令通过一个类型化选项--action支持 Xcode 的三种测试动作--action取值对应 xcodebuild 动作选择器要求test默认xcodebuild ... test必须提供--project或--workspace之一以及--schemebuild-for-testingxcodebuild ... build-for-testing同上仅构建测试产物不执行测试test-without-buildingxcodebuild ... test-without-building必须提供已存在的--xctestrun文件拒绝工程类选择器选择器约束并非只在文档层面承诺ValidateTestOptionsinternal/xcode/test.go在启动任何子进程前就完成了确定性的校验test与build-for-testing要求工程/工作区二选一--project必须后缀.xcodeproj、--workspace必须后缀.xcworkspace且--scheme必填test-without-building则禁止--project、--workspace、--scheme、--configuration、--derived-data-path并要求--xctestrun后缀为.xctestrun且文件真实存在validateTestInputPaths。此外每种动作都强制要求一个或多个显式--destination这样一次运行不会依赖 Xcode 基于宿主机的默认目的地选择保证在 CI 上与在本地行为一致。源码中if len(opts.Destinations) 0 { return fmt.Errorf(--destination is required) }直接体现了这条硬性约束。调用方式与全部 Typed 参数设计文档给出了一条完整的基线命令asc xcode test \ --project App.xcodeproj \ --scheme App \ --configuration Debug \ --destination platformiOS Simulator,nameiPhone 17 Pro \ --result-bundle-path .asc/artifacts/App-tests.xcresult \ --output json在 internal/cli/xcode/test.go 中这些参数被逐一注册为 Typed flag完整清单如下参数类型说明与约束--project单值.xcodeproj路径与--workspace互斥且必须二选一--workspace单值.xcworkspace路径与--project互斥且必须二选一--scheme单值Xcode scheme 名除test-without-building外必填--action单值test默认/build-for-testing/test-without-building--configuration单值构建配置如Debug、Release仅对工程类动作有效--destination可重复Xcode 目的地描述符必填可传多次--test-plan单值Xcode 测试计划名与--xctestrun互斥--xctestrun单值已存在的.xctestrun文件仅test-without-building使用--only-testing可重复只运行指定的测试目标或标识符--skip-testing可重复跳过指定的测试目标或标识符--derived-data-path单值DerivedData 目录缺省分配在稳定的 asc 缓存路径下--result-bundle-path单值新结果包.xcresult的落点缺省自动分配--clean布尔在所选动作前先执行clean--no-code-signing布尔显式设置CODE_SIGNING_ALLOWEDNO--xcodebuild-flag可重复原样透传给xcodebuild的原始参数标准输出 flag—--output、--pretty等通用输出控制命令对参数形状有严格约定空值一律非法--%s must not be empty位置参数一律拒绝xcode test does not accept positional arguments。同时有几个重要的互斥/作用域规则--test-plan与--xctestrun互斥--clean、--no-code-signing、--configuration、--derived-data-path只对选择工程/工作区的动作有效test-without-building全部拒绝可重复的目的地与测试过滤值拒绝空串和控制字符输入但保留字面空白——这正是exactTestStringFlaginternal/cli/xcode/test.go存在的意义destination 与测试标识符中可能含空格必须原样到达xcodebuild不能被通用 flag 解析吞掉。透传参数的安全约束--xcodebuild-flag提供了灵活性但被设计为可控的逃生舱。源码中的reservedTestPassthroughArgument与validateTestPassthroughArgumentsinternal/xcode/test.go明确禁止透传参数覆盖以下 asc 托管项选择器类-workspace、-project、-scheme、-configuration、-destination、-testPlan、-xctestrun、-only-testing、-skip-testing、-derivedDataPath、-resultBundlePath以及 ASC 托管的签名设置如CODE_SIGNING_ALLOWEDNO认证类参数值不能为空带值参数必须跟随一个值且该值不能是另一个被识别的 xcodebuild 选项防止 xcodebuild 静默吞掉下一个选项当凭据。所有透传值以独立 argv 条目传递保留用户给定的顺序与空白。这也意味着命令本身的动作永远由--action决定argv 末尾追加的test/build-for-testing/test-without-building由buildTestCommand统一构造internal/xcode/test.go透传层无法篡改动作语义。结果包分配与产物保护对于执行测试的动作asc总是为运行供应一个新的结果包路径显式提供--result-bundle-path时先解析为绝对路径再使用扩展名必须为.xcresult缺省时在用户缓存目录下分配cache/asc/xcode-test/scheme-时间戳-哈希.xcresult其中哈希是对工程/工作区路径、scheme、action、configuration、test-plan 与全部 destinations 的 SHA-256 摘要前 12 位见resolveTestResultBundlePathinternal/xcode/test.go保证不同选择器组合不会互相覆盖已存在的路径、目录、符号链接目的地一律拒绝validateTestResultBundleDestination在启动子进程前用Lstat检查validateTestResultBundlePathComponents则逐个组件检查符号链接仅放行 macOS 系统级/etc、/tmp、/var别名且该检查在 xcodebuild 前后各执行一次因为最终路径是由子进程在包外创建的。DerivedData 路径同理显式提供时转为绝对路径缺省时分配在缓存下的稳定路径按选择器摘要哈希resolveTestDerivedDataPath便于build-for-testing之后衔接test-without-building。build-for-testing不需要结果包但在恰好能从其 DerivedData 目录下识别出唯一安全的.xctestrun候选文件时会报告该路径findXctestrunPathinternal/xcode/test.go候选多于一个时不猜测、不报告。结构化结果解析xcresulttool 双读设计文档明确指出结果包通过 Xcode 官方工具链汇总而不是解析人读的xcodebuild日志。当前实现使用两次结构化读取internal/xcode/test.goxcresulttool get test-results summary --path PATH --compact提供totalTestCount、passedTests、failedTests、skippedTests、testFailures等聚合字段xcresulttool get test-results tests --path PATH --compact提供递归的testNodes树。解析器只把Test Case节点展平appendTestCases按nodeType过滤失败文本只从结构化的 failure-message 子节点取有界内容。状态归一化normalizeTestStatus只接受passed、failed、skipped与expected-failure四类期望失败expected failure不算失败但计数会被单独报告。聚合一致性校验是一道严格的防线validateTestSummary/ParseTestResultSummary聚合计数必须非负且passed failed skipped expectedFailures必须等于totalTestCount否则报inconsistent test countsexpectedFailures在 Xcode 提供该字段时做对账缺失时由剩余计数推导当展平后的用例与聚合描述同一统计单元用例数等于 total时逐用例状态计数会与聚合交叉核对多目的地或重复运行产生的树即便叶子数与聚合不同也保留原样不强行篡改未知字段一律忽略。另外结构化输出在解析前就被封顶maxXcresulttoolOutputBytes为 16 MiB、诊断输出封顶 8 KiB、用例数上限 10000、失败详情上限 100 条、单条失败消息上限 4096 字符常量定义见 internal/xcode/test.go。缺必需聚合字段、JSON 畸形、结果包缺失或工具不可用都是显式的后处理错误——asc 绝不凭空捏造成功计数只要有任何测试失败就绝不报告成功。输出契约JSON 收据、表格/Markdown 与 JUnitJSON稳定的 camelCase 收据JSON 走的是注册的导出输出收据类型internal/asc/output_xcode.go字段名稳定为 camelCase。设计文档给出了完整示例{ action: test, project: App.xcodeproj, scheme: App, configuration: Debug, destinations: [platformiOS Simulator,nameiPhone 17 Pro], derivedDataPath: /path/to/DerivedData, resultBundlePath: /path/to/App-tests.xcresult, tests: { total: 12, passed: 10, failed: 1, skipped: 1, expectedFailures: 0, durationMs: 4812, failures: [ {identifier: AppTests/LoginTests/testInvalidPassword, message: assertion failed} ] }, success: false, durationMs: 5120, exitStatus: 65 }要点build-for-testing会省略tests字段并在安全发现时报告.xctestrun路径exitStatus保留 xcodebuild 进程的原始退出码示例中的 65 正是 Xcode 测试失败常见的退出码取消、预检与结果后处理错误不会冒充子进程退出状态表格table与 Markdown 渲染同样的稳定汇总字段测试失败明细保持有界formatXcodeTestFailure截断到 4096 字节Xcode 的实时诊断输出留在 stderr结构化 stdout 永远不会包含完整的原始日志或环境信息。JUnit全局--report junit的聚合对账当提供全局--report junit --report-file PATH且存在结构化测试结果时命令为每个解析出的测试生成一个 JUnit testcase并在展平树未能完整代表聚合计数时合成有界的聚合用例testResultJUnitReportinternal/cli/xcode/test.go合成顺序刻意优先aggregate-failed-*再aggregate-skipped-*、aggregate-passed-*——这样在聚合用例封顶maxJUnitAggregateCases 10000时失败的签名也不会被吞掉零测试的汇总不产生任何通过占位套件级 duration 直接取汇总的summary.DurationMS避免按用例求和时丢失 setup/teardown 与多目的地重复执行的时间当 xcodebuild 异常退出或后处理失败且报告中尚无失败行时追加一条xcode test did not complete successfully的基础设施失败行但已由失败用例代表的普通非零退出不会被重复计数shouldAddJUnitInfrastructureFailure。报告文件沿用仓库既有的 no-overwrite不覆盖已存在文件与受限权限写入器行为。使用/预检失败则保留原有的通用命令级报告。关联子命令asc xcode test junit与asc xcode test-destinations在 internal/cli/xcode/test.go 中test命令还挂载了子命令asc xcode test junitinternal/cli/xcode/test_junit.go它不运行测试直接把已存在的.xcresult包转成与asc xcode test --report junit相同形态的 JUnit XML命令格式为asc xcode test junit --xcresult ./Test.xcresult --report-file ./junit.xml --output json若聚合汇总读取成功但逐用例补全失败命令 fail-closed不写部分报告。配套的asc xcode test-destinationsinternal/cli/xcode/test_destinations.go则是一个只读的simctl list输出可直接粘贴进--destination的DestinationString如platformiOS Simulator,idUDID支持--platform iOS|watchOS|tvOS|visionOS|macOS与--available-only过滤且绝不创建、启动或删除模拟器。验证与失败行为命令的确定性校验选项形状、路径合法性全部发生在创建目录或启动子进程之前保证坏的调用不产生副作用。本地辅助逻辑复用了仓库既有的 macOS-only Xcode 可用性检查与进程组取消行为ensureXcodeAvailable、进程组信号。失败语义有三个关键分支对应 internal/xcode/test.go 的Test主流程动作失败但结果包可读仍会尽力解析出部分汇总readPartialTestResultSummary使用独立的 30 秒后处理超时并主动丢弃调用方的取消/截止以便抢救可读数据但命令最终返回原始的 xcodebuild 非零错误动作成功但结果包无法汇总返回后处理错误并保留产物供诊断绝不静默通过测试失败summary.Failed 0或存在 failed 用例返回类型化错误ReportedTestFailuresErrorinternal/xcode/test.go区分测试真的失败了与基础设施错误避免 JUnit 层双重计数。命令在所有平台上都出现在帮助与生成的文档中跨平台可见但只在装有可用 Xcode 的 macOS 上真正执行。它不需要 App Store Connect 凭证或网络因此非常适合作为本地测试闸门。测试与质量保障计划设计文档的验证计划在仓库中落地为三层RED 覆盖CLI 测试internal/cli/xcode/test_test.go 覆盖命令发现、动作专属 flag 校验、可重复 destination 与过滤器、输出格式、错误流与 usage 退出码测试名如TestXcodeTestPassesTypedOptionsAndPrintsJSON、TestXcodeTestValidationErrorsAreUsageErrors、TestXcodeTestRejectsAuthenticationPassthroughUsageErrorsBeforeChild直接对应上述契约核心单测通过注入的进程与解析器接缝runXcodeTestCommand、readTestResultSummaryFn、SetSimulatorListLoaderForTesting、SetXCResultSummaryLoaderForTesting等覆盖精确 argv 生成、结果包路径分配与碰撞保护、动作失败、取消、汇总解析、有界失败详情与 JUnit 转换——包括TestXcodeTestJUnitSynthesizesAggregateFailuresBeforeFillingCap、TestXcodeTestJUnitKeepsInfrastructureRowWhenReportHasNoFailure这类边界场景完整门禁与实机校验全量门禁为make build、make format、make check-docs、make lint、ASC_BYPASS_KEYCHAIN1 make test在装有完整 Xcode 的主机上实机检查覆盖一次通过运行、一次失败运行、build-for-testing 后接 test-without-building、多目的地、测试过滤、JUnit 输出并确认源码文件保持不变不修改工程。设计取舍与备选方案设计文档最后给出了被否决的替代路线解释了为何需要一个专门的类型化命令只加原始--xcodebuild-flag逃生舱虽然能触达测试动作但无法提供选择器/路径校验、结构化输出、产物保护结果包路径防覆盖、防符号链接与稳定的退出契约扩展asc xcode build去推断测试动作会让既有 build 结果失真破坏其动作不变量一次构建只对应一个明确动作专门的类型化命令让编译与测试语义各自显式同时复用已有的本地进程管理与渲染基础设施——这正是当前asc xcode test的定位。一句话总结asc xcode test把本地测试做成了与远端发布同级的、可脚本化、可机器消费的一等公民能力。想深入理解或二次开发建议从 xcode-test-command.md 设计文档出发对照 internal/cli/xcode/test.go 的参数注册与输出渲染、internal/xcode/test.go 的校验与解析内核、internal/cli/xcode/test_test.go 的契约测试逐步阅读。赞分享【免费下载链接】App-Store-Connect-CLIFast, scriptable CLI for the App Store Connect API. Automate TestFlight, builds, submissions, signing, analytics, screenshots, subscriptions, and more项目地址https://gitcode.com/gh_mirrors/ap/App-Store-Connect-CLI点击查看免费下载相关推荐App-Store-Connect-CLI 的 Xcode PKG 导出支持asc xcode export --pkg-path 设计解析App Store Connect CLI 的 Xcode PKG 导出支持 asc xcode export pkg path 设计解析 导读 macOSApp-Store-Connect-CLI 的 asc xcode install向已连接 iOS 真机安装本地 IPA 的完整设计解析App Store Connect CLI 的 asc xcode install 向已连接 iOS 真机安装本地 IPA 的完整设计解析 asc xcodeApp Store Connect CLI 驱动 Xcode本地 build、archive、export 与 xcode test 结构化结果完整指南App Store Connect CLI 驱动 Xcode本地 build、archive、export 与 xcode test 结构化结果完整指南 Ap上一篇游戏NAT类型如何变成FullConeturboacc全锥形NAT实战指南附IPv6前缀代理与NAT类型检测下一篇揭秘DJI无人机通信DroneSecurity如何解码Drone-ID协议创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表