我想使用断言来测试gcd函数,但我不知道如何捕获异常(并防止程序崩溃)。
int gcd(int a, int b) {
if(a<0 || b<0) {
throw "Illegal argument";
}
if(a==0 || b==0)
return a+b;
while(a!=b) {
if(a>b) {
a = a - b;
}
else {
b = b - a;
}
}
return a;
}
void test_gcd() {
assert(gcd(16,24) == 8);
assert(gcd(0, 19) == 19);
try {
gcd(5, -15);
assert(false);
} catch (char* s) {
assert(true);
cout << "Illegal";
}
}
答案 0 :(得分:2)
“我想使用断言来测试gcd函数,但我不知道如何捕获异常(并防止程序崩溃)。” < / p>
正如reference documentation assert()
中所述,是一个实现定义的宏(强调我的):
#ifdef NDEBUG #define assert(condition) ((void)0) #else #define assert(condition) /*implementation defined*/ #endif
如果未定义
NDEBUG
,则assert
检查其参数(必须具有标量类型)是否等于零。如果是,则断言输出标准错误输出 的实现特定诊断信息,并调用std::abort
。诊断信息必须包括表达文本,以及标准宏__FILE__
,__LINE__
和标准变量__func__
的值。
因此 assert()
不会引发异常 。要测试代码并正确使用异常,您应该具有以下内容,其中expect_true()
是打印消息的内容,如果参数的计算结果为false
而不是abort()
程序:
int gcd(int a, int b) {
if(a<0 || b<0) {
throw std::invalid_argument("a and b must be negative values");
}
// ...
}
#define expect_true(arg) \
do { \
if(!(arg)) { \
std::cout << "Unexpected false at " \
<< __FILE__ << ", " << __LINE__ << ", " << __func__ << ": " \
<< #arg \
<< std::endl; } \
} while(false);
void test_gcd() {
expect_true(gcd(16,24) == 8);
expect_true(gcd(0, 19) == 19);
bool exceptionCaught = false;
try {
gcd(5, -15);
} catch (const std::invalid_argument& ex) {
cout << "Illegal as expected" << endl;
exceptionCaught = true;
}
expect_true(exceptionCaught);
}
这是一个fully working version。并且another sample未通过测试用例。
此外,由于assert()
将始终中止您的test_gcd()
功能,因此进行单元测试有点乏味。我建议使用一个不错的单元测试框架,您可以更好地控制测试期望并运行各种测试用例。例如。使用像Google Test这样的东西(它将具有EXPECT_TRUE()
的实现。)