HarmonyOS开发:性能集成测试——性能场景测试

举报
Jack20 发表于 2026/06/24 16:28:58 2026/06/24
【摘要】 HarmonyOS开发:性能集成测试——性能场景测试📌 核心要点:单个模块的性能OK不代表集成后性能也OK——模块A耗时50ms,模块B耗时50ms,串行调用就变成了100ms。性能集成测试验证的是多模块协同场景下的性能表现,定位瓶颈,防止性能回归。 一、背景与动机你做过性能优化吧?把一个函数从100ms优化到50ms,心里美滋滋。但你有没有想过——这个函数被调用了10次呢?或者它和另一...

HarmonyOS开发:性能集成测试——性能场景测试

📌 核心要点:单个模块的性能OK不代表集成后性能也OK——模块A耗时50ms,模块B耗时50ms,串行调用就变成了100ms。性能集成测试验证的是多模块协同场景下的性能表现,定位瓶颈,防止性能回归。


一、背景与动机

你做过性能优化吧?把一个函数从100ms优化到50ms,心里美滋滋。但你有没有想过——这个函数被调用了10次呢?或者它和另一个50ms的函数串行执行呢?又或者它在循环里被调用了1000次呢?

单模块性能测试只告诉你"这个模块跑多快",不告诉你"集成后整体跑多快"。更关键的是,性能问题往往出现在模块交互的边界上——模块A返回了大量数据,模块B解析这些数据耗时飙升;模块C频繁调用模块D,D的锁竞争导致整体吞吐量下降。这些瓶颈,单模块测试根本发现不了。

性能回归也是个老大难问题——这个版本启动2秒,下个版本变成3秒,你都不知道是哪个模块拖慢了。没有性能基线,就没有回归检测。性能集成测试就是系统性地验证集成场景下的性能指标,建立基线,定位瓶颈,防止回归。


二、核心原理

2.1 性能集成测试体系

flowchart TB
    A[性能集成测试体系] --> B[多模块协同性能]
    A --> C[性能回归检测]
    A --> D[性能瓶颈定位]
    A --> E[资源消耗监控]

    B --> B1[串行调用链耗时]
    B --> B2[并发调用吞吐量]
    B --> B3[数据流转延迟]
    B --> B4[模块间通信开销]

    C --> C1[性能基线建立]
    C --> C2[版本间对比]
    C --> C3[自动化回归检测]
    C --> C4[性能趋势分析]

    D --> D1[耗时热点分析]
    D --> D2[内存分配追踪]
    D --> D3[IO瓶颈检测]
    D --> D4[锁竞争分析]

    E --> E1[CPU使用率]
    E --> E2[内存占用]
    E --> E3[网络流量]
    E --> E4[磁盘IO]

    classDef mainStyle fill:#4CAF50,stroke:#388E3C,color:#fff,font-weight:bold
    classDef collabStyle fill:#3498DB,stroke:#2980B9,color:#fff
    classDef regressStyle fill:#2ECC71,stroke:#27AE60,color:#fff
    classDef bottleStyle fill:#F39C12,stroke:#E67E22,color:#fff
    classDef resourceStyle fill:#9B59B6,stroke:#8E44AD,color:#fff

    class A mainStyle
    class B,B1,B2,B3,B4 collabStyle
    class C,C1,C2,C3,C4 regressStyle
    class D,D1,D2,D3,D4 bottleStyle
    class E,E1,E2,E3,E4 resourceStyle

2.2 性能指标分类

指标类型 具体指标 度量方式 关注点
响应时间 函数耗时、页面加载时间 毫秒 用户体验
吞吐量 每秒处理请求数 QPS 系统容量
资源占用 CPU、内存、磁盘、网络 百分比/字节 资源效率
稳定性 长时间运行内存增长 MB/小时 内存泄漏
一致性 多次执行耗时波动 标准差 性能稳定性

