☰
AI 说“完成”后,我又跑了 52 项关键测试:用华为云码道 CodeArts 打磨 HarmonyOS 旅行清单
2026/10/6 8:07:18 网站建设 项目流程

一键开通华为云码道 CodeArts 代码智能体

先看结果:这不是停在提示词里的 Demo

如果只看 Agent 页面,这个项目曾多次显示“任务完成”;但如果按真实工程标准检查,它还经历了 API 不兼容、状态刷新不及时、数据库字段迁移、补丁夹带反向修改等问题。真正的完成,不是生成了代码,而是应用能够构建、能够运行、数据能够保存、问题能够复现和回归。

最终交付结果如下:

指标结果
应用形态HarmonyOS NEXT 原生 Phone 应用
开发过程10 个可独立验证的阶段
关键回归测试Stage5、Stage8、Stage9 合计 52 项全部通过
数据层InMemory 与 relationalStore 两套 Repository 实现
工程验证ArkTS 编译通过,Debug HAP 构建成功
设备验证创建、生成、勾选、进度、自定义、删除和持久化全部通过
开源交付AtomGit公开源码、README、运行截图和 MIT License

图 1:应用不是静态原型。首页能够读取已保存行程,显示交通方式、日期、完成数量和进度条,并可继续进入详情页操作。

本文不只展示“AI 生成了什么”,更复盘我如何使用华为云码道 CodeArts Agent 完成需求拆分、跨文件实现、测试补齐和 UI 优化,以及如何识别并修正不能直接进入正式分支的生成结果。

一、项目背景

每次出门旅行,我都会遇到一个看似简单但很容易出错的问题:到底该带什么?证件、衣物、洗护用品、充电设备和常用药品分散在不同的备忘录里,旅行天数、交通方式和活动安排不同,所需物品也会变化。如果只使用一张静态清单,不仅容易漏项,也无法直观看到整理进度。

因此,我使用 HarmonyOS NEXT 和 ArkTS 开发了“旅行物品清单助手”。用户输入目的地、出发日期、返回日期、交通方式和活动类型后,应用会根据规则自动生成分类清单;用户可以勾选物品、查看完成进度、添加自定义物品,并通过本地关系型数据库保存行程和勾选状态。

这次开发没有让 AI 一次性生成整个项目,而是借助华为云码道 CodeArts Agent 将任务拆分成多个可验证阶段。每一阶段都经过代码审查、补丁检查、本地编译、单元测试和设备运行验证。这样的流程比“生成后直接运行”更稳妥,也更接近真实项目开发。

图 2:CodeArts Agent 已连接公开的 AtomGit 项目StarsAbc987/TravelChecklist。截图保留项目与账号信息,用于证明参赛开发链路。

二、最终实现的功能

应用目前包含以下核心能力:

  • 创建、查看和删除旅行行程;
  • 手动输入日期或使用系统日期选择器;
  • 校验日期格式、无效日期及返回日期先后关系;
  • 根据交通方式、活动类型和旅行天数生成清单;
  • 按证件、衣物、洗护、电子设备、药品和其他六类展示物品;
  • 支持自定义交通方式和自定义活动;
  • 支持添加、删除自定义物品;
  • 勾选清单后实时更新分类进度、总进度和进度条;
  • 使用 relationalStore 保存行程、清单及勾选状态;
  • 支持浅色、深色两套鼠尾草绿色主题。

图 3:创建页同时支持标准选项和“其他”自定义输入;日期既可手动输入,也可以调用系统日期选择器。

三、技术架构

项目采用分层结构,避免页面直接操作数据库:

层级主要职责
Model定义 Trip、ChecklistItem、交通方式、活动类型和清单分类
Repository定义行程与清单的数据访问接口,并提供内存和数据库两套实现
Service处理日期校验、行程创建、清单生成和业务编排
ViewModel为页面提供状态、进度计算和用户操作入口
ArkUI 页面与组件展示行程列表、创建表单、详情页和清单分类
DataAccessor封装 relationalStore 的增删改查和 ResultSet 生命周期

