C ++ Google Test деление на ноль - PullRequest
       31

C ++ Google Test деление на ноль

0 голосов
/ 19 сентября 2018

Я учусь писать модульные тесты и начал с простого класса «Калькулятор», который я хотел протестировать.Я выяснил, как использовать функции EXPECT / ASSERT, какие тестовые примеры и т. Д., Но у меня возникла проблема, когда я хотел проверить деление на ноль.Есть ли возможность проверить это?Я имею в виду, что я должен написать в качестве результата теста?Есть ли что-то вроде "ОШИБКА"?Или я должен использовать исключения?

Это мои тесты:

TEST(TestCalc, TestPos) 
{
    Calc calculate;
    EXPECT_EQ(10.0, calculate.add(5.0, 5.0));
    EXPECT_EQ(9, calculate.mul(3, 3));
    EXPECT_EQ(9, calculate.div(27, 3));
    EXPECT_EQ(9, calculate.sub(12, 3));
}
TEST(TestCalc, TestNeg)
{
    Calc calculate;
    EXPECT_EQ(-1.0, calculate.add(5.0, -6.0));
    EXPECT_EQ(-9, calculate.mul(3, -3));
    EXPECT_EQ(-9, calculate.div(27, -3));
    EXPECT_EQ(15, calculate.sub(12, -3));
}

TEST(TestCalc, TestZero)
{
    Calc calculate;
    EXPECT_EQ(10.0, calculate.add(5.0, 0));
    EXPECT_EQ(9, calculate.mul(3, 0));
    EXPECT_EQ(, calculate.div(27,0));
    EXPECT_EQ(12, calculate.sub(12,0));
}

Ответы [ 3 ]

0 голосов
/ 19 сентября 2018

Я не согласен с @Ketzu.У вас есть ожидание того, как должен вести себя калькулятор при делении на ноль.

EXPECT_EQ(, calculate.div(27,0));

Возможно, это ожидание не совсем правильно сформулировано в этом тесте.

Если calculate.div(27,0) выдает исключение, чем выможет поймать это исключение, и ваш тест не пройден, если он не сгенерирован.Вы можете написать что-то вроде этого

TEST(ExceptionTest, ExpectThrowsSpecificException) {
    try {
        calculate.div(27,0);
        FAIL() << "calculate.div(27,0) should throw an error, since a     division by zero is not valid\n";
    } catch (TestException& exception) {
        EXPECT_THAT(std::string(exception.what()), Eq("VALID_SETTING"));
        EXPECT_THAT(exception.errorCode, Eq(20));
    }
}

См. здесь для подробного обсуждения.

Если не сгенерировано исключение, как вы обнаруживаете ненормальное использование calculate.div?

0 голосов
/ 20 сентября 2018

Есть ли возможность проверить это?Я имею в виду, что я должен написать в качестве результата теста?Есть ли что-то вроде "ОШИБКА"?Или я должен использовать исключения?

Это основной вопрос, который вам нужно задать (и ответить) себе - как должен работать ваш калькулятор (в данном случае функция Calc::div()) ведет себя, если задан неверный ввод.Есть несколько способов, которыми он может себя вести:

  1. Crash .Это (обычно) поведение, которое вы получаете, если вы делите на ноль в C ++ (технически это поведение не определено, поэтому компилятор может сделать ЧТО-ТО . К счастью (для нас) большинство компиляторов соглашаются, что завершение всего процесса«правильное» НИЧЕГО сделать здесь)
  2. Вернуть некоторое значение .Вы можете вернуть (в случае деления на ноль) бесконечность .Или возможно NaN .Или любое другое значение, которое имеет смысл в вашем контексте.Однако этот подход смешивает результат с обработкой ошибок , что в настоящее время не рекомендуется (так как это заставит вас проверять каждый вызов функции на «результаты ошибок» - и если вызабудьте одну проверку, вы получите неприятные ошибки при продолжении операций с недействительными / поддельными значениями.)
  3. Бросить исключение .Вы можете выдать исключение, сигнализирующее, что что-то пошло не так.Это обычно используемый метод в настоящее время (за исключением очень чувствительных к производительности вещей, где каждая микросекунда имеет значение), поскольку он аккуратно отделяет нормальный путь (возвращаемое значение результата) от пути ошибки (исключение) (и если вы забудете обработать исключение, вызаметит сразу вместо использования неверного значения, как в варианте 2)

Как только вы определились с вашим поведением, вы можете проверить его.

Для Вариант 1 gtest предоставляет тесты на смерть .
Для Вариант 2 Вы можете просто подтвердить, что получили ожидаемый результат.
Для Опция 3 вы можете поймать и оценить исключение, либо с помощью утверждений об исключениях , либо с помощью самодельного try { } catch { } с FAIL() в конце блока try (поэтому вы замечаете, что если функция не выдает исключение, когда вы этого ожидаете)

0 голосов
/ 19 сентября 2018

Ваш комментарий

Я думал, что смогу проверить его

предположить недопонимание о тестах.

Ваши тесты проверяют только поведение вашегоклассы - это то, что вы хотите. Тесты никоим образом не являются механизмами обработки ошибок!

Если одна из ваших функций создает сбой приложения с определенными параметрами, ваши тесты не должны помечаться как правильные.

Как ее решить (исключение и подходящий макрос) см. В комментарии Джона.

...