2.3 性能测试核心原则

  1. 可重复:同样的测试条件,结果应该一致(允许小幅波动)
  2. 可对比:有基线数据,能做版本间对比
  3. 可定位:性能问题能定位到具体模块和函数
  4. 可自动化:集成到CI流水线,每次提交自动检测

三、代码实战

3.1 基础用法:多模块协同性能测试

// PerformanceProfiler.ets - 性能分析工具
export interface PerformanceMetric {
  name: string
  duration: number        // 耗时(毫秒)
  startTime: number
  endTime: number
  metadata: Record<string, string>
}

export class PerformanceProfiler {
  private metrics: Array<PerformanceMetric> = []
  private startTimes: Map<string, number> = new Map()

  // 开始计时
  start(name: string): void {
    this.startTimes.set(name, Date.now())
  }

  // 结束计时并记录
  end(name: string, metadata?: Record<string, string>): PerformanceMetric {
    const startTime = this.startTimes.get(name)
    if (startTime === undefined) {
      throw new Error(`未找到计时器: ${name}`)
    }
    const endTime = Date.now()
    const metric: PerformanceMetric = {
      name,
      duration: endTime - startTime,
      startTime,
      endTime,
      metadata: metadata ?? {}
    }
    this.metrics.push(metric)
    this.startTimes.delete(name)
    return metric
  }

  // 获取所有指标
  getMetrics(): Array<PerformanceMetric> {
    return [...this.metrics]
  }

  // 获取指定名称的指标
  getMetricByName(name: string): PerformanceMetric | undefined {
    return this.metrics.find(m => m.name === name)
  }

  // 清空指标
  clear(): void {
    this.metrics = []
    this.startTimes.clear()
  }

  // 生成报告
  generateReport(): PerformanceReport {
    const totalDuration = this.metrics.reduce((sum, m) => sum + m.duration, 0)
    const avgDuration = this.metrics.length > 0 ? totalDuration / this.metrics.length : 0
    const maxDuration = Math.max(...this.metrics.map(m => m.duration))
    const minDuration = Math.min(...this.metrics.map(m => m.duration))

    return {
      totalDuration,
      avgDuration,
      maxDuration,
      minDuration,
      metricCount: this.metrics.length,
      metrics: [...this.metrics],
      hotspots: this.metrics
        .filter(m => m.duration > avgDuration * 2)
        .sort((a, b) => b.duration - a.duration)
    }
  }
}

export interface PerformanceReport {
  totalDuration: number
  avgDuration: number
  maxDuration: number
  minDuration: number
  metricCount: number
  metrics: Array<PerformanceMetric>
  hotspots: Array<PerformanceMetric>
}

// ==================== 多模块协同性能测试 ====================
import { describe, it, beforeAll, beforeEach, assertEqual, assertTrue } from '@ohos/hypium'
import { PerformanceProfiler, PerformanceReport } from '../PerformanceProfiler'

// 模拟业务模块
class DataRepository {
  async fetchUsers(): Promise<Array<{ id: string; name: string }>> {
    // 模拟数据库查询
    await new Promise<void>(resolve => setTimeout(resolve, 50))
    return [{ id: '1', name: '张三' }, { id: '2', name: '李四' }]
  }
}

class BusinessService {
  private repo: DataRepository

  constructor(repo: DataRepository) {
    this.repo = repo
  }

  async processUsers(): Promise<Array<{ id: string; displayName: string }>> {
    const users = await this.repo.fetchUsers()
    // 模拟业务处理
    await new Promise<void>(resolve => setTimeout(resolve, 30))
    return users.map(u => ({ id: u.id, displayName: `用户:${u.name}` }))
  }
}

class ViewModel {
  private service: BusinessService

  constructor(service: BusinessService) {
    this.service = service
  }

  async loadAndFormat(): Promise<string> {
    const users = await this.service.processUsers()
    // 模拟UI格式化
    await new Promise<void>(resolve => setTimeout(resolve, 10))
    return users.map(u => u.displayName).join(', ')
  }
}