这种设计带来的直接收益是可测试性。早期阶段可以使用 InMemory Repository 快速验证领域逻辑,数据库接入后再切换到 RelationalStore Repository,而上层 Service 和 ViewModel 不需要重写。

四、使用华为云码道完成分阶段开发

我将整个项目拆分成十个阶段,每个阶段只解决一个主要问题:

阶段主要工作
Stage 1建立领域模型、枚举、日期工具和错误类型
Stage 2实现内存版 Trip 与 Checklist Repository
Stage 3实现基于规则的清单生成服务
Stage 4完成应用服务和业务编排
Stage 5完成 ViewModel、页面、组件和导航
Stage 6接入 relationalStore,实现本地持久化
Stage 7完善空状态、校验反馈和发布体验
Stage 8增加日期选择器、自定义输入、图标和进度刷新
Stage 9加固数据库异常处理和迁移逻辑
Stage 10整理 README、构建说明和最终交付检查

在每个阶段,我都会要求 CodeArts Agent 先读取现有代码,再给出修改范围,避免无关文件被改动。交付时生成独立分支或补丁,不直接覆盖main。本地确认无误后再合并,这使每一步都有清晰的 Git 记录,也便于定位回归问题。

为什么要拆成十个阶段,而不是一次性要求“帮我做一个旅行清单应用”?原因有三点:

  1. 上下文可控:每轮只让 Agent 聚焦一个层级或一种风险,减少跨文件修改时遗漏旧约束;
  2. 回归可定位:每个阶段都有独立分支、提交或补丁,出现问题时能够快速定位引入点;
  3. 验收可量化:业务能力、数据库迁移、输入体验和 UI 优化分别验收,避免“页面能打开”掩盖数据层问题。

以 Stage 8 为例,它不是简单增加两个输入框。Agent 需要同时理解日期工具、数据模型、Service、ViewModel、Repository、数据库字段、页面状态和测试 Mock。执行前先读取 23 个相关文件,再按计划修改;结束后检查差异、提交记录和补丁可应用性。这个过程让我看到 CodeArts 在跨文件理解上的效率,也让我更重视任务边界和最终差异审查。

图 4:安全裁剪后的 CodeArts 执行过程。可见分支/工作区检查、文件读取、执行计划、修改、git diff --check与提交步骤;认证信息未纳入图片。

五、核心实现一:基于规则生成旅行清单

清单生成器会按“基础物品→交通方式→活动类型→旅行天数”的顺序合并规则,再按物品名称去重。这样,同一个物品即使被多条规则命中,也只会出现一次。

