原生测试框架

仓颉的原生测试框架构建在仓颉的标准库中,为用户提供了先进的测试体验,既允许传统和简单的测试技术,也允许更先进的技术用于更高级的测试场景。测试框架包括三个主要部分:单元测试框架、Mocking 测试框架和基准测试框架。

单元测试框架

单元测试框架,顾名思义,允许用户在他们的仓颉项目中创建单元测试。除了能够像实现单个仓颉函数一样创建简单的单元测试之外,它还提供了各种更高级的技术:

  • 参数化测试:基于多种输入参数运行被测试代码;
  • 数据驱动测试:从文件中读取多组测试数据,作为入参,运行同一份测试代码;
  • 随机化参数测试:支持结构化构造的不同随机数据作为入参,运行同一份测试代码。相较于业界仅可生成基础类型和字符数组类型的随机值,仓颉提供了更为强大的随机化参数测试能力;
  • 泛型类型参数化测试:对于泛型库开发者,框架可基于同一测试代码,通过传入不同类型参数,测试泛型函数在不同类型上的实现;
  • 死亡测试:对于底层库开发者,框架支持捕获不符合预期的信号,段错误和其他发生在底层库中的错误。

此外,为了进一步改善用户体验,测试框架引入了对 power assertions 和 difference assertions 的原生实现,提供对测试数据和故障背后原因的详尽说明。

上述这些特性都是灵活可配置的,并可以按需组合使用。例如,测试泛型函数时,使用类型参数化一次生成多种类型实例化实现,传入对应类型下随机生成的测试数据,同时使用 power assertions 和 difference assertions 获取更为清晰的信息。

Mocking 框架

Mocking 框架允许用户使用 mock 和 spy 来改变在测试中的仓颉类的行为:这些 mock 或 spy 对象可以通过捕获和修改被处理对象的行为,来测试程序的其余部分如何与该对象交互。Mocking 是一种高级技术,主要用于测试由大量交互组件组成的大型应用程序。

我们的 Mocking DSL 的设计尽量遵照现有语言 mocking 框架的风格,让用户的切换过程更加简单。DSL 允许指定、验证和修改在测试代码中的对象的行为,并产生可读的错误提示。但与其他 Mocking 框架不同,仓颉的 Mocking 框架基于独特的编译器插桩技术实现,用户不仅可以 mock 接口和开发类型,还可以 mock final 类。

仓颉的 Mocking 框架与单元测试框架能够无缝结合,两者的任何功能都可以一起使用,使框架的测试能力更加强大。

基准测试框架

仓颉测试框架提供了先进的基准测试体验,包括基于线性回归的统计值计算,预热和精确测量。值得一提的是,单元测试框架提供的大多数功能也可用于基准测试,允许参数化测试,参数随机化生成和泛型类型对泛型代码的基准测试。

除此之外,基准测试框架还具有自己的一套功能,例如相对于给定基线的计算,访问原始基准测试数据(以便在需要时进行用户自己的计算)以及分别针对 micro 和 macro 基准测试的精确误差估计。