Catch2 是一个 C++ 单元测试库,吹嘘自己比 NUnit 和 xUnit 还要高明, 支持在 TEST_CASE() 中的多个 SECTION, 意思是说 SECTION 外头的代码相当于setup 和 teardown,section 内部则被认为是实际的 test case, 这种写法可以省很多代码,云云:

https://github.com/catchorg/Catch2/blob/v2.x/docs/tutorial.md#test-cases-and-sections
山寨一个Catch2的SECTION-LMLPHP
然而 Catch2 文档里卖关子,不说原理。 我们来山寨一个:

test2.cpp

#include <stdio.h>
#include <vector>

static int section_idx = 0;

void test()
{
    printf("comman setup\n");
    std::vector<int> v(5);

    if (section_idx == 0)
    {
        printf("--- check 1\n");
        v.resize(10);
        printf("v.size() = %d\n", v.size());
    }

    if (section_idx == 1)
    {
        printf("--- check 2\n");
        printf("v.size() = %d\n", v.size());
    }

    if (section_idx == 2)
    {
        printf("--- check 3\n");
        v.resize(20);
        printf("v.size() = %d\n", v.size());
    }

    if (section_idx == 3)
    {
        printf("--- check 4\n");
        printf("v.size() = %d\n", v.size());
    }

    printf("\n");
    section_idx++;
}

int main()
{
    for (int i = 0; i < 4 ; i++)
    {
        test();
    }

    return 0;
}

改进一下:
test3.cpp:

#include <stdio.h>
#include <vector>

static int section_idx = 0;

void test()
{
    printf("comman setup\n");
    std::vector<int> v(5);

    auto f0 = [&]() -> void
    {
        printf("--- check 1\n");
        v.resize(10);
        printf("v.size() = %d\n", v.size());
    };
    if (section_idx == 0)
        f0();

    auto f1 = [&]() -> void
    {
        printf("--- check 2\n");
        printf("v.size() = %d\n", v.size());
    };
    if (section_idx == 1)
        f1();

    auto f2 = [&]() -> void
    {
        printf("--- check 3\n");
        v.resize(20);
        printf("v.size() = %d\n", v.size());
    };
    if (section_idx == 2)
        f2();

    auto f3 = [&]() -> void
    {
        printf("--- check 4\n");
        printf("v.size() = %d\n", v.size());
    };
    if (section_idx == 3)
        f3();

    printf("\n");
    section_idx++;
}

int main()
{
    for (int i = 0; i < 4 ; i++)
    {
        test();
    }

    return 0;
}

再改进一下:

#include <stdio.h>
#include <vector>

static int section_idx = 0;
int section_num = 0;

void test()
{
    static bool inited = false;

    printf("comman setup\n");
    std::vector<int> v(5);

    auto f0 = [&]() -> void
    {
        printf("--- check 1\n");
        v.resize(10);
        printf("v.size() = %d\n", v.size());
    };
    if (!inited)
        section_num++;
    else
    {
        if (section_idx == 0)
            f0();
    }

    auto f1 = [&]() -> void
    {
        printf("--- check 2\n");
        printf("v.size() = %d\n", v.size());
    };
    if (!inited)
        section_num++;
    else
    {
        if (section_idx == 1)
            f1();
    }

    auto f2 = [&]() -> void
    {
        printf("--- check 3\n");
        v.resize(20);
        printf("v.size() = %d\n", v.size());
    };
    if (!inited)
        section_num++;
    else
    {
        if (section_idx == 2)
            f2();
    }

    auto f3 = [&]() -> void
    {
        printf("--- check 4\n");
        printf("v.size() = %d\n", v.size());
    };
    if (!inited)
        section_num++;
    else
    {
        if (section_idx == 3)
            f3();
    }

    printf("\n");
    section_idx++;
    inited = true;
}

int main()
{
    test();
    for (int i = 0; i < section_num ; i++)
    {
        test();
    }

    return 0;
}

结果:

➜  shanzhai_catch2 ./a.out
comman setup

comman setup
--- check 2
v.size() = 5

comman setup
--- check 3
v.size() = 20

comman setup
--- check 4
v.size() = 5

comman setup

成功!

11-18 17:55