Как вы разрабатываете и тестируете задачи
Что проверяют
Есть ли у вас осознанный цикл от задачи до мержа и какими инструментами вы ловите ошибки, характерные именно для C++. Следом обычно просят рассказать о последнем баге, который прошёл мимо тестов, или спрашивают, пишете ли вы тесты до кода.
Как отвечать
Опишите свой реальный процесс по этапам и на каждом назовите инструмент:
- перед кодом: разобрать требования и критерии приёмки, выписать граничные случаи (пустой ввод, переполнение, многопоточный доступ), прикинуть интерфейс;
- сборка: CMake, предупреждения
-Wall -Wextraи в CI-Werror, сборка несколькими компиляторами (GCC, Clang, при необходимости MSVC), форматирование черезclang-format; - юнит-тесты: GoogleTest с GoogleMock или Catch2, запуск через CTest. Зависимости подменяются через интерфейсы или шаблонные параметры;
- санитайзеры: тестовая сборка с
-fsanitize=address,undefinedи отдельная с-fsanitize=thread, потому что ThreadSanitizer не совмещается с AddressSanitizer в одной сборке. Valgrind выручает, когда пересобрать код с санитайзером нельзя; - статический анализ:
clang-tidy, cppcheck или PVS-Studio в CI; - по необходимости: фаззинг через libFuzzer для парсеров и всего, что принимает внешние данные, Google Benchmark для кода с требованиями к скорости, покрытие через
llvm-covили gcov; - ревью и CI: мерж только после зелёного пайплайна и ревью.
Про TDD говорите честно. Если тест первым вы пишете только при исправлении бага (сначала воспроизводящий тест, потом исправление), так и скажите, это нормальная практика. Приведите пример с цифрами: сколько идёт сборка с тестами, что поймал санитайзер, какой баг всё же ушёл в прод и что вы после этого поменяли в процессе.
Где спотыкаются
Рассказывают только про юнит-тесты. В C++ зелёные тесты не гарантируют отсутствия неопределённого поведения, и без санитайзеров вопрос «как вы ловите UB» ставит в тупик.
Заявляют «всегда работаем по TDD», а на уточнении про тест к конкретной функции не могут показать, как это выглядело.
Говорят «тестирует QA», перекладывая качество на соседний отдел. Разработчику на C++ такое прощают хуже всего: ошибки памяти находит либо он сам, либо пользователь.