Я правильно понимаю что Вы были первым на своём месте работы, кто начал применять юнит-тесты и убедил в их пользе коллег? Расскажите, пожалуйста, как Вам удалось последнее.
Не совсем так. Начался вот тот самый проект для военных, с полугодовыми сроками поставок, и мысль о необходимости тестов как-то одновременно забрела нескольким людям в головы, по совершенно рациональным соображениям. Как-то так вышло, что за практическое велосипедостроение сел я, ну и завертелось.
А с годами "противники" тестов потихоньку от нас уволились :)
Но вообще — я не могу сказать (и в посте вроде бы тоже не утверждал такого), что у нас прям все радужно, покрытие 100% и бегают TDD-шные единороги. Сейчас более-менее покрыты только наши самодельные библиотеки и отдельные куски в проектах (опять же, те, которые одновременно легко тестить и очень нужно протестить).
Собственно, я примерно так и делаю; работа с железом прячется за интерфейсами программными, которые в тестах подделываются.
А где запускать тесты — это отдельный вопрос, эт я в самом начале статьи расписал достаточно подробно, как мне кажется.
Я имею ввиду, что моки все равно нужно делать практически для каждого теста свои, даже если один и тот же модуль и вроде как мок один тоже должен быть, но разные методы одного класса и тесты к ним пишут разные программисты и каждый под свой метод делает отдельный мок.
Вероятно, это зависит от задач. Я лично довольно редко испытываю нужду в новых моках, уж не на каждый тест точно; под группу — ну может быть, хотя это обычно просто структура с пачкой флагов и методов для колбэков.
Иначе говоря, я пока не испытываю острой потребности в генерации моков (а может быть просто не осознаю ее), поэтому в эту сторону копать не стал :)
Ну не все фреймворки умеют тестировать такое. Колонка templates в ссылке, что я дал.
Боюсь, по-прежнему не понимаю, что вы имеете в виду. По ссылке буквально просто "колонка templates", без пояснений :D
Типа, тестить допустимые параметры у метафункций? Такое — нет; насколько я понимаю, для этого нужны или тесты на уровне системы сборки или какие-то извращения с unevaluated context или SFINAE, честно говоря особо не задумывался.
Насколько я понимаю терминологию — это именно юнит-тестирование. Не интеграционное, не системное, не тестирование устройства в сборе — а тестирование отдельных программных компонентов.
Разумеется, в тестах могут быть ошибки, документация может быть неточной и т.д. и т.п. Наличие юнит-тестов не отменяет необходимость тестирования на всех остальных уровнях.
И почему вам сложно просто накидать десяток наименований тестируемых функций если вы так широко применяете юнит-тестирование?
Я хотел привести пример, который был бы более-менее понятен сам по себе (и, собственно, привел его в предыдущем комментарии). Конечно, я могу сюда вставить огромный листинг, только что он вам скажет? Что вы хотите в нем увидеть?
Скажем тоже работал с китайскими дешевыми лазерными лидарами.
Они могут выдать непредсказуемые строки, которые неточно приведены в документации.
В моем случае это был датчик с военной приемкой, поэтому документация все же была более-менее.
И потом — а что делать-то? Это ведь реальная ситуация; срок поставки — полгода, через полгода времени писать уже не будет. Писать "на шару" и не тестировать никак?
Моки — просто руками -_- Не дорос я до генераторов.
Для часто используемых вещей моки просто уже написаны.
Поддерживает ли последний рассмотренный фреймворк с++17 и шаблоны? Ну типа, variadic templates?
Последний фреймворк — всмысле мой велосипед? Ну, сам он под с++17 должен собраться (хотя я не проверял, но там зависимостей даже от С++11 нет жестких).
Ну, скажем, есть некий датчик, с которым нужно общаться по некоему протоколу.
Датчик физически получить на руки можно примерно через полгода, но документация на него есть.
Значит, можно писать код и тестировать его, подсовывая на вход данные, которые составлены по документации.
Можно было бы написать полноценный, физический имитатор датчика и подключать к нему нашу плату — а можно написать тест, который проверит конкретный кусок кода.
Выгода — все делается программно, не нужно писать какие-то дополнительные вспомогательные программы или разрабатывать новые платы. Плюс это хорошо автоматизируется.
Пример какой-то такой будет:
Spoiler header
UMBA_TEST("Task should parse answer and put distance in the register")
{
::umba::setTaskCycleCounter(1);
// делаем вид, что передача уже завершена
osSemaphoreGive( uartMock.m_transmitCompleteSem );
// имитируем ответ от датчика с первым адресом
// ибо первый запрос должен быть к нему
uint16_t x = presendRndAnswer(1);
run_task();
UMBA_CHECK( testTable.getReg16Val( REG_RO_LS5_1_DIST_0) == x, "Distance from answer should be in the register");
UMBA_CHECK
(
testTable.getRegVal( REG_RO_LS5_STATUS ) == Ls5Task::status_error,
"Common state should be error because only one sensor has answered"
);
return 0;
}
static void presendAnswer(uint8_t adr, uint16_t data)
{
// шаблон ответа на запрос расстояния
static char answer[] = {"!08LR55555\r"};
uint8_t ansSize = sizeof(answer)-1;
// преобразуем адрес в строку
uint8ToAscii(adr, answer+1);
// преобразуем данные в строку
uint16ToAscii(data, answer+5);
// заполним очередь
uartMock.receiveData( answer, ansSize );
}
// предпослать ответ с рандомными данными
static uint16_t presendRndAnswer(uint8_t adr)
{
using common_functions::xorshiftRandomByte;
uint16_t x = xorshiftRandomByte()<<8 | xorshiftRandomByte();
presendAnswer(adr, x);
return x;
}
Мое самое любимое — при регистрации макс. длина не указана, спокойно вводишь длинный пароль, но он молча обрезается. И потом вводишь пароль во время логина — а он не подходит! Копируешь, вставляешь — все равно не подходит!
Возможно еще, что вы (не сознательно, конечно) выбрали такую метрику, сравнение по которой подтверждает вашу точку зрения.
Допустим, мне лично кажется не совсем корректным оценивать эмоциональную окраску текста целой песни по отдельным словами. Нет ли возможности оценить окраску всего текста? Или предложений/абзацев?
Не совсем так. Начался вот тот самый проект для военных, с полугодовыми сроками поставок, и мысль о необходимости тестов как-то одновременно забрела нескольким людям в головы, по совершенно рациональным соображениям. Как-то так вышло, что за практическое велосипедостроение сел я, ну и завертелось.
А с годами "противники" тестов потихоньку от нас уволились :)
Но вообще — я не могу сказать (и в посте вроде бы тоже не утверждал такого), что у нас прям все радужно, покрытие 100% и бегают TDD-шные единороги. Сейчас более-менее покрыты только наши самодельные библиотеки и отдельные куски в проектах (опять же, те, которые одновременно легко тестить и очень нужно протестить).
Так что увы, никакого управленческого чуда.
Собственно, я примерно так и делаю; работа с железом прячется за интерфейсами программными, которые в тестах подделываются.
А где запускать тесты — это отдельный вопрос, эт я в самом начале статьи расписал достаточно подробно, как мне кажется.
Вероятно, это зависит от задач. Я лично довольно редко испытываю нужду в новых моках, уж не на каждый тест точно; под группу — ну может быть, хотя это обычно просто структура с пачкой флагов и методов для колбэков.
Иначе говоря, я пока не испытываю острой потребности в генерации моков (а может быть просто не осознаю ее), поэтому в эту сторону копать не стал :)
Боюсь, по-прежнему не понимаю, что вы имеете в виду. По ссылке буквально просто "колонка templates", без пояснений :D
Типа, тестить допустимые параметры у метафункций? Такое — нет; насколько я понимаю, для этого нужны или тесты на уровне системы сборки или какие-то извращения с unevaluated context или SFINAE, честно говоря особо не задумывался.
Насколько я понимаю терминологию — это именно юнит-тестирование. Не интеграционное, не системное, не тестирование устройства в сборе — а тестирование отдельных программных компонентов.
Разумеется, в тестах могут быть ошибки, документация может быть неточной и т.д. и т.п. Наличие юнит-тестов не отменяет необходимость тестирования на всех остальных уровнях.
Я хотел привести пример, который был бы более-менее понятен сам по себе (и, собственно, привел его в предыдущем комментарии). Конечно, я могу сюда вставить огромный листинг, только что он вам скажет? Что вы хотите в нем увидеть?
В моем случае это был датчик с военной приемкой, поэтому документация все же была более-менее.
И потом — а что делать-то? Это ведь реальная ситуация; срок поставки — полгода, через полгода времени писать уже не будет. Писать "на шару" и не тестировать никак?
Спасибо :)
Моки — просто руками -_- Не дорос я до генераторов.
Для часто используемых вещей моки просто уже написаны.
Последний фреймворк — всмысле мой велосипед? Ну, сам он под с++17 должен собраться (хотя я не проверял, но там зависимостей даже от С++11 нет жестких).
А что вы имеете в виду под поддержкой?
Ну, скажем, есть некий датчик, с которым нужно общаться по некоему протоколу.
Датчик физически получить на руки можно примерно через полгода, но документация на него есть.
Значит, можно писать код и тестировать его, подсовывая на вход данные, которые составлены по документации.
Можно было бы написать полноценный, физический имитатор датчика и подключать к нему нашу плату — а можно написать тест, который проверит конкретный кусок кода.
Выгода — все делается программно, не нужно писать какие-то дополнительные вспомогательные программы или разрабатывать новые платы. Плюс это хорошо автоматизируется.
Пример какой-то такой будет:
Комфорт — понятие относительное, но я в любом случае связан "политикой компании" так сказать :)
Ммм, возможно дело в том, что у вас Линукс :)
Спасибо!
Спасибо!
Ого! А cfg-шниками не поделитесь?
А вы случайно 1986ВЕ1 не побеждали через stlink?
А Therac разве не на ассемблере программировали?
Меня лично в Ruby слегка напугало отсутствие привычных (по С) областей видимости.
Даа, а designated initializers в С++ выглядят так же, но работают немножко иначе.
С objcopy вставка будет на этапе линковки (если я ничего не путаю), а значит:
А расположение и тут можно будет настроить с помощью атрибута у массива.
Т_Т
Предложение вроде есть, но по понятным причинам не хотят, чтобы это выглядело как директива препроцессора.
Мое самое любимое — при регистрации макс. длина не указана, спокойно вводишь длинный пароль, но он молча обрезается. И потом вводишь пароль во время логина — а он не подходит! Копируешь, вставляешь — все равно не подходит!
Все-таки качественный онлайн курс — это и видеоролики, и "квизы", и задания с автоматической проверкой, и форум, на котором отвечают преподаватели.
Возможно еще, что вы (не сознательно, конечно) выбрали такую метрику, сравнение по которой подтверждает вашу точку зрения.
Допустим, мне лично кажется не совсем корректным оценивать эмоциональную окраску текста целой песни по отдельным словами. Нет ли возможности оценить окраску всего текста? Или предложений/абзацев?