Google测试-为模板类实例化生成值 [英] Google Test - generate values for template class instanciation

查看:50
本文介绍了Google测试-为模板类实例化生成值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用Google Test时遇到问题.我有一个等效于以下代码的代码:

I am having an issue with Google Test. I have a code equivalent to what follows:

template<int N> class A {
public:
    A() {}
    A(int n) {
        var = n;
    }
    int var;
};


test_A.cpp

#include "gtest/gtest.h"
#include "A.h"

template<typename T> class TestA : public ::testing::Test {};

TYPED_TEST_CASE_P(TestA);

TYPED_TEST_P(TestA, SomeTest){
    TypeParam x(0);
    EXPECT_EQ(x.var,0);
    ...
}

REGISTER_TYPED_TEST_CASE_P(TestA, SomeTest);

typedef ::testing::Types<A<0>, A<1>, A<2>, A<3>, A<4>, A<5> ... A<511>, A<512>> MyTypes;
INSTANTIATE_TYPED_TEST_CASE_P(My, TestA, MyTypes);

int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}


总而言之,我想对 N 的许多版本在类 A 上运行测试 SomeTest .使用类型参数化测试以上开发的,问题在于使用类型化测试"来进行测试.方法,我必须手动编写要测试的类 A 的所有版本.


To sum up, I want to run the test SomeTeston class A for many versions of N. With the type-parameterized test developed above, the problem is that with "typed test" method, I have to write manually all versions of class A I want to test.

使用Google测试,您还可以编写值参数化测试,它非常方便,因为您可以使用 Range :

With Google Test, you can also write value-parameterized tests, which is very convenient because you can use generators like Range:

INSTANTIATE_TEST_CASE_P(InstantiationName, TestA, ::testing::Range(0,512,1));

然后,您可以使用测试内的函数 GetParam()来访问值.这种语法将使我要设置的内容变得非常容易.但是,似乎这些值在编译时无法解析,因此无法用于指定模板值.

and then, you can access the values using the function GetParam() inside the test. This syntax would make what I want to do very easy to setup. However, it seems that the values are not resolved at compile time, and they are therefore not usable to specify templates values.

我的问题是:

  • 是否有一些语法等效于Google Test中的值参数化测试,以指定要测试的所有 A 版本?
  • 如果没有,我如何生成要用于类型参数化测试的类型 A< 0>,...,A< 512< 的列表?
  • Is there some syntax which is equivalent to value-parameterized testing in Google Test to specify all versions of A I want to test?
  • If there is not, how can I generate my list of types A<0>, ..., A<512> to be used with type-parameterized testing?

N.B:必须符合c ++ 11.

N.B: It has to be c++11 compliant.

推荐答案

您正在寻找一种通过Googletest来节省手指操作的方法您通过避免对类型列表进行硬编码而在上面概述的解决方案:

You're looking for a way to economise fingerwork in the sort of googletest solution you've sketched above by avoiding the hardcoding of the typelist:

A<0>, A<1>, A<2>, A<3>, A<4>, A<5>, ... A<511>, A<512>

MyTypes 的定义中,并在编译时以某种方式生成它仅给出类型列表的长度.

in the definition of MyTypes, and having it somehow generated at compiletime given just the length of the typelist.

遗憾的是,通过解决这些问题,您可以节省的手指工作量非常有限这个问题.在内部,googletest仅使用C ++ 03.所以没有杂种模板,随C ++ 11一起提供.因此,对类型列表的长度:

Regrettably, there's a very limited amount of fingerwork you can save by solving this problem. Internally, googletest employs C++03 exclusively. So no variadic templates, which arrived with C++11. Hence there's a hardcoded limit on the length of the typelist in:

::testing::Types<T0, T1, ... Tn>

您需要513种类型的列表:硬编码限制为50.在编译之后失败.

You're wanting a list of 513 types: the hardcoded limit is 50. After that compilation fails.

不过,如果您要使用这种类型的googletest解决方案做很多事情,类型列表的长度在N x 10范围内,那么拥有代码可能值得您库存以按您想要的方式生成它们.

Still, if you're going to be doing a lot with this type of googletest solution, with typelist lengths in the N x 10 range, it might be worth your while having code in stock to generate them the way you want.

