ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

芯片测试程序版本管理:目录结构设计的四道坎

2026/9/6 9:53:44 拓冰建站 浏览量
芯片测试程序版本管理:目录结构设计的四道坎 接手旧测试程序的那天我就知道这个“烂摊子”不好收拾。甲方给的加密驱动盘里装着一个跑了几年的芯片测试程序目录里密密麻麻堆了三四层文件夹名字从“FINAL_v2”到“FINAL_v3_real”再到“final_new_2024”…文件混着测试数据、日志、临时改的.bin、机台上导出的.csv还有好几个不知道干嘛用的旧配置。最让人崩溃的是程序里每个测试项对应的限值文件散落在不同子目录换一台机型就得手动改路径。机器上跑的版本和页面里保存的版本根本对不上。那次之后我花了大半年把手里所有芯片测试程序包全部重构成了公司内部的标准化目录顺手把版本管理也彻底理顺了。这个“二”我想专门聊聊目录结构这件事。芯片测试程序要做版本管理第一关从来不是学会几条git命令而是先把目录结构设计清楚。一台ATE上跑的测试程序动辄几百个文件测试项、限值、校准文件、机台配置、数据采集脚本全都挤在一起。目录结构如果一开始就是乱的后面无论你用多好的版本管理工具都只能把混乱备份得更好一点而已。目录结构这件事我总结下来要过四道坎。这四道坎看起来都不起眼但每一道都决定了你的版本库能不能长期健康地活下来。1. 第一道坎顶层目录按产品线划分还是按测试平台划分很多测试工程师第一次搭目录结构时纠结的本质就一句话最上层这一级到底放产品型号还是放测试平台如果你是做定制芯片的一个型号对应一条产品线测试程序基本只在一种平台上跑那按产品线划分会很直观目录顶层就是产品型号里面再放需要的东西。但问题是芯片公司通常不会这么简单。同一个产品可能有多个量产节点不同节点又可能用不同厂商的ATE甚至同一款芯片会从开发验证阶段的实验室机台转到量产阶段的量产机台。这时候最上层的划分逻辑一旦选错整个目录就非常别扭。按平台划分你会发现同一个产品的程序散落在好几个平台目录下做版本管理时根本没法把一个产品的完整程序一次性打成一个基线按产品划分平台相关的公共配置又会在不同产品目录里重复出现改一处忘一处。两种方案我都不打算直接否定我推荐的做法是“产品线优先平台作为第二级分支”第一级固定为产品线或产品型号这是所有版本管理、项目代号、评审编号的统一入口。第二级固定为测试平台或测试方案程序相关的源码、工程文件放这个层级。第三级才是功能模块比如source、spec、config、data、release这一层。这种结构的核心思路是产品线是相对稳定的业务实体而测试平台的更换、升级、并存只是产品生命周期里的一个变量。代码、数据可以跟着平台变但产品线这个锚点不能变。版本库里的主干、标签、分支都围绕产品线来组织平台差异只体现在子目录中。实际跑下来你会发现在做release包、做客户交付、做跨部门协作时这个顶层非常省事。1.1 两种顶层划分方案的利弊对照我先用一个表把两种方案的真实感受列出来很多细节是踩过坑才看得见的维度按产品线划分推荐按测试平台划分版本基线完整性一个产品一个仓库目录基线清晰产品程序散落多平台基线难定义平台升级影响平台升级只影响对应二级目录可单独升级顶层目录就需要整体重构跨产品复用共享代码需单独建公共仓库管理略复杂平台公共库天然集中复用方便新项目启动复制产品模板即可上手快按平台入口找东西但产品内聚性弱多项目中后期长期维护友好release追溯容易换平台时方案越用越乱如果你的公司测试平台非常统一所有产品都用同一种机台那按平台划分短期内也能跑还算顺手。但只要产品一多你会遇到一个特别尴尬的场景同一款产品在研发阶段和量产阶段用的机台不一样两边程序都要维护你在平台目录下再按产品分还是在产品目录里再按平台分怎么分都很别扭。所以我还是建议一开始就按产品线划分把平台差异降为第二级子目录。1.2 我建议的顶层目录实例直接给一个我已经用了两年、目前还比较舒服的目录骨架示例Product_A/ # 产品线版本库根目录 ├── src/ # 测试程序源码跟随版本管理 │ ├── common/ # 产品内公共代码、复用函数 │ ├── platform_advantest/ # 指定平台的测试程序工程 │ │ ├── testsuite/ # 测试项序列 │ │ ├── testmethod/ # 测试方法封装 │ │ └── device_interface/ # 设备接口层 │ └── platform_teradyne/ # 另一平台的测试程序工程 ├── spec/ # 测试规格、限值文档 ├── config/ # 机台配置、校准参数模板 ├── data/ # 测试数据、日志不入库见第二道坎 ├── release/ # 已发布版本归档 │ ├── v1.2.0/ │ └── v1.3.0/ └── docs/ # 设计文档、变更说明这套结构的关键点有两个。一是该产品线内所有平台的测试程序都放在同一个版本库里编程序、做测试、写文档的人永远从同一个入口进场。二是release目录保留了“发布快照”每个版本对应一份可追溯的归档这比在git里翻历史标签更直观尤其是当现场需要紧急回退时可以直接把历史版本拷到机台上不用重新拉代码再编译。我当时把所有库迁移到这个结构之后最大的感受是讨论问题的时候不再说“那个文件在某某机台的某某目录下”而是直接说“A产品线的spec里”。版本管理也是一样打tag、开分支、做审查全都在一个库里完成省掉了跨库关联的无数沟通成本。2. 第二道坎程序文件和数据文件哪些该进仓库目录结构确定之后第二个常见问题就是版本库里一片混乱什么文件都往里塞。芯片测试程序有个特点每天跑完测试都会产生大量现场数据——这包括stdf、dat、csv、日志文件、机台自动保存的备份文件、临时生成的波形图、良率汇总等。这些东西如果和测试程序源码放一起并且一股脑提交到版本库里两三个版本之后仓库体积就会膨胀到不可收拾。提交历史里夹杂着一堆几MB甚至几十MB的数据文件clone一次仓库慢得像下电影diff查看代码变更时也被大量二进制数据干扰。这里面的边界很多人其实不是不知道而是没有坚决执行。我的原则就三条能自动再次生成的文件一律不进版本库。数据文件和源文件必须物理隔离即使都在本地目录里也要分别放在data、log和src、config下。为应付审计或追溯而需要保留的数据进独立的存储系统或免密带库绝不进代码仓库。2.1 一份“干净”的测试程序包由哪些文件组成我做过一个内部培训列过一张“测试程序包文件清单”。这里直接分享出来可以作为初筛的依据类别进版本库典型文件测试源码是testmethod、testsuite、UI定义、工程文件公共库代码是common函数、API封装、基础库测试规格/限值文档是spec文档、limit模板机台配置模板是配置文件、参数文件、默认模板校准参数是需版本管理校准文件、Setup文件测试记录的原始数据否stdf、dat、日志、波形文件临时脚本/中间产物否临时修复用脚本、生成的临时文件发布包归档是release目录下的正式版本压缩包校准参数这条很多人会犹豫觉得它跟现场机台强相关不该入库。我的看法是校准参数恰恰是最需要版本管理的因为芯片测试现场经常出现“同一条线不同批次校准完结果不一样”的情况。把校准参数做成一个带版本、带生效日期的文件入库出现问题就可以快速回溯是不是校准参数变化导致的。但注意入库的是校准参数的“模板和配置”而非每批实时产生的校准曲线数据那些实时数据还是走数据存储。2.2 .gitignore 的实战配置如果说清点文件是目录结构设计的一部分那落地就靠.gitignore。Git本身不会主动忽略任何文件你不写规则它就把所有文件都当作跟踪对象。下面是我通常在芯片测试程序仓库里使用的.gitignore模板你可以直接裁剪使用# 数据与日志 *.stdf *.dat *.csv *.log *.txt.bak # 机台自动备份文件 *.bak *.tmp *.swp # 本地临时文件 temp/ tmp/ *.pyc __pycache__/ # 系统/工具生成 .DS_Store Thumbs.db .idea/ .vscode/这里有个细节很多人会忽略测试程序目录里经常有“机台会主动生成”的目录结构比如泰瑞达机台自动生成的tmid、日志目录爱德万测试台生成的result目录等。一定要提前观察清楚在.gitignore里一并忽略否则每次一跑测试git status就会一片红干扰你判断真正的变更。另一个值得注意的点是.gitignore只对“尚未被跟踪”的文件生效。如果一开始就误把数据文件提交进去了后面再加ignore是拦不住的必须先git rm --cached把文件从索引移除。这也是我为什么反复强调目录设计要在一开始就做对补课永远比欠课痛苦。2.3 大文件与二进制文件的处理思路芯片测试程序仓库里总有那么几个无论如何都要提交、但又奇大无比的文件比如某些加密的测试向量文件、仿真模型、特定平台下的库文件。这种文件用普通git管理会越来越痛苦。我的经验是能拆则拆不能拆就单独用Git LFS管理。Git LFS的思路很简单把大文件用指针替换入库实际内容存到LFS存储。本地clone时自动拉取必要文件仓库本身不会无限膨胀。如果你还在用老的git大文件管理模式仓库体积已经大到每改一行代码都要等半天那我建议尽早迁移到LFS。向团队推LFS时尽量把门槛降低直接在仓库根目录加一个.lfsconfig文件把LFS的URL固定好新人拉下来就能用。3. 第三道坎公共代码库的归属问题芯片测试程序里总有这么一块代码负责和机台通信的低层封装通用的开关矩阵驱动数据处理函数库甚至工程师自己写的一套“私房工具集”。这类公共代码很多项目都处理不好。处理不好就出现两种极端。一种是“人人自建”每个产品线都拷贝一份公共代码到自己目录下结果公共代码里修了一个bug其他产品线完全不知情继续用着有bug的旧版最后在产品表现上栽了跟头另一种是“人人共建”看着是公共目录其实谁都能改改坏了所有产品线一起遭殃最后公共代码变成“谁都不敢动”的重灾区。这个问题的本质是要把“复用”和“变更控制”这两件事分开。复用是为了提高效率变更控制是为了保证稳定。公共代码的维护者不能是所有使用者而应该是少数几个有权限的负责人。3.1 公共代码的两种管理模式对比IC测试程序的公共代码管理我实际见过两种比较靠谱的模式模式一公共代码独立仓库各产品线通过子模块引用。这种模式用git submodule把公共仓库挂到产品线仓库的某个目录下。好处是公共代码的版本管理很干净产品线锁定了一个特定的公共代码commit不会因为公共库更新而意外变化坏处是submodule的操作学习曲线陡峭新人经常忘记在拉取产品线仓库后同步子模块结果编译时用旧代码排查半天都发现不了。如果你团队的git水平参差不齐这个模式推行成本很高。模式二公共代码独立仓库产品线仓库通过自动化脚本在构建时拉取指定tag。这种模式名义上也是独立仓库但不引入submodule的复杂度。测试程序编译前执行一个脚本从公共仓库拉取特定版本的代码到本地工作目录。我目前在团队里用的就是这种每天CI构建时自动拉最新稳定tag总比团队成员手动同步靠谱。对比下来我的态度很明确如果你有专职的自动化构建环境上模式二如果你们还是以本地手动编译为主那模式一虽然麻烦但至少可控。3.2 公共代码仓库的目录设计公共库内部也要分目录不能一锅粥。我维护的公共代码仓库目录大致是这样的common_libs/ ├── api/ # 机台API封装层 ├── utils/ # 数据处理工具函数 ├── drivers/ # 仪表/探针台等驱动封装 ├── templates/ # 测试项模板、规范模板 └── docs/ # 引用说明、版本变更说明公共代码的目录设计原则和产品线仓库不太一样这里更强调“按功能分层”而不是“按项目组织”。因为公共代码的消费者是各个项目按项目分会造成同一个公共函数有多个拷贝失去公共库的意义。按功能分层每个功能模块内部再维护自己的变更历史使用者只需要关注自己用到的那部分API版本。这里还有一个小的经验补充公共代码库一定要维护一个CHANGELOG每次变更都要写清楚改了什么、影响哪些产品线、是否有破坏性变化。否则用产品线的人根本不知道公共库又更新了什么只能盲目升级升级完测试结果不对也无法定位。公共代码的变更说明重要性不亚于代码本身。4. 第四道坎配置文件漂移带来的版本错乱前面三道坎解决的是“放哪里”“哪些进库”的问题。配置文件的坑在于它的变化往往非常隐蔽改了之后不一定会立即报错只会让测试结果在某个边界条件下悄悄漂移。芯片测试程序里配置文件很多常见的有测试限值文件spec/limit文件定义了每一项测试的上下限机台配置参数如测试电压、电流量程、时序参数校准文件和校准系数Bin表映射测试结果分Bin的定义探针台、分选机通信参数。其中最容易出问题的就是测试限值文件和校准系数。限值文件被谁在某天随手改了一个数值跑出来的良率立刻变好大家还挺高兴量产几天后客户反馈有bad chip流出最后追查才发现是限值被改宽了。这种事故在芯片测试行业不是个别案例。版本管理能把变更记录下来但它解决不了“文件被改而不自知”的问题。要解决得从配置文件的生成和校验机制入手。4.1 配置文件的典型踩坑场景我见过最典型的场景是这样的量产线上某个产品的测试程序限值文件是直接在机台上打开手动编辑的。某天夜班工程师觉得某个测试项良率偏低顺手把下限从80改成了75保存关掉。第二天早班的高工发现测试程序跑出来的良率正常以为是产线优化了就没有深究。三天后出货抽检发现一颗边界芯片没过系统级测试追查下来发现就是那个限值改动导致的。配置文件在版本管理里确实留下了变更记录但问题在于它没有经过任何审批流程没有和“测试条件变更单”关联也没有在启动时做版本一致性检查。这个问题的根子在于配置文件和测试程序本身是“离线的”程序跑起来就读取本目录下的配置文件它无法判断这个文件是不是当前版本应该使用的文件。解决思路是说通俗点让“程序能自己识别配置文件的合法性”。4.2 配置文件的生成、校验与下发机制我推荐的机制是三层第一层配置模板进版本库作为唯一事实源。所有限值、参数模板都由负责人维护入库并打tag。任何人不得在机台上直接编辑最终配置文件。第二层通过脚本从模板生成实际配置文件自动加上版本号、生成时间和哈希值。生成的配置文件也进版本库但由于是生成物体积小入库没有问题或者作为release的一部分归档。这样做的好处是现场用的每一个配置文件都可以直接追溯到某个模板版本。第三层测试程序在启动时执行配置校验读取配置文件中的版本信息和哈希值如果版本不在允许的范围内直接拒绝启动并报错。这一步非常关键它确保机器上跑的程序一定是和当前产品基线匹配的版本。下面是一个简化的Python校验思路通常在ATE测试主程序初始化阶段调用import hashlib import json def verify_config(config_path, expected_version): with open(config_path, r) as f: config json.load(f) if config[version] ! expected_version: raise RuntimeError(fConfig version mismatch: expect {expected_version}, got {config[version]}) actual_hash hashlib.sha256( open(config_path, rb).read() ).hexdigest() if actual_hash ! config[sha256]: raise RuntimeError(Config file is tampered or corrupted.) print(Config verify PASS.)实际项目中你可能会在ATE测试项初始化的C语言或Java代码里做同样的事核心不变配置文件必须自带身份信息程序在运行前必须校验。能做到这一点配置文件的“漂移”问题就算真正堵住了。5. 版本管理的日常操作用 PyCharm 走通 SSH 链路目录结构设计好了配置文件机制也加了日常的版本管理操作才能真正落下来。这里我必须提一个很多人问过的问题如何在PyCharm里用SSH登录GitHub进行版本管理芯片测试工程师很多人用PyCharm来写测试代码但git操作经常还停留在网页端提交、本地命令行拉取的阶段。SSH配置好了以后你会发现用IDE做代码审查、提交、合并流畅度完全不一样。5.1 为什么用SSH而不是HTTPS芯片测试程序的代码仓库通常涉及商业保密。用HTTPS连接GitHub每次push都要输入用户名和token虽然有各种凭证管理器可以记住但在ATE控制器这种不能随便安装软件、网络策略又严格的机器上很容易出幺蛾子。SSH协议用密钥对做身份认证配置好后不用每次输密码也不依赖本地凭证管理器遇到网络代理也更稳定。实测下来SSH方式还有一个好处你可以把自己的私钥放在专门的安全目录里配合密码保护安全性比HTTPS token放在全局配置里要高一些。至少不会出现同事共用一台机台时不小心把token配置带出去的情况。5.2 从生成密钥到推送分支的完整流程我这里给一份当前主流的操作流程基于Windows或Linux都可以macOS也适用。第一步在本地生成SSH密钥对。打开终端执行ssh-keygen -t ed25519 -C your_emailexample.com建议一路回车使用默认路径比如~/.ssh/id_ed25519。如果你的测试环境有特殊安全要求也可以自定义密钥文件名但后续配置要对应起来。生成的密钥对中带.pub后缀的是公钥可以给别人看不带后缀的是私钥绝对不能泄露。第二步把公钥添加到GitHub账号。在本地执行cat ~/.ssh/id_ed25519.pub复制输出的内容到GitHub页面Settings - SSH and GPG keys - New SSH key粘贴保存。名字随意比如 “ATE-lab-machine”。第三步在PyCharm里配置SSH。打开PyCharm进入Settings/Settings - Version Control - Git确认SSH executable选择“Native”或“Built-in”。Native会调用系统ssh命令Built-in则用PyCharm自带的实现两种都可以但如果你本地自定义了~/.ssh/config选Native更保险。配置完成后回到PyCharm的欢迎页或VCS菜单选择“Clone Repository”把仓库的SSH地址复制进去比如gitgithub.com:yourcompany/yourtest.git输入仓库本地路径克隆下来。第四步验证连接。最稳的方法是在终端执行ssh -T gitgithub.com看到类似“Hi yourname! Youve successfully authenticated”的提示说明SSH链路已经通了。接下来你在PyCharm里做pull、push、fetch都不会再弹密码框。如果要推送到自己创建的分支直接在PyCharm右下角的分支菜单里新建分支提交后推送第一次推送需要选择“Push”并确认设置上游分支即可。5.3 日常协作分支、合并、冲突处理目录结构设计解决的是“文件放在哪里”SSH解决的是“版本库怎么连”但真正让版本管理运转起来的是规范的协作流程。我的建议是长期维护的产品线仓库使用简化版Git Flowmain分支永远保持可发布状态develop分支是日常集成分支每个功能或修复任务从develop拉一个feature/xxx分支。开发完成后通过PyCharm的Merge Request或直接在本地合并再推到远端。对于芯片测试程序这类需要频繁跑机台验证的项目分支数量不需要太多多了反而乱。真正容易出现问题的场景是合并冲突。在PyCharm里冲突文件会红色高亮右键选择“Resolve Conflicts”可以手动对比左右两侧内容。芯片测试程序最容易冲突的文件就是配置文件、限值文件和测试项序列文件。为了减少这类冲突我强烈建议多人改同一文件时遵循“按目录隔离”原则你不要动我在做的测试项我也不动你的配置文件高频率把远端变更同步到本地不要攒一个月的修改再一次性合并配置文件一旦生成尽量以自动脚本维护不要手工改避免冲突。6. 常见问题与排查技巧实录目录结构和版本管理实践过程中我积累了不少“疑难杂症”的排查经验。挑一些高频问题列表整理出来方便你直接对照处理。6.1 目录结构类问题速查表症状可能原因处理办法每个工程师的目录结构都不一样没有统一的模板和规范制定目录模板用脚手架脚本一键初始化版本库文件越拉越慢体积几十GB数据文件、日志误入库用Git LFS迁移大文件把数据目录加入ignore公共代码被误改全产品线受影响公共目录没有变更控制公共代码独立仓库限制写权限走审批程序在机台上找不到配置文件配置文件放在与程序分离的路径统一配置目录程序启动时用相对路径定位release目录越来越乱无法判断哪个是正式版本没有版本命名规范使用v主版本.次版本.修订号固定归档结构这些问题里最要命的是“每个工程师的目录结构都不一样”。这个问题的可怕之处在于它会让版本管理的其他一切工作都变成无效投资。我在团队里做过一次插件化和标准化把目录模板做成一个小工具执行一条命令就能生成一个符合规范的项目骨架最终逐步消灭了手工建目录的差异。6.2 版本管理操作类问题速查表症状可能原因处理办法PyCharm Clone时提示Permission denied (publickey)SSH公钥未配置或私钥路径不对重新检查公钥是否已添加到GitHubssh-add确认密钥提交后发现某个数据文件不想入库文件已经跟踪用ignore已拦不住git rm --cached filename再添加至.gitignore合并时conflict太多越解越乱分支长期未同步多个改动交织先abort再pull最新代码重新基于最新分支修改误删了本地更改没有commit文件已被git跟踪但改动丢失用Local History或IDE的本地历史恢复极端情况用git fsck测试程序在机台上无法回退到上一版本release没有归档只有源代码建立release目录每个正式版本打tag并归档压缩包这里特别强调一下“误删本地更改”的恢复。PyCharm自带的Local History功能非常好用哪怕你没有commit只要文件在本地有历史版本就能在右键菜单里打开Local History找到之前的版本。这个功能救过我好几次建议所有用PyCharm写代码的工程师都养成习惯重要改动在动手前先复制一份备份。6.3 实操中容易忽略的几个细节最后分享几个我踩过坑之后形成的固定习惯。第一提交信息必须写清楚“为什么”而不仅仅是“改了什么”。比如“修改open短路测试限值”就比“改limit文件”有用得多。版本管理的历史记录是给人看的好的提交信息能让你三个月后翻记录时一眼就明白当时的意图。第二测试程序的版本号和芯片硬件版本、测试软硬件配置最好打在一个统一的mindset里。也就是说你的发布版本号不能只代表程序源码还要能追溯到它适用于哪一批芯片的哪个设计版本、哪种校准配置。这样的话现场反馈一个异常你可以快速定位到底是硬件版本不匹配、程序版本落后还是配置漂移。第三目录结构不是一成不变的但变更要走“重命名”而不是“另建一套”。很多人觉得目录不好用第一反应是重新建一套更好的目录然后做拷贝迁移。这样做的后果是历史版本和旧目录完全脱节版本管理彻底失效。正确的做法是在版本管理库内部执行目录重命名让git记录追踪到文件历史确保旧分支也能正确对应。第四在ATE机台上建议同时初始化好.gitignore和SSH配置。因为现场调试经常会在机台上直接改代码如果机台上的环境没配置好每次修改都没有版本记录风险极大。我自己是每台常用机台都配好了开发环境、SSH密钥和git全局用户信息目的就是让现场调试的行为也能被版本管理覆盖。芯片测试程序的版本管理说到底是一场和混乱作斗争的工程实践。目录结构就是这场斗争的主战场。四道坎每一道都不是那种今天改完明天就见效的事但只要坚持做下去你会明显感觉到项目交接不再靠一张嘴release包不用再解压三遍找文件出了异常不用再满机台翻旧文档。这种踏实的掌控感是版本管理带给测试工程师最大的回报。