Я пересматриваю код, который реализует формулу, и я хочу сделать это сначала для тестирования, чтобы улучшить свои навыки тестирования и оставить код включенным.Как проверить многопараметрическую формулу
Этот конкретный фрагмент кода представляет собой формулу, которая принимает 3 параметра и возвращает значение. У меня даже есть несколько таблиц данных с ожидаемыми результатами для разных входных данных, поэтому теоретически я могу использовать jsst типа zillion тестов, просто изменяя входные параметры и проверяя результаты с соответствующим ожидаемым значением.
Но я думал, что должен быть лучший способ сделать это, и, глядя на документы, которые я нашел, Value Parameterized Tests.
Итак, теперь я знаю, как автоматически создавать тесты для разных входов.
Но как мне получить соответствующий ожидаемый результат, чтобы сравнить его с моим рассчитанным?
Единственное, что мне удалось найти, это статическая таблица поиска и статический член в текстовом инструменте, который является индексом таблицы поиска и увеличивается в каждом прогоне. Что-то вроде этого:
#include "gtest/gtest.h"
double MyFormula(double A, double B, double C)
{
return A*B - C*C; // Example. The real one is much more complex
}
class MyTest:public ::testing::TestWithParam<std::tr1::tuple<double, double, double>>
{
protected:
MyTest(){ Index++; }
virtual void SetUp()
{
m_C = std::tr1::get<0>(GetParam());
m_A = std::tr1::get<1>(GetParam());
m_B = std::tr1::get<2>(GetParam());
}
double m_A;
double m_B;
double m_C;
static double ExpectedRes[];
static int Index;
};
int MyTest::Index = -1;
double MyTest::ExpectedRes[] =
{
// C = 1
// B: 1 2 3 4 5 6 7 8 9 10
/*A = 1*/ 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0,
/*A = 2*/ 1.0, 3.0, 5.0, 7.0, 9.0, 11.0, 13.0, 15.0, 17.0, 19.0,
/*A = 3*/ 2.0, 5.0, 8.0, 11.0, 14.0, 17.0, 20.0, 23.0, 26.0, 29.0,
// C = 2
// B: 1 2 3 4 5 6 7 8 9 10
/*A = 1*/ -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0,
/*A = 2*/ -2.0, 0.0, 2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0,
/*A = 3*/ -1.0, 2.0, 5.0, 8.0, 11.0, 14.0, 17.0, 20.0, 23.0, 26.0,
};
TEST_P(MyTest, TestFormula)
{
double res = MyFormula(m_A, m_B, m_C);
ASSERT_EQ(ExpectedRes[Index], res);
}
INSTANTIATE_TEST_CASE_P(TestWithParameters,
MyTest,
testing::Combine(testing::Range(1.0, 3.0), // C
testing::Range(1.0, 4.0), // A
testing::Range(1.0, 11.0) // B
));
Это хороший подход, или есть ли лучший способ, чтобы получить право ожидаемого результата для каждого прогона?
Спасибо. В этом случае спецификация, которую я должен соблюдать, дает формулу плюс некоторые таблицы с ожидаемыми результатами для некоторых значений. Я могу быть вполне уверен, что, если мои результаты совпадут с этими таблицами, я сделал это нормально.Фактически, я уже нашел некоторые неправильные значения в спецификации, благодаря испытаниям. – MikMik
Это замечательно. Если вы добавите тестовые данные в свой тестовый класс, проблема будет в будущем, если вы хотите протестировать другой сценарий, вам нужно снова обновить свой класс. Но если вы получите доступ к своим тестовым данным из внешнего файла, ваша работоспособность тестового случая будет уменьшена. Потому что вы собираетесь обновить этот плоский файл, чтобы добавить новые тестовые данные. это оно. Не нужно создавать свой класс, а затем снова развертывать его. –
@PritamKarmakar, вы имеете в виду, что ремонтопригодность теста будет увеличена, правильно? Усилия, необходимые для его поддержания, будут уменьшены. – Alan