export default function multiModulePerformanceTest() {
  describe('多模块协同性能测试', () => {
    let profiler: PerformanceProfiler
    let viewModel: ViewModel

    beforeAll(() => {
      const repo = new DataRepository()
      const service = new BusinessService(repo)
      viewModel = new ViewModel(service)
    })

    beforeEach(() => {
      profiler = new PerformanceProfiler()
    })

    it('完整调用链_各环节耗时记录', 0, async () => {
      profiler.start('total')
      profiler.start('repo.fetchUsers')
      const repo = new DataRepository()
      await repo.fetchUsers()
      profiler.end('repo.fetchUsers')

      profiler.start('service.processUsers')
      const service = new BusinessService(repo)
      await service.processUsers()
      profiler.end('service.processUsers')

      profiler.start('viewModel.loadAndFormat')
      await viewModel.loadAndFormat()
      profiler.end('viewModel.loadAndFormat')

      profiler.end('total')

      const report = profiler.generateReport()
      assertTrue(report.totalDuration > 0, '总耗时应大于0')
      assertTrue(report.totalDuration < 500, '总耗时应小于500ms')

      // 验证各环节耗时记录
      const fetchMetric = profiler.getMetricByName('repo.fetchUsers')
      assertNotNull(fetchMetric)
      assertTrue(fetchMetric!.duration >= 40, `数据获取耗时${fetchMetric!.duration}ms,应>=40ms`)
    })

    it('串行调用_耗时累加', 0, async () => {
      profiler.start('serial-total')

      // 串行调用3次
      for (let i = 0; i < 3; i++) {
        profiler.start(`call-${i}`)
        await viewModel.loadAndFormat()
        profiler.end(`call-${i}`)
      }

      profiler.end('serial-total')

      const total = profiler.getMetricByName('serial-total')
      const call0 = profiler.getMetricByName('call-0')
      const call1 = profiler.getMetricByName('call-1')
      const call2 = profiler.getMetricByName('call-2')

      assertTrue(total!.duration >= call0!.duration + call1!.duration + call2!.duration - 10,
        '串行调用总耗时应约等于各次调用之和')
    })

    it('并发调用_吞吐量测试', 0, async () => {
      const concurrency = 10
      profiler.start('concurrent-total')

      const promises = []
      for (let i = 0; i < concurrency; i++) {
        promises.push(viewModel.loadAndFormat())
      }
      await Promise.all(promises)

      profiler.end('concurrent-total')

      const total = profiler.getMetricByName('concurrent-total')
      assertTrue(total!.duration > 0, '并发调用应有耗时')
      // 并发总耗时应小于串行总耗时
      assertTrue(total!.duration < 1500, `10次并发总耗时${total!.duration}ms,应小于1500ms`)
    })

    it('热点分析_识别最慢环节', 0, async () => {
      profiler.start('repo')
      const repo = new DataRepository()
      await repo.fetchUsers()
      profiler.end('repo')

      profiler.start('service')
      const service = new BusinessService(repo)
      await service.processUsers()
      profiler.end('service')

      profiler.start('viewmodel')
      await viewModel.loadAndFormat()
      profiler.end('viewmodel')

      const report = profiler.generateReport()
      assertTrue(report.hotspots.length > 0, '应有性能热点')
      // 数据层通常是最慢的
      assertTrue(report.hotspots[0].duration > 0, '热点耗时应大于0')
    })
  })
}

3.2 进阶用法:性能回归检测

// PerformanceBaseline.ets - 性能基线管理器
export interface BaselineEntry {
  metricName: string
  baselineDuration: number    // 基线耗时(毫秒)
  tolerancePercent: number    // 容差百分比
  lastUpdated: string         // 最后更新时间
}

export class PerformanceBaseline {
  private baselines: Map<string, BaselineEntry> = new Map()

  // 设置基线
  setBaseline(name: string, duration: number, tolerancePercent: number = 20): void {
    this.baselines.set(name, {
      metricName: name,
      baselineDuration: duration,
      tolerancePercent,
      lastUpdated: new Date().toISOString()
    })
  }

