c++ - 如何将 TYPED_TEST 中的一些测试用例标记为预期失败?
问题描述
我正在从事一个 C++ 学习项目,其双重目标是学习如何编写模板代码以及学习如何使用 GoogleTest。我的项目目标是实现一个工作四元数类以及使用 GoogleTest 编写的功能测试。
到目前为止,我的课程运行良好,但我想将一些 GoogleTest 测试用例标记为“预期失败”。这是四元数相关构造函数的签名 -
template <typename T>
class quaternion {
template <typename U, typename V, typename W, typename X>
quaternion(U u, V v, W w, X x);
};
我正在使用 GoogleTest 编写一些 TYPED_TEST 测试用例,其中我尝试使用诸如 unsigned char、char 等初始化器创建给定类型T的四元数......
这是我的类型列表
using MyTypes = ::testing::Types<char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned long, long long, unsigned long long, float, double, long double>;
这是测试夹具 -
TYPED_TEST(QuaternionTests, DirectInitialization00) {
unsigned int i = 5, j = 235, k = 67, l = 82;
this->SetUp(i, j, k, l);
EXPECT_EQ(this->q.a, 5);
EXPECT_EQ(this->q.b, 235);
EXPECT_EQ(this->q.c, 67);
EXPECT_EQ(this->q.d, 82);
}
其中 SetUp 只是调用四元数构造函数。
自然,当四元数的类型为char时,此测试会失败,因为四元数不能为成员b保存值 235 ( unsigned int ) 。
我的问题是 - 有没有办法在 TYPED_TEST 宏的范围内将T == char和unsigned int的特定组合标记为“预期失败”?还是我必须切换到常规的 TEST 宏?
解决方案
您可以修改测试主体来处理这种情况。据我所知,没有办法将类型参数标记为预期失败。
[例如,在 Python 的pytest
框架中,这可以通过pytest.param(int, marks=pytest.mark.xfail)
.]
当然可以自省类型参数并从测试主体中跳过测试。Google Test现在有一个GTEST_SKIP()
宏,我怀疑它可以从 Google Test 1.10.0 获得。
如果该宏不可用,您可以使用不太明确的SUCCEED()
宏,然后是一条return
语句:
TYPED_TEST(QuaternionTests, DirectInitialization00) {
// Could also check `std::numeric_limits<T>::max()`
// or `sizeof(T)`.
using T = typename QuaternionTests::TypeParam;
if constexpr (std::is_same_v<T, char>) {
// with gtest version 1.10.0 and later (?):
GTEST_SKIP() << "Test is not valid with T equal to `char`.";
// or with older versions gtest:
SUCCEED() << "Test is not valid with T equal to `char`.";
return;
}
unsigned int i = 5, j = 235, k = 67, l = 82;
this->SetUp(i, j, k, l);
EXPECT_EQ(this->q.a, 5);
EXPECT_EQ(this->q.b, 235);
EXPECT_EQ(this->q.c, 67);
EXPECT_EQ(this->q.d, 82);
}
另一种选择是引入一个包含标量类型的信息量更大的类型参数,以及有关是否期望成功的信息。例如:
template <typename T, bool ExpectSuccess = true>
struct QTestParam {
using type = T;
using expect_success = std::bool_constant<ExpectSuccess>;
};
using MyTypes = ::testing::Types<
QTestParam<char, /*ExpectSuccess*/ false>,
QTestParam<short int>,
QTestParam<int>,
QTestParam<long int>,
QTestParam<float>,
QTestParam<double>,
>;
然后,您可以像这样定义一个测试类模板,它以一种很好的方式提供对布尔指标的访问:
template <typename Param>
struct QuaternionTests : public ::testing::Test {
using T = Param::type; // scalar type such as int.
constexpr static bool ExpectSuccess() {
return Param::expect_success{};
}
constexpr static bool ExpectFailure() {
return !ExpectSuccess();
}
};
不幸的是,我认为单个测试需要像第一个代码片段那样实现“跳过”逻辑:
TYPED_TEST(QuaternionTests, DirectInitialization00) {
constexpr if (ExpectFailure()) {
GTEST_SKIP();
}
// [...]
};
推荐阅读
- php - 显示词尾取决于性别(波兰语问题),PHP
- sql-server - 在 MS SQL Server 中使用 case...when 语句时,如何屏蔽某些值并保持唯一性?
- timer - 使用计时器读取运行时数据
- android - 为什么 onResponse 方法不起作用?Retrofit2 库
- stored-procedures - Netezza - 如何在没有 REFTABLE 的情况下从存储过程返回多个值
- android - 找不到 Flutter 项目的 lint-gradle-api-26.1.2.jar
- sqlite - 无法在 ionic 中使用 SQLite 插件执行 sql
- javascript - Angular/typescript 排序大于 0 排序小于 0
- laravel - Laravel Spark 用例
- azure - Add-AzureRmApplicationGatewayBackendHttpSettings cmdlet 中的“用于应用服务”参数