Skip to content

KenForever1/quickcheck-cpp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

quickcheck-cpp

基于 C++20 实现一个简化版的 quickcheck 一个基本的属性测试框架。

包括如下功能:

(1)随机输入生成: 使用 C++ 的random生成随机数据。支持基本类型(如 int、double、std::string)和自定义类型。

(2)属性测试: 用户提供一个 Lambda 函数作为属性测试函数。会生成随机输入并验证属性是否成立。

(3)收缩失败用例: 如果测试失败,尝试收缩输入,找到最小的失败用例。

使用示例:

#include "quickcheck.hpp"

// 示例:测试 reverse 函数的属性
bool testReverseProperty(const std::vector<int> &xs)
{
    std::vector<int> rev = xs;
    std::reverse(rev.begin(), rev.end());
    std::vector<int> revRev = rev;
    std::reverse(revRev.begin(), revRev.end());
    return revRev == xs;
}

int main()
{
    // 测试 reverse 函数的属性
    QuickCheck::check<std::vector<int>>(
        "reverse(reverse(xs)) == xs",
        testReverseProperty);

    return 0;
}

依赖

  • gtest
  • fmt

特性

生成任意值

通过RandomGenerator 模板,用于生成随机数据。通过特化支持如下类型:

  • 基本类型:

char、int、long long、float、double 等基本类型均支持随机生成。

  • 字符串:

std::string 生成长度为 1 到 10 的随机字符串。

  • 容器:

std::vector:生成随机长度的向量,元素类型 T 可以是任意支持的类型。

std::map<K, V>:生成随机长度的映射,键值对由 RandomGenerator<std::pair<K, V>> 生成。

std::set:生成随机长度的集合,元素类型 T 可以是任意支持的类型。

std::unordered_map<K, V>:生成随机长度的无序映射。

  • 元组和键值对:

std::tuple<Ts...>:生成随机元组,元素类型由 RandomGenerator 生成。

std::pair<K, V>:生成随机键值对,键和值分别由 RandomGenerator 和 RandomGenerator 生成。

收缩失败用例(shrink)

实现收缩失败用例的功能是 quickcheck 的核心特性之一。当测试失败时,我们需要逐步收缩输入,找到最小的、仍然能触发失败的用例。

  • 收缩策略:

对于数值类型(如 int、double),逐步将值减半。

对于容器类型(如 std::vector、std::map),逐步删除元素。

对于复合类型(如 std::tuple),逐步收缩其组成部分。

  • 递归收缩:

对于复杂类型,递归地收缩其子元素。

  • 停止条件:

当输入无法进一步收缩,或收缩后的输入不再触发失败时,停止收缩。

例如,测试函数错误,输出:

Testing property: reverse(reverse(xs)) == xs
Test failed for input: [-80, 62, 40, -98, -50, 95, -21]
Shrinking input...Minimal failing input: [-80, 62, 40, -98, -50, 95, -21]

统计测试覆盖率

用于统计测试覆盖率,记录输入的最小值、最大值和测试次数。

Testing property: reverse(reverse(xs)) == xs
All tests passed!
Vector Coverage: minSize = 0, maxSize = 9, sizeCount = 100 
Element Coverage: Coverage: min = -100, max = 100, count = 202

doc

从这里开始

inspired

BurntSushi/quickcheck: Automated property based testing for Rust (with shrinking).

emil-e/rapidcheck: QuickCheck clone for C++ with the goal of being simple to use with as little boilerplate as possible.

About

Automated property based testing for cpp (with shrinking).

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published