Тестирование функций
Функции тестирования возвращают булево значение, которое можно проверить в условных частях областей видимости. Функции тестирования могут быть разделены на встроенные функции и функции библиотек.
См. также Функции замены.
Встроенные функции тестирования
Базовые функции тестирования реализованы как встроенные функции.
cache(variablename, [set|add|sub] [transient] [super|stash], [source variablename])
Это внутренняя функция, которой вам обычно не нужно пользоваться.
Эта функция была введена в Qt 5.0.
CONFIG(config)
Эта функция может быть использована для проверки переменных, помещенных в переменную CONFIG. Это то же самое, что и области видимости, но с дополнительным преимуществом, что вторым параметром можно передать активную конфигурацию. Так как порядок значений важен в CONFIG переменных (то есть, последнее заданное значение будет рассматриваться как активная конфигурация для взаимно исключающих значений), второй параметр может использоваться для указания набора значений для рассмотрения. Например:
CONFIG = debug CONFIG += release CONFIG(release, debug|release):message(Release build!) #will print CONFIG(debug, debug|release):message(Debug build!) #no print
Поскольку release считается активным значением (для анализа функций), она будет использована для генерации файла сборки. В общем случае второй параметр не нужен, но для конкретных взаимно исключающих проверок он неоценим.
contains(variablename, value)
Успешно выполняется, если переменная variablename содержит значение value; в противном случае, завершается неудачей. Можно указать регулярное выражение для параметра value.
Вы можете проверить возвращаемое значение этой функции, используя область видимости.
Например:
contains( drivers, network ) {
# drivers contains 'network'
message( "Configuring for network build..." )
HEADERS += network.h
SOURCES += network.cpp
} Содержание области видимости обрабатывается только в том случае, если переменная drivers содержит значение network. В этом случае соответствующие файлы добавляются в переменные SOURCES и HEADERS.
count(variablename, number)
Успешно выполняется, если переменная variablename содержит список со специфицированным количеством number значений; в противном случае, завершается неудачей.
Эта функция используется для обеспечения того, чтобы объявления внутри области видимости обрабатывались только в том случае, если переменная содержит нужное количество значений. Например:
options = $$find(CONFIG, "debug") $$find(CONFIG, "release")
count(options, 2) {
message(Both release and debug specified.)
} debug(level, message)
Проверяет, работает ли qmake на заданном уровне отладки. Если да, возвращает true и выводит сообщение отладки.
defined(name[, type])
Проверяет, определена ли функция или переменная name. Если type опущено, проверяются все функции. Чтобы проверить только переменные или определенный тип функций, укажите type. Это может иметь следующие значения:
-
testпроверяет только функции тестирования -
replaceпроверяет только функции замены -
varпроверяет только переменные
equals(variablename, value)
Проверяет, равняется ли variablename строке value.
Например:
TARGET = helloworld
equals(TARGET, "helloworld") {
message("The target assignment was successful.")
} error(string)
Эта функция никогда не возвращает значение. qmake отображает string как сообщение об ошибке пользователю и завершает работу. Эту функцию следует использовать только для необратимых ошибок.
Например:
error(An error has occurred in the configuration process.)
eval(string)
Вычисляет содержимое строки с использованием правил синтаксиса qmake и возвращает true. В строке можно использовать определения и присваивания для изменения значений существующих переменных или создания новых определений.
Например:
eval(TARGET = myapp) {
message($$TARGET)
} Примечание: Кавычки могут использоваться для разграничения строки, а возвращаемое значение можно игнорировать, если оно не требуется.
exists(filename)
Проверяет, существует ли файл с заданным filename именем. Если файл существует, функция успешна; в противном случае, она завершается неудачей.
Аргумент filename может содержать подстановочные знаки. В этом случае, эта функция успешна, если любой файл соответствует.
Например:
exists( $(QTDIR)/lib/libqt-mt* ) {
message( "Configuring for multi-threaded Qt..." )
CONFIG += thread
} Примечание: "/" должен использоваться в качестве разделителя каталогов, независимо от используемой платформы.
export(variablename)
Экспортирует текущее значение variablename из локального контекста функции в глобальный контекст.
for(iterate, list)
Инициализирует цикл, который перебирает все значения в list, устанавливая iterate для каждого значения по очереди. Для удобства, если list равно 1..10, iterate будет перебирать значения от 1 до 10.
Например:
LIST = 1 2 3
for(a, LIST):exists(file.$${a}):message(I see a file.$${a}!) greaterThan(variablename, value)
Проверяет, что значение variablename больше, чем value. Сначала эта функция пытается выполнить числовое сравнение. Если хотя бы один из операндов не преобразуется в число, эта функция выполняет строковое сравнение.
Например:
ANSWER = 42
greaterThan(ANSWER, 1) {
message("The answer might be correct.")
} Невозможно напрямую сравнить два числа как строки. В качестве обходного пути создайте временные значения с префиксом, не являющимся числом, и сравните их.
Например:
VALUE = 123
TMP_VALUE = x$$VALUE
greaterThan(TMP_VALUE, x456): message("Condition may be true.") См. также lessThan().
if(condition)
Вычисляет condition. Используется для группирования логических выражений.
Например:
if(linux-g++*|macx-g++*):CONFIG(debug, debug|release) {
message("We are on Linux or Mac OS, and we are in debug mode.")
} include(filename)
Включает содержимое файла, указанного filename, в текущий проект в точке его включения. Эта функция успешна, если filename включён; в противном случае, она завершается неудачей. Включённый файл обрабатывается немедленно.
Вы можете проверить, был ли файл включён, используя эту функцию в качестве условия для области видимости. Например:
include( shared.pri )
OPTIONS = standard custom
!include( options.pri ) {
message( "No custom build options specified" )
OPTIONS -= custom
} infile(filename, var, val)
Успешно выполняется, если файл filename (при парсинге qmake) содержит переменную var со значением val; в противном случае, завершается неудачей. Если вы не указали val, функция проверяет, была ли var присвоена в файле.
isActiveConfig
Это псевдоним для функции CONFIG.
isEmpty(variablename)
Успешно выполняется, если переменная variablename пустая; в противном случае, завершается неудачей. Это эквивалентно count( variablename, 0 ).
Например:
isEmpty( CONFIG ) {
CONFIG += warn_on debug
} isEqual
Это псевдоним для функции equals.
lessThan(variablename, value)
Проверяет, что значение variablename меньше, чем value. Работает как greaterThan().
Например:
ANSWER = 42
lessThan(ANSWER, 1) {
message("The answer might be wrong.")
} load(feature)
Загружает файл функции (.prf) указанный feature, если функция ещё не загружена.
log(message)
Выводит сообщение в консоль. В отличие от функции message, не добавляет текст в начало и не добавляет перенос строки.
Эта функция была введена в Qt 5.0.
См. также message().
message(string)
Всегда успешно выполняется и отображает string как общее сообщение пользователю. В отличие от функции error(), эта функция позволяет продолжить обработку.
message( "This is a message" )
Вышеупомянутая строка приводит к выводу "Это сообщение" в консоль. Использование кавычек необязательно, но рекомендуется.
Примечание: По умолчанию сообщения выводятся для каждого файла Makefile, генерируемого qmake для данного проекта. Если вы хотите гарантировать, что сообщения отображаются только один раз для каждого проекта, проверьте переменную build_pass в сочетании с областью видимости, чтобы отфильтровать сообщения во время сборки. Например:
!build_pass:message( "This is a message" )
mkpath(dirPath)
Создаёт путь к каталогу dirPath. Эта функция является оболочкой функции QDir::mkpath.
Эта функция была введена в Qt 5.0.
requires(condition)
Вычисляет condition. Если условие ложно, qmake пропускает этот проект (и его SUBDIRS) при сборке.
Примечание: Вы также можете использовать переменную REQUIRES для этой цели. Однако мы рекомендуем использовать эту функцию вместо неё.
system(command)
Выполняет заданную command команду в дочерней оболочке. Успешно выполняется, если команда завершается с нулевым кодом выхода; в противном случае, завершается неудачей. Вы можете проверить возвращаемое значение этой функции, используя область видимости.
Например:
system("ls /bin"): HAS_BIN = TRUE См. также вариант замены system().
touch(filename, reference_filename)
Обновляет метку времени filename для соответствия метке времени reference_filename.
Эта функция была введена в Qt 5.0.
unset(variablename)
Удаляет variablename из текущего контекста.
Например:
NARF = zort
unset(NARF)
!defined(NARF, var) {
message("NARF is not defined.")
} versionAtLeast(variablename, versionNumber)
Проверяет, что номер версии из variablename больше или равен versionNumber. Номер версии рассматривается как последовательность неотрицательных десятичных чисел, разделенных точкой; любая нечисловая часть строки игнорируется. Сравнение выполняется по частям слева направо; если одна версия является префиксом другой, она считается меньшей.
Эта функция была введена в Qt 5.10.
versionAtMost(variablename, versionNumber)
Проверяет, что номер версии из variablename меньше или равен versionNumber. Работает как versionAtLeast().
Эта функция была введена в Qt 5.10.
warning(string)
Всегда успешно выполняется и отображает string как сообщение об ошибке пользователю.
write_file(filename, [variablename, [mode]])
Записывает значения variablename в файл с именем filename, каждое значение на отдельной строке. Если variablename не указано, создаётся пустой файл. Если mode равно append, а файл уже существует, добавляется в него вместо перезаписи.
Эта функция была добавлена в Qt 5.0.
Библиотека функций тестирования
Сложные функции тестирования реализованы в библиотеке файлов .prf.
packagesExist(packages)
Использует механизм PKGCONFIG, чтобы определить, существуют ли заданные пакеты на момент разбора проекта.
Это может быть полезно для условной активации или деактивации функций. Например:
packagesExist(sqlite3 QtNetwork QtDeclarative) {
DEFINES += USE_FANCY_UI
} А затем, в коде:
#ifdef USE_FANCY_UI
// Use the fancy UI, as we have extra packages available
#endif prepareRecursiveTarget(target)
Упрощает создание целевых задач для всего проекта, аналогичных целевой задаче install, подготавливая целевую задачу, которая итерируется по всем подкаталогам. Например:
TEMPLATE = subdirs SUBDIRS = one two three prepareRecursiveTarget(check)
Подкаталоги, в которых указаны have_no_default или no_<target>_target в их .CONFIG, исключаются из этой целевой задачи:
two.CONFIG += no_check_target
Вы должны вручную добавить подготовленную целевую задачу в QMAKE_EXTRA_TARGETS:
QMAKE_EXTRA_TARGETS += check
Чтобы сделать целевую задачу глобальной, приведенный выше код нужно включить в каждый подкаталог в подпроекте. Кроме того, чтобы эти целевые задачи выполняли какие-либо действия, подпроекты, не являющиеся подкаталогами, должны включать соответствующий код. Самый простой способ сделать это — создать файл пользовательских функций. Например:
# <project root>/features/mycheck.prf
equals(TEMPLATE, subdirs) {
prepareRecursiveTarget(check)
} else {
check.commands = echo hello user
}
QMAKE_EXTRA_TARGETS += check Файл функций должен быть внедрен в каждый подпроект, например, через .qmake.conf:
# <project root>/.qmake.conf CONFIG += mycheck
Эта функция была добавлена в Qt 5.0.
qtCompileTest(test)
Строит проект теста. Если тест проходит, возвращается true, и config_<test> добавляется в переменную CONFIG. В противном случае возвращается false.
Чтобы использовать эту функцию, необходимо загрузить соответствующий файл функций:
# <project root>/project.pro load(configure)
Это также устанавливает переменную QMAKE_CONFIG_TESTS_DIR в подкаталог config.tests родительского каталога проекта. Это значение можно переопределить после загрузки файла функций.
Внутри каталога тестов должен быть один подкаталог на каждый тест, содержащий простой проект qmake. Следующий фрагмент кода иллюстрирует файл .pro проекта:
# <project root>/config.tests/test/test.pro SOURCES = main.cpp LIBS += -ltheFeature # Note that the test project is built without Qt by default.
Следующий фрагмент кода иллюстрирует основной файл .cpp проекта:
// <project root>/config.tests/test/main.cpp
#include <TheFeature/MainHeader.h>
int main() { return featureFunction(); } Следующий фрагмент кода демонстрирует вызов теста:
# <project root>/project.pro qtCompileTest(test)
Если проект теста успешно построен, тест пройден.
Результаты теста автоматически кешируются, что также делает их доступными для всех подпроектов. Поэтому рекомендуется запускать все тесты конфигурации в главном файле проекта.
Чтобы подавить повторное использование кэшированных результатов, передайте CONFIG+=recheck в qmake.
См. также load().
Эта функция была добавлена в Qt 5.0.
qtHaveModule(name)
Проверяет, присутствует ли модуль Qt, указанный через name. Список возможных значений см. в QT.
Эта функция была добавлена в Qt 5.0.1.
© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.2/qmake-test-function-reference.html