C ++ 14只是用于此类工作的工具.它是 template<等级T,T ... Ints>类std :: integer_sequence .但是您说您只能使用 C ++ 11 .在这种情况下,您需要手动替换 std :: integer_sequence .那里有很多东西在Google领域.乔纳森·韦克利(Jonathan Wakeley)的脱颖而出: std :: integer_sequence 是他的C ++ 14提案,以及他的实现是C ++ 14标准的原型.

C++14 has just the tool for jobs like this. It is template< class T, T... Ints> class std::integer_sequence. But you say that you're restricted to C++11. In that case, you'll need a hand-rolled substitute for std::integer_sequence. There are lots out in there in Google land. Jonathan Wakeley's one stands out: std::integer_sequence was his C++14 proposal, and his implementation is the prototype for the C++14 standard one.

现在,我将处理我自己的杂草丛生的杂草.这是头文件:

For now I'll make do with my own weedy one. Here's a header file:

integer_seq.h

#ifndef INTEGER_SEQ_H
#define INTEGER_SEQ_H

#if __cplusplus >= 201402L

#include <utility>

template<typename IntType, IntType ...Is>
using integer_seq = std::integer_sequence<IntType,Is...>;

template<typename IntType, IntType N>
using make_integer_seq = std::make_integer_sequence<IntType,N>;

#elif __cplusplus == 201103L

#include <type_traits>

template<typename IntType, IntType ...Is> struct integer_seq {};

namespace detail {

template<typename IntType, IntType Count, bool Done, IntType ...Is>
struct gen_seq;

template<typename IntType, IntType Count, IntType ...Is>
struct gen_seq<IntType, Count, false, Is...>
{
    static_assert(Count > 0,"Count must be positive");    
    using type = 
        typename gen_seq<   IntType, 
                            Count - 1, Count - 1 == 0, 
                            Count - 1, Is...
                        >::type;
};

template <typename IntType, IntType Count, IntType ...Is>
struct gen_seq<IntType, Count, true, Is...>
{
    using type = integer_seq<IntType,Is...>;
};

} // namespace detail


template<typename IntType, IntType N>
using make_integer_seq = typename detail::gen_seq<IntType,N,N == 0>::type;

#else
#error At least C++11 required :(
#endif

#endif

此标头定义:

template< typename IntType, IntType ...Is> struct integer_seq;

表示某个整数类型 IntType 的值的序列 Is ... ,并且:

which represents a sequence Is... of values of some integral type IntType, and:

template<typename IntType, IntType N> make_integer_seq;

这是该类型的别名:

integer_sequence<IntType,0,... N - 1>

如果您使用C ++ 14进行编译,则 integer_seq 本身只是它的别名 std :: integer_sqeuence .如果是C ++ 11,则手动滚动 integer_seq .

If you compile in C++14 then integer_seq is itself just an alias for std::integer_sqeuence. If C++11 then integer_seq is hand-rolled.

一旦有了模板 integer_seq ,您就可以使用它来获得一些影响在googletest的模板 :: testing :: Types 上.这是另一个头文件:

Once you've got template integer_seq, you can use it to get some leverage on googletest's template ::testing::Types. Here's another header file:

indexed_type_list

#ifndef INDEXED_TYPE_LIST_H
#define INDEXED_TYPE_LIST_H

#include <cstddef>
#include "gtest/gtest.h"
#include "integer_seq.h"

template<typename IntType, template<IntType> class T, typename Seq>
struct indexed_type_list;

template<typename IntType, template<IntType> class T, IntType ...Is>
struct indexed_type_list<IntType,T,integer_seq<IntType,Is...>>
{
    using type = ::testing::Types<T<Is>...>;
};

template<typename IntType, template<IntType> class T,  std::size_t Size>
using indexed_type_list_t =
    typename indexed_type_list<IntType,T,make_integer_seq<IntType,Size>>::type;

#endif

其中定义:

template<typename IntType, template<IntType> class T,  IntType Size>
indexed_type_list_t;

在给定某些整数类型 IntType 的情况下,该类型的数字 Size 以及一些一元非类型模板 template< IntType>T类,然后:

such that, given some integral type IntType, a number Size of that type, and some unary non-type template template<IntType> class T, then:

indexed_type_list_t<IntType,T,Size>

是以下内容的别名:

::testing::Types<T<0>,... T<Size - 1>>;

这就是您要追求的. indexed_type_list 公认是一个非常la脚的名字对于这个概念,但我的迷惑使我失望.

which is what you're after. indexed_type_list is admittedly a very lame name for this concept, but my imagaination fails me.

现在我们准备开始.这是我们适应标本解决方案的方法:

Now we ready to roll. Here's how we'd adapt your specimen solution:

main.cpp

#include "indexed_type_list.h"
#include "A.h"

template<typename T> class TestA : public ::testing::Test{};

TYPED_TEST_CASE_P(TestA);

TYPED_TEST_P(TestA, SomeTest){
    TypeParam x(0);
    EXPECT_EQ(x.var,0);
}

REGISTER_TYPED_TEST_CASE_P(TestA, SomeTest);

using MyTypes = indexed_type_list_t<int,A,50>;

INSTANTIATE_TYPED_TEST_CASE_P(My, TestA, MyTypes);

int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

编译并链接:

$ g++ -Wall -Wextra -pedantic -std=c++11 -c main.cpp
$ g++ -o testrunner main.o -lgtest -pthread

它的运行方式是:

$ ./testrunner
[==========] Running 50 tests from 50 test cases.
[----------] Global test environment set-up.
[----------] 1 test from My/TestA/0, where TypeParam = A<0>
[ RUN      ] My/TestA/0.SomeTest
[       OK ] My/TestA/0.SomeTest (0 ms)
[----------] 1 test from My/TestA/0 (0 ms total)

[----------] 1 test from My/TestA/1, where TypeParam = A<1>
[ RUN      ] My/TestA/1.SomeTest
[       OK ] My/TestA/1.SomeTest (0 ms)
[----------] 1 test from My/TestA/1 (0 ms total)

...
...

[----------] 1 test from My/TestA/48, where TypeParam = A<48>
[ RUN      ] My/TestA/48.SomeTest
[       OK ] My/TestA/48.SomeTest (0 ms)
[----------] 1 test from My/TestA/48 (0 ms total)

[----------] 1 test from My/TestA/49, where TypeParam = A<49>
[ RUN      ] My/TestA/49.SomeTest
[       OK ] My/TestA/49.SomeTest (0 ms)
[----------] 1 test from My/TestA/49 (0 ms total)

[----------] Global test environment tear-down
[==========] 50 tests from 50 test cases ran. (0 ms total)
[  PASSED  ] 50 tests.

这就是您解决的问题.一切都是可选的.

So that's your problem solved. It's all optional for here on.

反面

这种测试任何类模板的方法存在致命的设计缺陷一系列非类型模板参数.在解决之前就在那里为 :: testing :: Types 生成类型列表的问题,它仍然存在在那里.

There's a fatal design flaw in this approach to testing any class template over a range of non-type template parameters. It was there before we solved the problem of generating the typelist for ::testing::Types, and it's still there.

在实际的应用程序中,经过精心设计的您不会遇到像 template< int N>在 A.h 中定义的A类,其中模板参数 N 在模板定义或模板专业化中根本不使用.该模板参数没有实际用途. A 的定义可能以及:

In real applications, proficiently designed, you don't come across a class template like the template<int N> class A defined in A.h, where the template parameter N is not used at all, either in the template definition or for template specializations. That template parameter has no practical purpose. The definition of A might as well be:

class A {
public:
    A() {}
    A(int n) {
        var = n;
    }
    int var;
};

假设代替 A ,我们不得不多处理一点逼真的模板:

Suppose that instead of A we had to deal with a marginally more lifelike template:

dot_matrix.h

#ifndef DOT_MATRIX_H
#define DOT_MATRIX_H

#include <array>

template<std::size_t N>
struct dot_matrix
{
    bool get(std::size_t x, std::size_t y) const {
        return _square.at(x).at(y);
    }
    void set(std::size_t x, std::size_t y) {
        _square.at(x).at(y) = true;
        ++_filled;
    }
    void clear(std::size_t x, std::size_t y){
        _square.at(x).at(y) = false;
        --_filled;
    }