generate(trip:Trip):ChecklistItem[]{constallRuleItems:RuleItem[]=[];this.appendItems(allRuleItems,getBaseItems());this.appendItems(allRuleItems,getTransportItems(trip.transportType));for(leti=0;i<trip.activityTypes.length;i++){this.appendItems(allRuleItems,getActivityItems(trip.activityTypes[i]));}constdays:number=calculateTripDays(trip.departureDate,trip.returnDate);this.appendItems(allRuleItems,getDaysItems(days));// 后续按名称去重、按分类排序并生成 ChecklistItem// ...}

生成逻辑不直接依赖页面和数据库,同时支持注入固定 ID 和固定时间。因此测试时可以得到稳定、可重复的结果,不会因为随机 ID 或当前时间不同而失败。

六、核心实现二:勾选后立即刷新进度

开发过程中遇到过一个真实问题:用户点击物品后,圆形选中状态发生变化,但总完成进度没有同步刷新。问题原因是写入仓储后,ViewModel 中的清单数组仍然是旧数据。

修复方式是在状态变更后重新读取当前行程的清单:

toggleItemChecked(itemId:string,isChecked:boolean):void{this.service.toggleItemChecked(itemId,isChecked);if(this.currentTrip!==undefined){this.checklistItems=this.service.getChecklist(this.currentTrip.id);}}

进度文本和百分比都从最新数组计算:

getTripProgressPercent(tripId:string):number{constitems:ChecklistItem[]=this.getProgressItems(tripId);if(items.length===0){return0;}constcheckedCount:number=items.filter((item:ChecklistItem)=>item.isChecked).length;returnMath.floor(checkedCount*100/items.length);}

图 5、图 6:同一行程的详情与勾选结果。这里验证的是状态写入之后界面是否真正读取到最新数组,而不只是按钮外观发生变化。

七、核心实现三:数据库迁移与资源安全释放

Stage 8 增加自定义交通方式和自定义活动字段后,旧数据库中并不存在对应列。如果每次启动都直接执行ALTER TABLE,第二次执行就会因为字段已经存在而失败。

最终方案是先通过PRAGMA table_info获取列集合,只对缺失字段执行迁移:

privatemigrateTripsTable(rdbStore:relationalStore.RdbStore):void{constexistingColumns:Set<string>=this.getTableColumns(rdbStore,'trips');if(!existingColumns.has('custom_transport')){rdbStore.executeSync(ALTER_TRIPS_ADD_CUSTOM_TRANSPORT);}if(!existingColumns.has('custom_activity')){rdbStore.executeSync(ALTER_TRIPS_ADD_CUSTOM_ACTIVITY);}}

查询表结构时,ResultSet 在finally中关闭;数据库初始化失败时将ready设为false,并允许页面回退到内存仓储。这个阶段让我体会到,AI 能快速生成数据库代码,但资源关闭、重复初始化和旧数据迁移必须单独设计和测试。

八、两次不能直接接受 AI 结果的经历

1. API 看起来合理,但当前 SDK 不支持

在优化首页标题时,CodeArts Agent 使用了.customTitle(...)。代码从语义上很自然,但本地 ArkTS 编译器提示NavigationAttribute不存在该属性。根据当前 SDK 的实际能力,最终改为:

.title(this.TitleBar())

修改后重新构建,ArkTS 编译与 HAP 打包才全部通过。这说明 API 是否可用必须由项目实际 SDK 和编译器确认,不能只依赖生成结果。

2. 名为“增量补丁”,实际夹带反向修改

在最后一次 UI 微调中,我只要求增加标题间距,并将六个分类按钮改成 3×2 网格。但 Agent 生成的补丁除了目标修改,还包含大量撤销现有绿色主题的反向差异。如果直接应用,已经完成的卡片圆角、颜色资源和列表布局都会退回旧版本。

最终我先查看git apply --stat和补丁内容,只提取两个目标 hunk,再执行git diff --check和 HAP 构建。这个案例说明,AI 辅助开发中“审查差异”与“审查最终代码”同样重要。

这次 UI 调整也采用同样的方法:让 Agent 明确列出修改文件、逐页视觉变化、未修改的业务范围、已执行的静态检查和当前环境不能执行的验证。CodeArts 工作空间没有项目所需的 HarmonyOS hvigor 工具,因此它没有伪造云端构建结果;真正的 ArkTS 编译、HAP 构建和设备运行由我在本地 DevEco Studio 完成。

图 7:交付报告把“已执行”和“未在当前环境执行”分开记录。对 AI 生成结果而言,这种边界说明比一句笼统的“任务完成”更可信。

九、测试与验证结果

项目没有把“Agent 显示任务完成”当作最终完成,而是使用本地 DevEco Studio 验证。

验证项结果
Stage 5 ViewModel 与页面行为测试13/13 通过
Stage 8 日期、自定义输入与交互测试23/23 通过
Stage 9 数据访问、迁移和异常测试16/16 通过
ArkTS 编译通过
Debug HAP 构建BUILD SUCCESSFUL
设备运行首页、创建、详情、勾选、删除、持久化均通过
深色模式通过

52 项关键测试不是为了凑数字,而是覆盖三个最容易回归的层面:

测试组数量主要覆盖内容
Stage 513ViewModel 初始状态、创建行程、打开详情、勾选、自定义物品、删除、进度与分类
Stage 823日期格式与有效性、自定义交通/活动、输入 trim、页面交互与进度刷新
Stage 916DataAccessor 正常/异常路径、ResultSet 生命周期、字段迁移、重复初始化与回退

图 8:先验证页面背后的状态与业务入口,避免只靠手动点按判断正确性。

图 9:新增输入体验后进行专项回归,23/23 通过。

图 10:数据层加固后的 16/16 测试结果。三组关键回归合计 52 项。

测试通过之后,我还按真实用户路径进行设备验收:创建行程、选择和手输日期、自定义交通与活动、生成六类清单、勾选物品、添加自定义物品、删除行程、退出重进检查持久化,并切换深色模式检查颜色与文字对比。单元测试负责快速发现逻辑回归,设备验收则负责发现导航、键盘、布局和系统组件等真实交互问题,两者不能互相替代。

十、最终界面与体验

最终界面采用鼠尾草绿色作为主要视觉语言。浅色模式以低饱和绿色和白色卡片为主,深色模式使用深森林绿背景,并保留足够的文字对比度。自定义物品区域使用两行三列等宽分类按钮,避免最后一个分类单独换行。

图 11:分类按钮调整为 3×2 等宽网格,“其他”不再孤零零换行;选中态使用更深的鼠尾草绿,信息层级更清楚。

图 12:深色模式不是简单反色,而是单独配置背景、卡片、边框、主文字、次文字与强调色资源。

这次视觉调整坚持一个原则:只改变呈现,不偷偷改变业务。Agent 的任务中明确禁止新增天气、倒计时、历史归档等不存在的功能,也不允许修改 Model、Repository、Service、ViewModel 和数据库。最终只调整颜色资源、标题区域、卡片圆角、按钮排列和间距。这样的约束让 UI 优化保持可审查、可回滚,也避免为了“看起来更丰富”而制造虚假功能。

十一、使用华为云码道后的实际体会

华为云码道 CodeArts Agent 最明显的价值不是“替我写完所有代码”,而是帮助我快速理解陌生项目、拆分阶段任务、生成跨文件实现和补充测试。在领域模型、仓储接口、测试 Mock 和重复性代码方面,它显著减少了机械工作量。

但要让项目真正落地,开发者仍然需要承担三个职责:第一,明确每轮任务边界;第二,检查补丁是否只包含预期修改;第三,在真实 SDK、真实设备和真实数据环境中验证。尤其是 HarmonyOS 与 ArkTS 的 API 版本、状态刷新和关系型数据库资源管理,仅凭静态代码看起来正确还不够。

对我而言,这次项目最大的收获不是生成了多少代码,而是形成了“需求拆分—Agent 实现—差异审查—本地测试—人工验收—独立提交”的稳定协作流程。

十二、开源地址

  • AtomGit公开仓库:https://atomgit.com/StarsAbc987/TravelChecklist
  • 技术栈:HarmonyOS NEXT、ArkTS、ArkUI、relationalStore
  • 开源协议:MIT License

仓库包含可运行源代码、README、构建和测试说明、应用截图及开源协议。欢迎交流和提出改进建议。

图 13:AtomGit 公开仓库已经补充项目介绍,并提供可运行源代码、README、应用截图、构建与测试说明及 MIT License,评审者可以据此复现并核对本文内容。

结语:AI 提速,工程判断兜底

如果让我用一句话概括这次实践:CodeArts Agent 把跨文件理解和实现速度往前推了一大步,而真实 SDK、测试结果、设备表现和 Git 差异决定项目能不能交付。

“AI 说完成”只是一次协作回合的结束,不是软件质量的终点。把需求拆小、让每次修改都有边界、保留可核查的提交、在真实环境中编译运行,再用测试覆盖最容易回归的路径,才是我从这次 HarmonyOS 项目中得到的最有价值的方法。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询