ARTICLE DETAIL

资讯详情

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

Harmony os 技术实战|拼豆制图30:从两个示例用例开始搭建算法回归网

Harmony os 技术实战|拼豆制图30:从两个示例用例开始搭建算法回归网 拼豆制图已经包含资源字符解码、70×70 像素量化、2×2 主色降采样、加权颜色距离、图例行数和稳定 ID 解析等逻辑但测试目录仍处于工程初始化状态本地测试只有一个assertContain用例设备侧测试也只有一个同名示例两者都在验证字符串abc包含b。这不是说应用逻辑无法验证而是当前很多算法被写成服务或页面里的private static、private方法测试入口尚未形成。本篇以真实现状为起点设计一条可执行的升级路线先提取不依赖系统能力的纯函数再用边界样本覆盖字符、透明度、颜色距离、分组和图例几何PixelMap、相册选择与媒体保存继续留在设备侧。文中的新增测试是建议实现不会把尚未执行的结果写成既成事实。一、先盘点当前到底有什么测试本地目录的唯一用例是it(assertContain,0,(){letaabc;letbb;expect(a).assertContain(b);expect(a).assertEqual(a);});设备侧Ability.test.ets也只有一个结构相同的用例额外输出一条hilog。因此当前基线可以准确描述为本地测试1 个 it2 个通用字符串断言 设备测试1 个 it2 个通用字符串断言 业务算法断言0明确基线很重要。只有知道当前是 0 个业务断言后续新增的每个用例才有清晰价值也不会把示例代码误当成已有保障。二、不要先测试页面先把纯计算从 private 中移出来当前高价值算法分散在三个位置位置典型逻辑当前可直接导入PatternRepository字符索引、统计、变体解析否核心方法为 privateImageConvertService白底混合、颜色距离、主色降采样否核心方法为 private staticIndex格子分行、当前图案解析否页面私有方法且带状态测试不应通过修改可见性去调用页面内部细节也不应为了验证一个公式启动整页。更稳妥的第一步是提取无副作用模块例如// common/PatternAlgorithms.etsexportfunctionassetColorIndex(token:string):number{/* ... */}exportfunctionlegendRows(colorCount:number,columns:number):number{/* ... */}exportfunctionblendWithWhite(value:number,alpha:number):number{/* ... */}exportfunctionweightedColorDistance(a:Rgb,b:Rgb):number{/* ... */}exportfunctionsplitCellsT(cells:T[],width:number):T[][]{/* ... */}服务层调用这些函数测试也导入同一份实现。这样测到的是生产代码而不是复制一遍公式后验证副本。三、第一组字符解码要覆盖合法区间和非法输入资源编码使用.、0-9和A-F。最小边界集应包含it(decodes asset tokens,0,(){expect(assetColorIndex(.)).assertEqual(-1);expect(assetColorIndex(0)).assertEqual(0);expect(assetColorIndex(9)).assertEqual(9);expect(assetColorIndex(A)).assertEqual(10);expect(assetColorIndex(F)).assertEqual(15);expect(assetColorIndex(G)).assertEqual(-1);expect(assetColorIndex(a)).assertEqual(-1);});A和F分别覆盖字母区间的首尾G覆盖上界之外小写a则确认协议区分大小写。仅测试0或A都无法证明边界正确。还应为整张资源增加结构扫描70 行、每行 70 字符、色板不超过 16 色、所有非点字符都能映射到色板范围。字符函数测试负责映射规则资源扫描负责实际数据两者不能互相替代。四、第二组图例行数必须盯住 4 到 5 的跳变四列图例的公式是exportfunctionlegendRows(colorCount:number,columns:number):number{returnMath.max(1,Math.ceil(colorCount/columns));}建议样本it(calculates four-column legend rows,0,(){expect(legendRows(0,4)).assertEqual(1);expect(legendRows(4,4)).assertEqual(1);expect(legendRows(5,4)).assertEqual(2);expect(legendRows(16,4)).assertEqual(4);});4 - 1与5 - 2是最重要的一对。如果有人把Math.ceil改成Math.floor16 色仍然会得到 4只有 5 色样本能立即暴露裁切风险。同时要决定非法列数如何处理。columns0会产生无穷值不能默默进入尺寸计算。纯函数应在入口返回错误或抛出明确异常并为0与负数各留一个用例。五、第三组透明度阈值要同时覆盖 15 和 16像素转换中alpha 小于 16 的像素被视为空格if(alpha16){returnemptyCell;}因此必须成对验证alpha 15 - 空格 alpha 16 - 先与白色混合再寻找最近色白底混合公式为Math.round((value*alpha255*(255-alpha))/255)固定样本可直接复算expect(blendWithWhite(10,255)).assertEqual(10);expect(blendWithWhite(10,0)).assertEqual(255);expect(blendWithWhite(10,128)).assertEqual(132);这三个值分别覆盖完全不透明、完全透明和中间透明度。随机选择几个 alpha 虽然用例更多却不如边界值容易解释。六、第四组加权颜色距离不能只测试“相同颜色为零”工程使用带红色均值修正的加权平方距离constredMean(redAredB)/2;return(2redMean/256)*redDiff*redDiff4*greenDiff*greenDiff(2(255-redMean)/256)*blueDiff*blueDiff;至少应验证四种性质同色距离为 0。交换 A、B 后结果相同。绿色通道差 10 的贡献为 400。输入靠近不同红色均值时红蓝权重按公式变化。示例consta{red:40,green:80,blue:120};constb{red:50,green:80,blue:120};expect(distance(a,b)).assertEqual(distance(b,a));expect(distance(a,a)).assertEqual(0);浮点结果不宜一律用整数相等可以比较绝对误差是否小于固定阈值。真正要防的是权重项、通道顺序或平方被误删。七、第五组2×2 主色降采样要固定平票规则70×70 图生成 35×35 预览时每个预览格读取一个 2×2 区块。dominantColorInBlock()统计各色出现次数并只在count bestCount时替换最佳项。这意味着平票时保留色板索引更小的颜色。建议覆盖[A, A, B, empty] - A [A, B, A, B] - A平票按色板顺序 [empty × 4] - null [B, B, B, A] - B平票行为必须写进测试名称否则未来有人把改为结果会从“前者优先”变成“后者优先”预览图会在大量 2:2 区块中出现不稳定色点。由于当前主色函数依赖私有色板可进一步把它改为接收paletteIds或已解析索引让纯函数不再读取服务的静态状态。八、第六组格子分行要先挡住 width0页面中的分行逻辑为for(leti0;icells.length;iwidth){rows.push(cells.slice(i,iwidth));}正常输入cells.length4900、width70会得到 70 行。但若width0且 cells 非空i 0会让循环永远无法前进。这正是纯函数测试能提前捕获的危险边界。提取后的入口应先保护if(width0){thrownewError(width must be greater than zero);}随后覆盖空数组 width 70 - 0 行 5 个格子 width 2 - [2, 2, 1] 4900 个格子 width 70 - 70 行每行 70 非空数组 width 0 - 明确失败不进入循环尾行[2,2,1]可以证明slice不会丢掉不足一整行的数据资源图则应在更早的结构校验中保证整除。九、统计函数要同时验证“色板颜色”和“可见颜色”countColors()会为色板中的每个颜色都生成统计项即使其计数为 0visibleColorCount()才统计count 0的项。用例应明确两种语义palette.length 3 cells 使用 A 两次、B 一次、C 零次 colorStats.length 3 visibleColorCount 2 countBeads 3如果只断言colorStats.length无法发现计数内容错误如果只断言可见颜色数又可能漏掉零计数项是否被保留。图例布局使用哪个数也应通过调用方用例明确下来。十、本地测试与设备侧测试的边界并不是所有逻辑都应该塞进本地测试。可以按依赖分三层本地 Hypium字符索引与资源结构扫描。图例行数和画布尺寸算式。alpha 白底混合、RGB 解析、颜色距离。2×2 主色选择、颜色统计、格子分行。种子 ID、顺序、热度与变体固定样本。设备侧 ohosTestPixelMap.readPixelsToBuffer()得到的 RGBA 通道顺序。图片解码、缩放和释放时机。相册选择器的成功与取消分支。媒体保存对话框与临时文件流程。PNG 打包器输入输出是否被系统组件接受。人工图像复核70×70 网格的十格粗线。三位色号是否溢出。16 色图例与页脚是否重叠。相册中实际保存文件的清晰度与方向。本地测试快且定位精确设备侧验证系统契约人工复核负责视觉结果。三层回答的问题不同不能用一张成功截图代替算法边界也不能用纯函数断言声称系统相册已经可用。十一、测试名称应该直接描述输入与规则与其继续使用assertContain更有价值的名称是assetColorIndex_returns15_forF legendRows_movesToSecondRowAtFiveColors alpha15_isEmpty_but_alpha16_isQuantized dominantColor_keepsLowerPaletteIndexOnTie splitCells_rejectsZeroWidth seedAnime6_reusesVariantZeroWithoutChangingId失败报告不打开测试源码就能看出是哪条契约变化。名称里包含边界值也能阻止后来者用更“普通”的样本替换掉关键输入。十二、从 0 个业务断言开始的落地顺序建议按风险与改造成本逐步推进新建纯算法文件先迁移字符索引、图例行数、白底混合和颜色距离。为每个函数补首尾、跳变与非法输入。迁移格子分行并增加width 0保护。把主色选择改成显式输入色板固定平票规则。增加 50 张资源的全量结构扫描。最后再补 PixelMap、相册选择和媒体保存的设备侧用例。每一步都应先让生产代码调用新函数再删除旧私有实现避免两份算法长期并存。完成后记录真实执行环境与结果未执行的设备路径仍然明确标注待验证。小结Harmony os 项目的测试升级不应从“给页面多点几次”开始。当前工程只有两个通用示例用例业务断言为 0最有价值的第一步是把字符解码、图例几何、alpha 混合、颜色距离、主色降采样和格子分行提取为可导入的纯函数。边界样本才是这张回归网的亮点4 到 5 色决定图例是否换行alpha 15 与 16 决定格子是否为空2:2 平票决定预览颜色width 0 决定循环能否结束。把这些真实分界固定下来再把 PixelMap 与相册能力留给设备侧测试就能从占位示例变成能够解释故障位置的工程资产。
返回列表