    unsigned filled() const {
        return _filled;
    }

    unsigned vacant() const {
        return area() - _filled;
    }

    static constexpr std::size_t side() {
        return N * 2;
    }

    static constexpr std::size_t area() {
        return side() * side();
    }

private:
    unsigned _filled;
    std::array<std::array<bool,N>,N> _square;
};

#endif

假设, template< std :: size_t N>一般是struct dot_matrix 封装大小为 N x N 的固定大小的正方形点矩阵.我说应该是因为现在它被一个错误击倒了-是的,这是一个不切实际的明显错误-我们希望通过googletest单元测试将其淘汰.

Supposedly,template<std::size_t N> struct dot_matrix generically encapsulates a fixed-size square dot matrix of size N x N. I say supposedly because right now it's let down by a bug - true, an unrealistically obvious bug - that we'd hope to flush out by googletest unit-testing.

您可以通过吸管对单元测试进行编码,并为 TYPED_TEST_CASE_P 样式测试,具有:

You draw the straw to code the unit-testing and get everything setup up for TYPED_TEST_CASE_P style testing, with:

using MyTypes = ::testing::Types<dot_matrix<0>,... dot_matrix<49>>;

是否编译时生成都没关系

It doesn't matter whether you compiletime-generate

dot_matrix<0>,... dot_matrix<49>

或用困难的方式编码.

例如,您写了一堆 TYPED_TEST_P s:

You write a bunch of TYPED_TEST_Ps, for instance:

TYPED_TEST_P(TestDotMatrix,IsSquare){
    TypeParam matrix;
    auto side = matrix.side();
    EXPECT_EQ(matrix.area(),side * side));
}

TYPED_TEST_P(TestDotMatrix, IsConsistent){
    TypeParam matrix;
    auto cap = matrix.filled() + matrix.vacant();
    EXPECT_EQ(matrix.area(),cap));
}
...

团队负责人的代码审查和发现:-

The team leader code reviews and spots:-

  • dot_matrix< N> 中的错误.它没有封装 N x N 点矩阵.实际上,它封装了 2N x 2N 点矩阵.

  • A bug in dot_matrix<N>. It doesn't encapsulate an N x N dot matrix. Actually, it encapsulates a 2N x 2N dot matrix.

您还没有一个测试来验证 dot_matrix< N> 是否包含 N x N 矩阵.

You haven't got a test that verifies that dot_matrix<N> contains an N x N matrix.

您可以重新考虑此案,以纠正这一疏忽:-

You get back on the case to fix this oversight:-

TYPED_TEST_P(TestDotMatrix, SizeIsRight){
    TypeParam matrix;
    EXPECT_EQ(???,matrix.side());
}

但是你不能.您不能填写 ??? ,因为 TypeParam 只是测试不知道的 N N 的某个值的 dot_matrix< N> 什么是需要替换的 ??? .

But you can't. You cannot fill in ???, because TypeParam is just a dot_matrix<N> for some value of N that the test does not know, and that N is what needs replace ???.

因为所有测试都不知道其 TypeParam N 的值被实例化,它们都只能测试 dot_matrix< N> 的行为就 N 而言是不变的,就像这样:

Because none of the tests know the value of N with which their TypeParam was instantiated, they can all test only behaviours of dot_matrix<N> that are invariant with respect to N, just like that:

TYPED_TEST_P(TestA, SomeTest){
    TypeParam x(0);
    EXPECT_EQ(x.var,0);
}

以上.测试50种不同值的 N 不变的行为 N 没什么用.当然,对这些 N 不变行为进行测试很有用.只是对于50个不同的 N 值,或者实际上不只是一个以上的值.

above. Testing a behaviour that doesn't vary with N for 50 different values of N isn't useful. It is useful to have tests for those N-invariant behaviours, of course. Just not for 50 different values of N, or indeed, more than one.

的行为 N 的变化也需要进行测试.像:做 dot_matrix< N> 报告正确的尺寸和区域为此 N ?

The behaviours that do vary with N also need to be tested. Like: Does a dot_matrix<N> report the right size and area for that N?

对于这些这些测试,您的googletest解决方案需要一个范围为在 TYPED_TEST_P 的实例化中, N 有所不同.这是需要做的感谢您将那些 TYPED_TEST_P s排除在"???"之外十全十美:-

