Я написал простой класс C ++ для автоматических тестов (который я максимально упростил для вопроса)
class TestCase {
int passed, failed; // keeps the number of tests passed/failed so far.
public:
TestCase(): passed(0), failed(0) {}
void print() const {
int total = passed+failed;
int grade = (total==0? 0: 100*passed/total);
cout << "\n*** Right: " << passed << ". Wrong: " << failed << ". Grade: " << grade << " ***\n";
}
TestCase& check_equal(int actual, int expected) {
if (actual==expected) {
passed++;
} else {
failed++;
cout << "The result is " << actual << " but it should equal " << expected << "!" << endl;
}
return *this;
}
};
Который я использую так:
TestCase testcase;
testcase
.check_equal(sum(1,2), 3)
.check_equal(factorial(5), 120)
...
.check_equal(fibonacci(4), 3)
.print();
Этоработает нормально до тех пор, пока проверенные функции не выдают исключения.Если какая-либо функция внутри «check_equal» выдает исключение - ничего не печатается.Я могу обернуть весь блок в try & catch, например:
TestCase testcase;
try {
testcase
.check_equal(sum(1,2), 3)
.check_equal(factorial(5), 120)
...
.check_equal(fibonacci(4), 3)
} catch (...) {
testcase.print();
}
Но тогда, если первая проверка прошла успешно, а вторая проверка выдает исключение, оценка равна 100, так как пройдено = 1, не удалось =0, всего = 1.Это, очевидно, неправильно.
Я мог бы, конечно, решить, что в случае исключения оценка равна 0, но это тоже неправильно, поскольку некоторые проверки все же были успешными.Я хотел бы, чтобы оценка была, например, числом успешных дел, поделенным на общее количество тестов.Однако класс не знает общего числа тестов, так как исключение происходит до того, как он увидит все тесты!
Возможное решение состоит в том, чтобы обернуть каждый вызов функции, который передается в check_equal, в try-блок catch, но это становится очень громоздким, когда есть много маленьких тестов.
Что такое элегантное решение для исправления этого класса?