  // 检查是否回归
  checkRegression(name: string, actualDuration: number): RegressionResult {
    const baseline = this.baselines.get(name)
    if (!baseline) {
      return { isRegression: false, message: '无基线数据', deviation: 0 }
    }

    const upperLimit = baseline.baselineDuration * (1 + baseline.tolerancePercent / 100)
    const deviation = ((actualDuration - baseline.baselineDuration) / baseline.baselineDuration) * 100

    if (actualDuration > upperLimit) {
      return {
        isRegression: true,
        message: `性能回归!${name}耗时${actualDuration}ms,超过基线${baseline.baselineDuration}ms的${baseline.tolerancePercent}%容差`,
        deviation
      }
    }

    return {
      isRegression: false,
      message: `${name}耗时${actualDuration}ms,在基线${baseline.baselineDuration}ms的${baseline.tolerancePercent}%容差内`,
      deviation
    }
  }

  // 批量检查回归
  checkAllRegressions(metrics: Array<{ name: string; duration: number }>): Array<RegressionResult> {
    return metrics.map(m => ({
      ...this.checkRegression(m.name, m.duration),
      metricName: m.name,
      actualDuration: m.duration
    }))
  }

  // 更新基线
  updateBaseline(name: string, newDuration: number): void {
    const existing = this.baselines.get(name)
    if (existing) {
      existing.baselineDuration = newDuration
      existing.lastUpdated = new Date().toISOString()
    }
  }

  // 导出基线数据
  exportBaselines(): string {
    return JSON.stringify(Array.from(this.baselines.entries()))
  }

  // 导入基线数据
  importBaselines(data: string): void {
    const entries = JSON.parse(data) as Array<[string, BaselineEntry]>
    for (const [key, value] of entries) {
      this.baselines.set(key, value)
    }
  }
}

export interface RegressionResult {
  isRegression: boolean
  message: string
  deviation: number
  metricName?: string
  actualDuration?: number
}

// ==================== 性能回归测试 ====================
import { describe, it, beforeAll, assertEqual, assertTrue } from '@ohos/hypium'
import { PerformanceProfiler } from '../PerformanceProfiler'
import { PerformanceBaseline } from '../PerformanceBaseline'

export default function performanceRegressionTest() {
  describe('性能回归检测测试', () => {
    let profiler: PerformanceProfiler
    let baseline: PerformanceBaseline

    beforeAll(() => {
      profiler = new PerformanceProfiler()
      baseline = new PerformanceBaseline()

      // 设置性能基线(基于历史数据)
      baseline.setBaseline('app-startup', 2000, 20)     // 启动2秒,容差20%
      baseline.setBaseline('page-load', 500, 25)         // 页面加载500ms,容差25%
      baseline.setBaseline('data-query', 100, 30)        // 数据查询100ms,容差30%
      baseline.setBaseline('image-render', 200, 20)      // 图片渲染200ms,容差20%
    })

    it('启动耗时_未超过基线', 0, async () => {
      // 模拟启动
      profiler.start('app-startup')
      await new Promise<void>(resolve => setTimeout(resolve, 1800))  // 1.8秒
      profiler.end('app-startup')

      const metric = profiler.getMetricByName('app-startup')!
      const result = baseline.checkRegression('app-startup', metric.duration)
      assertTrue(!result.isRegression, result.message)
    })

    it('页面加载_超过基线检测回归', 0, async () => {
      // 模拟页面加载(故意超基线)
      profiler.start('page-load')
      await new Promise<void>(resolve => setTimeout(resolve, 700))  // 700ms,超基线40%
      profiler.end('page-load')

      const metric = profiler.getMetricByName('page-load')!
      const result = baseline.checkRegression('page-load', metric.duration)
      assertTrue(result.isRegression, '超过基线容差应检测为回归')
      assertTrue(result.deviation > 25, `偏差${result.deviation}%应超过25%容差`)
    })

    it('数据查询_刚好在容差内', 0, async () => {
      profiler.start('data-query')
      await new Promise<void>(resolve => setTimeout(resolve, 120))  // 120ms,超基线20%,在30%容差内
      profiler.end('data-query')

      const metric = profiler.getMetricByName('data-query')!
      const result = baseline.checkRegression('data-query', metric.duration)
      assertTrue(!result.isRegression, '在容差内不应检测为回归')
    })

    it('批量回归检测_生成报告', 0, async () => {
      const metrics = [
        { name: 'app-startup', duration: 2100 },    // 超基线5%,在20%容差内
        { name: 'page-load', duration: 400 },        // 低于基线
        { name: 'data-query', duration: 150 },       // 超基线50%,超过30%容差
        { name: 'image-render', duration: 250 }      // 超基线25%,超过20%容差
      ]

      const results = baseline.checkAllRegressions(metrics)
      const regressions = results.filter(r => r.isRegression)

      assertEqual(regressions.length, 2, '应检测到2个回归')
      assertTrue(regressions.some(r => r.metricName === 'data-query'), 'data-query应被检测为回归')
      assertTrue(regressions.some(r => r.metricName === 'image-render'), 'image-render应被检测为回归')
    })

    it('基线更新_新版本基线', 0, () => {
      baseline.updateBaseline('app-startup', 2200)
      const result = baseline.checkRegression('app-startup', 2300)
      assertTrue(!result.isRegression, '更新基线后2300ms应在容差内')
    })
  })
}