It is for these tests that your googletest solution requires a range that varies N in instantiations of the TYPED_TEST_Ps. And here is what needs to be be appreciated to get those TYPED_TEST_Ps out the '???' quandry:-

正在测试模板struct dot_matrix< std :: size_t N> 的事实是不变.不需要为任何测试提供此信息:测试范围不需要传达它.唯一不同的是 N . N 的值是每个测试所需的一件事要知道.实例化测试所需的范围是一系列值 N .

The fact that a template struct dot_matrix<std::size_t N> is under test is invariant. None of the tests needs to be given this information: the test range doesn't need to convey it. The only thing that varies is N. The value of N is the one thing that each test needs to know. The range that you require to instantiate the tests is a range of values of N.

乍一看,这给googletest解决方案带来了困难.

That presents a difficulty, at first sight, for a googletest solution.

Googletest提供了用于生成值参数化测试可以为给定范围内的每个实例化一个 TEST_P 作为 :: testing :: Values(...) runtime 参数.

Googletest offers a framework for generating Value Parameterized Tests that can instantiate a TEST_P for each of a range of values given as runtime arguments to ::testing::Values(...).

Googletest还提供了用于生成输入类型的框架测试类型参数化测试可以针对给定的每个 types 类型的实例分别实例化 TYPED_TEST TYPED_TEST_P 作为 :: testing :: Types< ...> compiletime 模板参数.

Googletest also offers frameworks for generating Typed Tests and Type Parameterized Tests that can instantiate a TYPED_TEST or TYPED_TEST_P for each of a range of types given as compiletime template arguments to ::testing::Types<...>.

但是我们需要一个非类型模板参数的值范围.C ++要求这样的参数就是编译时积分常数.测试范围的googletest选项不包括一系列编译时积分常数.

But we need a range of values of a non-type template parameter. C++ requires such a parameter to be a compiletime integral constant. The googletest options for test ranges do not include a range of compiletime integral constants.

幸运的是,C ++ 11或更高版本采用了映射整数的方法来进行拯救类型唯一的常量.它是 template<类IntType,IntType v>struct std :: integral_constant .对于整数类型 IntType 的任何常量 N :

Happily, C++11 or later comes to the rescue with a way to map an integral constant uniquely to a type. It is template< class IntType, IntType v > struct std::integral_constant. For any constant N of integral type IntType:

struct std::integral_constant<IntType,N>;

是唯一映射的类型,您可以从该类型中检索编译时间常量 N 为:

is the uniquely mapped type, and from that type you can retrieve a compiletime constant N as:

std::integral_constant<IntType,N>::value;

因此googletest解决方案简而言之:

So here in bare essense is the googletest solution:

...
using MyTypes =
    ::testing::Types<std::integral_constant<0>,...std::integral_constant<49>>;

...
...

TYPED_TEST_P(TestDotMatrix, SizeIsRight){
    dot_matrix<TypeParam::value> matrix;
    EXPECT_EQ(TypeParam::value,matrix.side());
}

这是一个完全有效的示例,其范围为 testing :: Types 像以前一样编译时生成.

and here's a fully working example, with the testing::Types range compiletime-generated as before.

新标题:

integral_constant_typelist.h

#ifndef INTEGRAL_CONSTANT_TYPELIST_H
#define INTEGRAL_CONSTANT_TYPELIST_H

#include <cstddef>
#include <type_traits>
#include "gtest/gtest.h"
#include "integer_seq.h"

template<typename IntType, IntType Start,typename Seq>
struct integral_constant_typelist;

template<typename IntType, IntType Start,IntType ...Is>
struct integral_constant_typelist<IntType,Start,integer_seq<IntType,Is...>>
{
    using type =
        ::testing::Types<std::integral_constant<IntType,Start + Is>...>;
};

template<typename IntType, IntType Start,std::size_t Size>
using integral_constant_typelist_t =
    typename integral_constant_typelist<
        IntType,Start,make_integer_seq<IntType,Size>
    >::type;

#endif

indexed_type_list.h 不同,此标头的名称不正确.它是googletest工具包的候选人.它定义:

This header, unlike indexed_type_list.h, is not badly named. It's a candidate for your googletest toolkit. It defines:

template<typename IntType, IntType Start,std::size_t Size>
integral_constant_typelist_t

为以下类型:

::testing::Types<std::integral_constant<IntType,Start>,...
                    std::integral_constant<IntType,Start + (Size - 1)>

例如.

integral_constant_typelist_t<int,3,10>

是以下类型:

::testing::Types<
    std::integral_constant<int,3>,...std::integral_constant<int,12>>

这是 dot_matrix< N> 的测试套件:

main.cpp

#include "integral_constant_typelist.h"
#include "dot_matrix.h"

using arbitrary = std::integral_constant<std::size_t,42>;

// A fixture template for N-variant tests
template<
    typename T // = `std::integral_constant<std::size_t, N>`, for some `N`
> struct TestDotMatrixVariant : ::testing::Test
{
    using int_type = typename T::value_type; // = std::size_t
    static constexpr int_type N_param() {
        return T::value;    // = N
    }
    using test_type = dot_matrix<N_param()>;
    dot_matrix<N_param()> const & get_specimen() const {
        return _specimen;
    }
    dot_matrix<N_param()> & get_specimen() {
        return _specimen;
    }
protected:
    test_type _specimen;
};

// A fixture for invariant tests
struct TestDotMatrixInvariant : TestDotMatrixVariant<arbitrary>{};

// Invariant test
TEST_F(TestDotMatrixInvariant,IsSquare){
    auto const & specimen = get_specimen();
    auto side = specimen.side();
    EXPECT_EQ(specimen.area(),side * side);
}

// Another invariant test
TEST_F(TestDotMatrixInvariant, IsConsistent){
    auto const & specimen = get_specimen();
    auto cap = specimen.filled() + specimen.vacant();
    EXPECT_EQ(specimen.area(),cap);
}

// Yet another invariant test
TEST_F(TestDotMatrixInvariant,OutOfRangeGetXThrows)
{
    auto const & specimen = get_specimen();
    auto x = specimen.side() + 1;
    EXPECT_THROW(specimen.get(x,0),std::out_of_range);
}

// More invariant tests...

// An N-variant test case
TYPED_TEST_CASE_P(TestDotMatrixVariant);

// An N-variant test
TYPED_TEST_P(TestDotMatrixVariant,SizeIsRight){
    EXPECT_EQ(this->N_param(),this->get_specimen().side());
}

REGISTER_TYPED_TEST_CASE_P(TestDotMatrixVariant,SizeIsRight);

using dot_matrices_0_50 = integral_constant_typelist_t<std::size_t,0,50>;

INSTANTIATE_TYPED_TEST_CASE_P(N_0_to_50,TestDotMatrixVariant,dot_matrices_0_50);

// More N-variant test cases and N-variant tests...

int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

编译并链接:

$ g++ -Wall -Wextra -pedantic -std=c++11 -c main.cpp
$ g++ -o testrunner main.o -lgtest -pthread

运行:

$ ./testrunner
[==========] Running 53 tests from 51 test cases.
[----------] Global test environment set-up.
[----------] 3 tests from TestDotMatrixInvariant
[ RUN      ] TestDotMatrixInvariant.IsSquare
[       OK ] TestDotMatrixInvariant.IsSquare (0 ms)
[ RUN      ] TestDotMatrixInvariant.IsConsistent
[       OK ] TestDotMatrixInvariant.IsConsistent (0 ms)
[ RUN      ] TestDotMatrixInvariant.OutOfRangeGetXThrows
[       OK ] TestDotMatrixInvariant.OutOfRangeGetXThrows (0 ms)
[----------] 3 tests from TestDotMatrixInvariant (0 ms total)

[----------] 1 test from N_0_to_50/TestDotMatrixVariant/0, where TypeParam = std::integral_constant<unsigned long, 0ul>
[ RUN      ] N_0_to_50/TestDotMatrixVariant/0.SizeIsRight
[       OK ] N_0_to_50/TestDotMatrixVariant/0.SizeIsRight (0 ms)
[----------] 1 test from N_0_to_50/TestDotMatrixVariant/0 (0 ms total)

