Комментарии 9
Интересно а на манер rust не получится пометить функции тесты каким нибудь атрибутом из тех что в стандарте имеются?
В стандарте — не уверен. В перечне стандартных ничего подходящего нет, вроде бы.
С помощью макросов по идее можно облагородить [[gnu::section("test")]]
или __attribute__((section("tests")))
. Тогда все тестовые функции и данные можно разместить в отдельной секции, что даёт ряд плюшек:
- нет путаницы с тестовыми функциями и остальными
- линкер может выкинуть всё тестовое добро при сборке
Без сторонней тулзы, которая парсит код, не получится. Или я что-то упустил?
Не получится, да. В статье как раз и используются «внешние» средства для интроспекции. В том смысле, что приходится прибегать к парсерам, которые разбирают бинарный файл или образ библиотеки и достают информацию оттуда. В противоположность, когда эта информация изначально программным образом доступна самой программе. В принципе, ничто также не мешает программе распарсить свой собственный образ в памяти и найти там информацию, которую возможно сохранил динамический загрузчик.
Я про атрибуты имел в виду то, что можно, скажем, написать
#include <iostream>
[[gnu::section("__TEXT,__tests")]]
void run_test()
{
std::cout << "run_test()\n";
}
void test_function()
{
std::cout << "test_function()\n";
}
тогда функции run_test
и test_function
попадут в разные секции:
$ nm -gU libtest.dylib -s __TEXT __text | grep test
0000000000001380 T __Z13test_functionv
$ nm -gU libtest.dylib -s __TEXT __tests | grep test
0000000000001e80 S __Z8run_testv
Таким образом удобнее фильтровать именно функции-тесты, рассматривая только секцию __tests
.
По идее, можно даже вырезать секцию с тестами из файла при сборке, но я не очень силён в скриптах для компоновщика.
extern "C"
и не будет никакого mangling функций на верхнем уровне. Так что посыл "живите с этим" в корне неверен.
Тесты на Си без SMS и регистрации