3.3 完整示例:性能瓶颈定位

// BottleneckDetector.ets - 性能瓶颈检测器
export interface CallNode {
  name: string
  duration: number
  children: Array<CallNode>
  percentage: number  // 占总耗时的百分比
}

export class BottleneckDetector {
  private rootNodes: Array<CallNode> = []
  private totalDuration: number = 0

  // 添加调用链
  addCallChain(name: string, duration: number, children: Array<CallNode> = []): void {
    this.rootNodes.push({ name, duration, children, percentage: 0 })
    this.recalculatePercentages()
  }

  // 重新计算百分比
  private recalculatePercentages(): void {
    this.totalDuration = this.rootNodes.reduce((sum, n) => sum + n.duration, 0)
    for (const node of this.rootNodes) {
      node.percentage = (node.duration / this.totalDuration) * 100
      this.calculateChildPercentages(node, node.duration)
    }
  }

  // 递归计算子节点百分比
  private calculateChildPercentages(parent: CallNode, parentDuration: number): void {
    for (const child of parent.children) {
      child.percentage = (child.duration / parentDuration) * 100
      this.calculateChildPercentages(child, child.duration)
    }
  }

  // 查找瓶颈(占比超过threshold的节点)
  findBottlenecks(thresholdPercent: number = 30): Array<CallNode> {
    const bottlenecks: Array<CallNode> = []
    for (const node of this.rootNodes) {
      this.findBottlenecksRecursive(node, thresholdPercent, bottlenecks)
    }
    return bottlenecks.sort((a, b) => b.percentage - a.percentage)
  }

  private findBottlenecksRecursive(node: CallNode, threshold: number, result: Array<CallNode>): void {
    if (node.percentage >= threshold) {
      result.push(node)
    }
    for (const child of node.children) {
      this.findBottlenecksRecursive(child, threshold, result)
    }
  }

  // 生成火焰图数据
  generateFlameChartData(): string {
    return JSON.stringify(this.rootNodes, null, 2)
  }

  // 获取总耗时
  getTotalDuration(): number {
    return this.totalDuration
  }
}

// ==================== 瓶颈定位测试 ====================
import { describe, it, beforeAll, assertEqual, assertTrue } from '@ohos/hypium'
import { BottleneckDetector, CallNode } from '../BottleneckDetector'