[----------] 1 test from N_0_to_50/TestDotMatrixVariant/1, where TypeParam = std::integral_constant<unsigned long, 1ul>
[ RUN      ] N_0_to_50/TestDotMatrixVariant/1.SizeIsRight
main.cpp:58: Failure
Expected equality of these values:
  this->N_param()
    Which is: 1
  this->get_specimen().side()
    Which is: 2
[  FAILED  ] N_0_to_50/TestDotMatrixVariant/1.SizeIsRight, where TypeParam = std::integral_constant<unsigned long, 1ul> (0 ms)
[----------] 1 test from N_0_to_50/TestDotMatrixVariant/1 (0 ms total)
...
...
...
[----------] 1 test from N_0_to_50/TestDotMatrixVariant/49, where TypeParam = std::integral_constant<unsigned long, 49ul>
[ RUN      ] N_0_to_50/TestDotMatrixVariant/49.SizeIsRight
main.cpp:58: Failure
Expected equality of these values:
  this->N_param()
    Which is: 49
  this->get_specimen().side()
    Which is: 98
[  FAILED  ] N_0_to_50/TestDotMatrixVariant/49.SizeIsRight, where TypeParam = std::integral_constant<unsigned long, 49ul> (0 ms)
[----------] 1 test from N_0_to_50/TestDotMatrixVariant/49 (0 ms total)

[----------] Global test environment tear-down
[==========] 53 tests from 51 test cases ran. (1 ms total)
[  PASSED  ] 4 tests.
[  FAILED  ] 49 tests, listed below:
[  FAILED  ] N_0_to_50/TestDotMatrixVariant/1.SizeIsRight, where TypeParam = std::integral_constant<unsigned long, 1ul>
...
...
...
[  FAILED  ] N_0_to_50/TestDotMatrixVariant/49.SizeIsRight, where TypeParam = std::integral_constant<unsigned long, 49ul>

49 FAILED TESTS

所有不变式测试均通过.对 dot_matrix< 0> 的变体测试 SizeIsRight 通过了它应有的测试.然后呢通过 dot_matrix< 49> 对于 dot_matrix< 1> 失败,

All of the invariant tests passed. Variant test SizeIsRight passed, as it should, for dot_matrix<0>. Then it failed, as it should, for dot_matrix<1> through dot_matrix<49>.

更好的调试:

static constexpr std::size_t side() {
    // return N * 2; <-- Wrong
    return N; // <-- Right
}

然后:

$ ./testrunner
[==========] Running 53 tests from 51 test cases.
[----------] Global test environment set-up.
[----------] 3 tests from TestDotMatrixInvariant
[ RUN      ] TestDotMatrixInvariant.IsSquare
[       OK ] TestDotMatrixInvariant.IsSquare (0 ms)
[ RUN      ] TestDotMatrixInvariant.IsConsistent
[       OK ] TestDotMatrixInvariant.IsConsistent (0 ms)
[ RUN      ] TestDotMatrixInvariant.OutOfRangeGetXThrows
[       OK ] TestDotMatrixInvariant.OutOfRangeGetXThrows (0 ms)
[----------] 3 tests from TestDotMatrixInvariant (0 ms total)

[----------] 1 test from N_0_to_50/TestDotMatrixVariant/0, where TypeParam = std::integral_constant<unsigned long, 0ul>
[ RUN      ] N_0_to_50/TestDotMatrixVariant/0.SizeIsRight
[       OK ] N_0_to_50/TestDotMatrixVariant/0.SizeIsRight (0 ms)
[----------] 1 test from N_0_to_50/TestDotMatrixVariant/0 (0 ms total)
...
...
...
[----------] 1 test from N_0_to_50/TestDotMatrixVariant/49, where TypeParam = std::integral_constant<unsigned long, 49ul>
[ RUN      ] N_0_to_50/TestDotMatrixVariant/49.SizeIsRight
[       OK ] N_0_to_50/TestDotMatrixVariant/49.SizeIsRight (0 ms)
[----------] 1 test from N_0_to_50/TestDotMatrixVariant/49 (0 ms total)

[----------] Global test environment tear-down
[==========] 53 tests from 51 test cases ran. (1 ms total)
[  PASSED  ] 53 tests.

一切都很好.

这篇关于Google测试-为模板类实例化生成值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