You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对随机几何函数进行单元测试?

几何随机点生成函数的黑盒单元测试方案

针对这类生成几何图形内随机点的函数,黑盒测试可以从边界合法性、分布均匀性、辅助功能验证三个核心维度展开,完全不依赖内部实现细节:

一、边界合法性测试(硬约束校验)

这是最基础的测试,确保所有生成的点严格落在目标图形的内部或边界上,只要有一个点不符合就判定失败。

针对不同图形的校验逻辑:

  • 矩形:对生成的点(px, py),验证 x ≤ px < x+width 且 y ≤ py < y+height(因为random()返回[0,1),所以结果是左闭右开区间)
  • 圆形:计算点到圆心的距离 d = sqrt((px-centerX)² + (py-centerY)²),验证 d ≤ radius
  • 线段:设线段两端点为A(x1,y1)、B(x2,y2),验证:
    1. 点P在线段的包围盒内:min(x1,x2) ≤ px ≤ max(x1,x2) 且 min(y1,y2) ≤ py ≤ max(y1,y2)
    2. 向量AP与AB的点积≥0,且向量BP与BA的点积≥0(确保点在线段的参数范围内)
  • 三角形:设三个顶点为A、B、C,计算点P的重心坐标权重,验证三个权重均≥0且和为1;或者验证点在三条边的内侧(通过叉积判断方向)
  • 椭圆:代入椭圆方程 ((px-h)/a)² + ((py-k)/b)² ≤ 1((h,k)为中心,a、b为半长/短轴)

测试步骤:

  1. 生成大量样本点(建议104~105个,平衡测试速度和覆盖度)
  2. 对每个点执行对应图形的边界校验逻辑
  3. 若存在任意一个点不满足约束,测试直接失败

二、分布均匀性测试(随机性核心验证)

黑盒下无法直接看内部随机数调用,只能通过统计方法验证点的分布是否符合「图形内均匀分布」的预期:

1. 直方图卡方检验

  • 将目标图形划分为等面积的子区域(比如矩形分成10×10的网格,圆形分成5个环形+8个扇形的组合)
  • 统计每个子区域内的点数量,计算实际频率
  • 用卡方检验判断实际频率与理论均匀分布(每个子区域预期点数=总点数/子区域数)的差异是否在可接受范围内(卡方值小于临界值则通过)

2. 累积分布函数(CDF)校验

针对图形的一维特征验证分布:

  • 矩形:提取所有点的x坐标,其CDF应该是[x, x+width)上的线性函数。将x坐标排序后,计算累积比例,与理论CDF对比,用KS检验判断是否符合均匀分布
  • 圆形:提取点到圆心的距离r,由于均匀分布的圆形随机点满足r²服从[0, radius²)的均匀分布,验证r²的CDF是否为线性函数即可

3. 蒙特卡洛面积验证

利用随机点的均匀性估算图形面积,与理论值对比:

  • 用一个已知面积的简单图形(比如矩形)完全包围目标图形
  • 生成大量点,统计落在目标图形内的比例,乘以包围图形的面积得到估算面积
  • 验证估算面积与理论面积的误差在置信区间内(比如95%置信度下误差≤1%)

三、辅助功能测试

  • 输出对象复用验证:传入自定义的Vector2实例作为out参数,验证函数返回的是同一个实例,且其x/y属性被正确修改
  • 边界参数测试:传入极端参数(比如width=0、radius=0),验证函数返回合法点(比如矩形返回(x,y),圆形返回圆心)
  • 可选:确定性Mock测试:如果测试框架允许mockrandom()函数的返回值,可以验证特定输入下的输出(比如random()返回0时,矩形返回(x,y),圆形返回圆心)

示例测试代码片段(以矩形函数为例)

// 边界合法性测试
test('randomPointInRectangle returns points within bounds', () => {
  const x = 10, y = 20, width = 30, height = 40;
  const sampleCount = 10000;
  
  for (let i = 0; i < sampleCount; i++) {
    const point = randomPointInRectangle(x, y, width, height);
    expect(point.x).toBeGreaterThanOrEqual(x);
    expect(point.x).toBeLessThan(x + width);
    expect(point.y).toBeGreaterThanOrEqual(y);
    expect(point.y).toBeLessThan(y + height);
  }
});

// 分布均匀性测试(x坐标均匀性)
test('randomPointInRectangle x-coordinate is uniformly distributed', () => {
  const x = 0, y = 0, width = 100, height = 100;
  const sampleCount = 10000;
  const bins = 10;
  const binSize = width / bins;
  const counts = new Array(bins).fill(0);
  
  for (let i = 0; i < sampleCount; i++) {
    const point = randomPointInRectangle(x, y, width, height);
    const binIndex = Math.floor(point.x / binSize);
    counts[binIndex]++;
  }
  
  // 卡方检验简化版:预期每个bin有1000个点,允许±10%误差
  const expected = sampleCount / bins;
  counts.forEach(count => {
    expect(count).toBeGreaterThanOrEqual(expected * 0.9);
    expect(count).toBeLessThanOrEqual(expected * 1.1);
  });
});

内容的提问来源于stack exchange,提问作者HankMoody

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 07:36:02