export default function bottleneckDetectionTest() {
  describe('性能瓶颈定位测试', () => {
    let detector: BottleneckDetector

    beforeAll(() => {
      detector = new BottleneckDetector()

      // 模拟一个典型的页面加载调用链
      detector.addCallChain('页面加载', 500, [
        {
          name: '数据获取',
          duration: 300,
          children: [
            { name: '网络请求', duration: 200, children: [], percentage: 0 },
            { name: '数据解析', duration: 80, children: [], percentage: 0 },
            { name: '数据转换', duration: 20, children: [], percentage: 0 }
          ],
          percentage: 0
        },
        {
          name: 'UI渲染',
          duration: 150,
          children: [
            { name: '布局计算', duration: 50, children: [], percentage: 0 },
            { name: '绘制', duration: 100, children: [], percentage: 0 }
          ],
          percentage: 0
        },
        {
          name: '动画初始化',
          duration: 50,
          children: [],
          percentage: 0
        }
      ])
    })

    it('总耗时计算正确', 0, () => {
      assertEqual(detector.getTotalDuration(), 500, '总耗时应为500ms')
    })

    it('瓶颈识别_数据获取占比最高', 0, () => {
      const bottlenecks = detector.findBottlenecks(30)
      assertTrue(bottlenecks.length > 0, '应识别到瓶颈')
      assertEqual(bottlenecks[0].name, '数据获取', '数据获取应是最大瓶颈')
      assertTrue(bottlenecks[0].percentage >= 50, `数据获取占比${bottlenecks[0].percentage}%,应>=50%`)
    })

    it('子瓶颈_网络请求是数据获取的瓶颈', 0, () => {
      const bottlenecks = detector.findBottlenecks(50)
      // 网络请求占数据获取的200/300=66.7%
      const networkBottleneck = bottlenecks.find(b => b.name === '网络请求')
      assertNotNull(networkBottleneck)
      assertTrue(networkBottleneck!.percentage >= 60, '网络请求应占数据获取60%以上')
    })

    it('火焰图数据_可导出分析', 0, () => {
      const flameData = detector.generateFlameChartData()
      assertNotNull(flameData)
      assertTrue(flameData.includes('数据获取'), '火焰图数据应包含模块名')
      assertTrue(flameData.includes('网络请求'), '火焰图数据应包含子模块名')
    })

    it('低阈值_识别更多瓶颈', 0, () => {
      const bottlenecks10 = detector.findBottlenecks(10)
      const bottlenecks50 = detector.findBottlenecks(50)
      assertTrue(bottlenecks10.length >= bottlenecks50.length, '低阈值应识别更多瓶颈')
    })
  })
}

四、踩坑与注意事项

坑点1:性能测试结果不稳定

同一段代码,跑10次,耗时从50ms到150ms都有——波动太大,基线没法定。

原因:后台进程干扰、GC暂停、JIT编译优化、CPU频率波动。

建议

  • 性能测试前关闭后台应用
  • 先跑几轮预热(让JIT编译完成),再开始计时
  • 取中位数而不是平均值,中位数更抗干扰
  • 允许±20%的波动,不要把容差设太紧

坑点2:Mock数据导致性能测试失真

你用Mock数据测性能——Mock返回的是固定数据,没有网络延迟、没有数据库IO。测试结果很好看,但真实场景性能可能差10倍。

建议:性能测试尽量用真实数据和真实依赖。如果必须Mock,Mock的延迟应该模拟真实场景的延迟分布。

坑点3:只测平均耗时不测尾部延迟

平均耗时100ms,但99%分位耗时500ms——10个用户里有1个体验极差,但你不知道。

建议:性能测试不仅看平均值,还要看P90、P95、P99分位值。尾部延迟才是用户体验的真实反映。

坑点4:性能基线过时

3个月前定的基线,代码已经改了100个commit,基线早就失效了。但CI还在用旧基线检测回归——要么误报一堆,要么漏掉真正的回归。

建议:每个大版本更新一次基线。日常开发中如果基线频繁误报,说明基线需要更新了。基线更新要走审批流程,不能随便改。

坑点5:性能测试和功能测试混在一起

