LINUX.ORG.RU

Тестирование в С++, как проверить правильность указанных свойств?

 ,


0

1

Допустим есть такой код с ошибкой:

struct Cmd {
	Operation op = Operation::...;
	double subtractor = 0.;
	double multipler = 0.;
};

void randomModifSubtractor(Cmd& cmd) {
	double& v = cmd.multipler; // <- ЭТО ОШИБКА, д.б. subtractor
	v = static_cast<double>(rand()) / RAND_MAX; // для демо сойдет
}

void randomModifCmd(Cmd& cmd) {
	if (rand() % 2 == 0)
		randomModifSubtractor(cmd);
	else
		randomModifMultipler(cmd);
}

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

Как может тестироваться такая ошибка? Или может быть можно по другому написать этот код, что бы ошибка тестировалась или минимизировалась ее вероятность?


Ответ на: комментарий от LINUX-ORG-RU

Раздели cmd на две разные структуры. И функции будут принимать два разных типа.

Это то же самое, что strong types.

Я например такое иногда использую (или вариации):

template <class TT, class Tag>
struct UniqValT {

    explicit UniqValT() {}

    explicit UniqValT(TT val) : pValue(val + 1) {
        assert( val < std::numeric_limits<TT>::max() );
    }

    bool operator < (const UniqValT& o) const { return pValue < o.pValue; }
    bool operator == (const UniqValT& o) const { return pValue == o.pValue; }

    explicit operator bool() const { return has(); }

    TT value() const { return pValue-1; }

    bool has() const { return !empty(); }
    bool empty() const { return *this == UniqValT(); }

private:
    TT pValue = 0;
};

а после пишется:

struct Size : public UniqValT<uint, struct Tag_Size> {};

и использование:

void doSomething2(Size sz) {}
void doSomething1(Size sz) { doSomething2(sz); }

...
doSomething1(Size(5));

Числовые значения тогда уже не туда не отправить. Но попытка приделать это к каждой переменной приведет к бесконечной доводке и оптимизации тестирования.

victor79
() автор топика
Последнее исправление: victor79 (всего исправлений: 1)
Ответ на: комментарий от victor79

Ну, да. Но я в своих скромных поделках на сишке так как постоянно то там то тут указатели и подобная «проблема» может выскочить где угодно ибо void* дохрена привык если что сеть на жопку и методично просканировть всё глазками. Хотя в случае ТС конечно сложно, не прям в этом конкретном, а вообще ибо может же быть просто функции принимающие double напрямую и если он не те переменные не тем функциям будет давать то будут расчёты, но как у той секретарши печатающей 1500 знаков в минуту. А если подобным стронг туподефом :D всё фигачить то этих уникальных типов будет столько что запутаешься нахрен. Всё же подобные логические ошибки это тупо баги их надо в первую очередь не дупускать руками и головой, а то на пустом почти месте городится переусложнение кода ИМХО конечно.

Но тут тред про плюсы, а я в них никакой, да есть у вас поболе вариантов обхода таких полупроблем.

LINUX-ORG-RU ★★★★★
()
Ответ на: комментарий от victor79

Да, это только со временем приходит, никто не имеет врожденных способностей к тестированию, их можно только постепенно развивать. Для данного конкретного случая посмотри на C++ template traits и там еще есть Concepts, они помогают проверять типы на этапе компиляции, например

template <typename CMD,
          typename = std::enable_if_t<std::is_base_of_v<ISubstractor, CMD>> >
void  randomModifSubtractor(CMD const & m)
{
   ...
}   

при таком подходе код даже тестировать не надо - он просто не соберется если CMD не будет унаследован от ISubstractor. Данный пример примитивный, там очень много других вариантов задания условий, можно в литературе посмотреть.

Но еще раз повторюсь, что подход в лоб не решит такого рода проблему. Тут нужен набор функциональных тестов, с большим покрытием. К тому же такие довески очень сильно влияют на производительность.

spring
()
Последнее исправление: spring (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.