增强测试声明以支持多种测试
虽然单个测试有效,但尝试添加另一个测试不会生成。这就是我在创造中试图做的.cpp通过添加另一个测试。其中一个测试为空,第二个测试抛出一个 int。以下是我们刚刚尝试使用的两个场景:
#include"../Test.h"
TEST
{
}
TEST {
throw 1;
}
失败是由于 Test 类被声明了两次,以及 run 方法。每次使用 Test 类时,TEST 宏都会声明该类的新全局实例。每个实例称为测试。我们在代码中看不到类或实例,因为它们被 TEST 宏隐藏。
我们需要修改 TEST 宏,以便它生成唯一的类和实例名称。在我们这样做的同时,让我们也修复测试本身的名称。我们不希望所有测试都具有名称“testCanBeCreated”,并且由于名称需要来自测试声明,因此我们还需要修改 TEST 宏以接受字符串。这是新创造的方式。cpp 文件应如下所示:
#include"../Test.h"
TEST("Test can be created")
{
}
TEST("Test with throw can be created") {
throw 1;
}
这让我们可以为每个测试提供句子名称,而不是将名称视为单个单词的函数名称。我们仍然需要修改 TEST 宏,但最好先从预期的用法开始,然后让它工作。
为了创建唯一的类和实例名称,我们可以向程序员要求一些独特的东西,但是类的类型名称和该类的实例名称确实是编写测试的程序员不需要担心的细节。要求提供唯一名称只会使详细信息可见。我们可以改用基名称,并向其添加声明测试的行号,以使类名和实例名都唯一。
宏能够获取使用该宏的源代码文件的行号。我们所要做的就是通过附加此行号来修改生成的类和实例名称。
如果这很容易就好了。
所有宏都由预处理器处理。它实际上比这要复杂一些,但从预处理器的角度思考是一个很好的简化。预处理器知道如何执行简单的文本替换和操作。编译器永远不会看到使用宏编写的原始代码。相反,编译器会在预处理器完成后看到最终结果。
我们将需要两组在 Test 中声明的宏。 h.一个集合将生成一个唯一的类名,例如,如果在第 7 行使用了 TEST 宏,则为 Test7。另一组宏将生成唯一的实例名称
我们需要一组宏,因为从行号到串联结果需要多个步骤。如果这是您第一次看到这样使用的宏,那么发现它们令人困惑是正常的。宏使用简单的文本替换规则,起初对我们来说似乎是额外的工作。从行号到唯一名称需要多个文本替换步骤,这些步骤不是 obviouas。宏如下所示:
#define MERETDD_CLASS_FINAL(line) Test ## line
#define MERETDD_CLASS_RELAY( line) MERETDD_CLASS_FINAL(line)
#define MERETDD_CLASS MERETDD_CLASS_RELAY(_LINE_)
#define MERETDD_INSTANCE_FINAL(line) test ## line
#define MERETDD_INSTANCE_RELAY(line) MERETDD_INSTANCE_FINAL(
line)
#define MERETDD_INSTANCE MERETDD_INSTANCE_RELAY(LINE_)
每组需要三个宏。要使用的宏是每个集合中的最后一个宏,MERETDD_CLASS和MERETDD_INSTANCE。其中每个都将替换为使用 the_LINE 值的中继宏。继电器宏将看到实际的行号,而不是of_LINE_and继电器宏将被替换为最终宏和给定的行号。最后一个宏将使用 ## 运算符进行串联。我确实警告过你,如果这很容易就好了。我相信这是许多程序员避免宏的原因之一。至少你已经完成了本书中最困难的宏用法。
例如,最终结果将是类名的测试 7 和实例名称的测试 7。这两组宏之间唯一真正的区别是类名使用大写的 T 进行测试,而实例名使用小写的 t 进行测试。
需要将类和实例宏添加到 Test 中。h 在需要使用它们的 TEST 宏的定义正上方。所有这些都有效,因为即使 TEST 宏看起来使用许多源代码行,请记住每一行都以反斜杠结尾。这会导致所有内容都集中在一行代码上。这样,每次使用 TEST 宏时,所有行号都将相同,下次使用时行号将不同。
新的 TEST 宏如下所示:
#define TEST(testName)\
class MERETDD_CLASS : public MereTDD::TestBase { \
public:\
MERETDD_CLASS (std::string_view name)\ :TestBase(name)\
{ \
MereTDD::getTests() .push_back(this);\ }\
void run () override;\ };\
MERETDD_CLASS MERETDD_INSTANCE(testName);\
void MERETDD CLASS::run ()
MERETDD_CLASS宏用于声明类名、声明构造函数、声明全局实例的类型以及将 run 方法声明的范围限定为类。所有这四个宏都将使用相同的行号,因为每行末尾都有反斜杠。
MERETDD_INSTANCE宏仅使用一次来声明全局实例的名称。它还将使用与类名相同的行号。
现在生成项目并运行表明第一个测试通过,因为它实际上没有执行任何操作,第二个测试失败,因为它抛出以下内容:
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 N 天,点击查看活动详情”