性能测试需要预热、需要多次执行取平均值,和功能测试的"跑一次断言结果"完全不同。混在一起,要么功能测试变慢,要么性能测试不准。

建议:性能测试和功能测试分开执行。CI流水线中,功能测试每次提交跑,性能测试每天跑一次或合并请求时跑。

坑点6:忽略了冷启动和热启动的区别

冷启动(进程不存在)耗时2秒,热启动(进程在后台)耗时200ms。如果你只测了热启动,以为性能很好,用户第一次打开App等2秒——体验很差。

建议:冷启动和热启动分别测试,分别建立基线。冷启动是用户的第一印象,更重要。

坑点7:内存性能被忽视

只关注了耗时,没关注内存。一个操作耗时50ms但分配了10MB内存——调用100次就是1GB,GC一触发就卡顿。

建议:性能测试同时监控内存分配。可以用performance.memory(如果可用)或DevEco Profiler的内存分析功能。


五、HarmonyOS 6适配说明

API差异表

功能/接口 HarmonyOS 5 HarmonyOS 6 变更说明
性能分析 手动打点 @ohos.perfProfiler 官方性能分析框架
基线管理 需自实现 @ohos.perfBaseline 官方基线管理
回归检测 需自实现 PerfRegressionDetector 内置回归检测
火焰图 需外部工具 @ohos.perfFlameChart 内置火焰图生成
资源监控 @ohos.resourceMonitor @ohos.resourceMonitor 新增GPU监控

行为变更

  1. @ohos.perfProfiler:官方性能分析框架,支持自动打点、调用链追踪、耗时统计。不再需要手动Date.now()计时。

  2. PerfRegressionDetector:内置回归检测器,自动对比当前性能数据与基线,超过阈值自动告警。

  3. 火焰图生成:内置火焰图数据生成,可以直接在DevEco Studio中可视化查看性能热点。

适配代码

// HarmonyOS 6性能集成测试
import { describe, it, assertEqual, assertTrue } from '@ohos/hypium'
import { PerfProfiler, PerfTrace } from '@ohos.perfProfiler'
import { PerfBaseline, RegressionLevel } from '@ohos.perfBaseline'

export default function harmonyOS6PerfTest() {
  describe('HarmonyOS 6性能集成测试', () => {
    it('PerfProfiler_自动打点', 0, async () => {
      const profiler = new PerfProfiler()

      // 自动追踪函数耗时
      const trace: PerfTrace = profiler.trace('data-loading')
      await dataRepository.fetchUsers()
      trace.end()

      assertTrue(trace.duration > 0, '应记录耗时')
      profiler.report()  // 自动生成报告
    })

    it('PerfBaseline_自动回归检测', 0, async () => {
      const baseline = new PerfBaseline()
      baseline.loadFromFile('perf-baseline.json')

      const currentDuration = await measureStartupTime()
      const result = baseline.check('app-startup', currentDuration)

      if (result.level === RegressionLevel.CRITICAL) {
        assertTrue(false, `严重性能回归: ${result.message}`)
      }
    })

    it('火焰图_自动生成', 0, async () => {
      const profiler = new PerfProfiler()
      profiler.startSession('page-load')

      // 执行业务逻辑...
      await pageViewModel.loadPage()

      const flameData = profiler.endSession()
      assertNotNull(flameData, '应生成火焰图数据')
    })
  })
}

六、总结

维度 评价
学习难度 ⭐⭐⭐⭐
使用频率 ⭐⭐⭐⭐
重要程度 ⭐⭐⭐⭐⭐

性能集成测试的核心价值在于:发现单模块测试发现不了的性能瓶颈。模块A快、模块B快,但A调用B的链路慢——这种问题只有集成测试能发现。性能基线是回归检测的基础——没有基线,你根本不知道性能是变好了还是变差了。瓶颈定位是优化的前提——不知道慢在哪,优化就是盲猜。性能测试不是"跑一次看结果",而是"建立基线、持续监控、自动回归检测"的完整体系

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。