Skip to main content
Мы публикуем частые обновления нашей документации, и перевод этой страницы, возможно, еще выполняется. Актуальные сведения см. в документации на английском языке.

Тестирование пользовательских запросов

Вы можете настроить тесты для запросов CodeQL, чтобы убедиться, что они продолжают возвращать ожидаемые результаты в новых выпусках CodeQL CLI.

GitHub CodeQL лицензируется на уровне пользователя после установки. CodeQL можно использовать только для определенных задач в соответствии с лицензионными ограничениями. Дополнительные сведения см. в разделе Сведения о CodeQL CLI.

Если у вас есть учетная запись GitHub Enterprise и лицензия на GitHub Advanced Security, вы можете использовать CodeQL для автоматического анализа, непрерывной интеграции и непрерывной поставки. Вы можете создать корпоративную учетную запись, обратившись в отдел продаж. Дополнительные сведения см. в разделе Сведения о GitHub Advanced Security.

Примечание: Эта статья была перенесена с веб-сайта документации CodeQL в январе 2023 г.

Сведения о тестировании пользовательских запросов

CodeQL предоставляет простую платформу тестирования для автоматического тестирования регрессии запросов. Протестируйте запросы, чтобы убедиться, что они работают должным образом.

Во время теста запроса CodeQL сравнивает результаты, которые пользователь ожидает получить от запроса, с фактически созданными. Если ожидаемые и фактические результаты отличаются, тест запроса завершается сбоем. Чтобы исправить тест, следует выполнить итерацию по запросу и ожидаемым результатам до тех пор, пока фактические и ожидаемые результаты точно не будут совпадать. В этом разделе показано, как создавать тестовые файлы и выполнять в них тесты с помощью test run подкоманды.

Настройка тестового пакета CodeQL для пользовательских запросов

Все тесты CodeQL должны храниться в специальном пакете "тест" CodeQL. То есть каталог для тестовых файлов с файлом qlpack.yml , который определяет:

name: <name-of-test-pack>
version: 0.0.0
dependencies:
  <codeql-libraries-and-queries-to-test>: "*"
extractor: <language-of-code-to-test>

Значение dependencies указывает пакеты CodeQL, содержащие тестируемые запросы. Как правило, эти пакеты разрешаются из источника, поэтому указывать фиксированную версию пакета не требуется. Определяет extractor язык, используемый CLI для создания тестовых баз данных из файлов кода, хранящихся в этом пакете CodeQL. Дополнительные сведения см. в разделе Сведения о пакетах CodeQL.

Может оказаться полезным посмотреть, как организованы тесты запросов в репозитории CodeQL. Каждый язык имеет src каталог , ql/<language>/ql/srcкоторый содержит библиотеки и запросы для анализа баз кода. Наряду с каталогом src test есть каталог с тестами для этих библиотек и запросов.

Каждый test каталог настраивается как тестовый пакет CodeQL с двумя подкаталогами:

  • query-tests ряд подкаталогов с тестами для запросов, хранящихся в каталоге src . Каждый подкаталог содержит тестовый код и файл ссылки QL, указывающий тестируемый запрос.
  • library-tests ряд подкаталогов с тестами для файлов библиотеки QL. Каждый подкаталог содержит тестовый код и запросы, написанные как модульные тесты для библиотеки.

Настройка тестовых файлов для запроса

Для каждого запроса, который требуется протестировать, необходимо создать вложенный каталог в тестовом пакете CodeQL. Затем добавьте следующие файлы в подкаталог перед выполнением тестовой команды:

  • Файл ссылки на запрос (.qlref файл), определяющий расположение проверяемого запроса. Расположение определяется относительно корня пакета CodeQL, содержащего запрос. Обычно это пакет CodeQL, указанный dependencies в блоке тестового пакета. Дополнительные сведения см. в разделе Запрос ссылочных файлов.

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

  • Пример кода, для которого требуется выполнить запрос. Он должен состоять из одного или нескольких файлов, содержащих примеры кода, для идентификации в котором предназначен запрос.

Вы также можете определить результаты, которые должны отображаться при выполнении запроса к примеру кода, создав файл с расширением .expected. Кроме того, можно оставить тестовую команду, чтобы создать .expected файл.

Пример создания и тестирования запроса см. в примере ниже.

Важно: Файлы .ql, .qlrefи .expected должны иметь согласованные имена.

Если вы хотите напрямую указать .ql сам файл в тестовой команде, он должен иметь то же базовое имя, что и соответствующий .expected файл. Например, если запрос имеет значение MyJavaQuery.ql, ожидаемый файл результатов должен иметь значение MyJavaQuery.expected.

Если вы хотите указать .qlref файл в команде, он должен иметь то же базовое имя, что и соответствующий .expected файл, но сам запрос может иметь другое имя.

Имена примеров файлов кода не обязательно должны соответствовать другим тестовым файлам. Все примеры файлов кода, найденные рядом с файлом .qlref (или .ql) и в любых подкаталогах, будут использоваться для создания тестовой базы данных. Поэтому для простоты рекомендуется не сохранять тестовые файлы в каталогах, которые являются предками друг друга.

Работает codeql test run

Тесты запросов CodeQL выполняются с помощью следующей команды:

codeql test run <test|dir>

Аргумент <test|dir> может быть одним или несколькими из следующих:

  • Путь к файлу .ql .
  • Путь к файлу .qlref , который ссылается на .ql файл.
  • Путь к каталогу, в который будет выполняться рекурсивный поиск по .ql файлам и .qlref .

Также можно указать:

  • --threads: при необходимости — количество потоков, используемых при выполнении запросов. По умолчанию используется 1параметр . Можно указать больше потоков для ускорения выполнения запросов. При указании 0 число потоков совпадает с количеством логических процессоров.

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

Пример

В следующем примере показано, как настроить тест для запроса, который ищет в коде if Java операторы с пустыми then блоками. Он включает шаги по добавлению пользовательского запроса и соответствующих тестовых файлов для разделения пакетов CodeQL за пределами вашего репозитория CodeQL. Это гарантирует, что при обновлении библиотек CodeQL или извлечении другой ветви вы не будете перезаписывать пользовательские запросы и тесты.

Подготовка запросов и тестовых файлов

  1. Разработка запроса. Например, следующий простой запрос находит пустые then блоки в коде Java:

    import java
    
    from IfStmt ifstmt
    where ifstmt.getThen() instanceof EmptyStmt
    select ifstmt, "This if statement has an empty then."
    
  2. Сохраните запрос в файле с именем EmptyThen.ql в каталоге вместе с другими пользовательскими запросами. Например, custom-queries/java/queries/EmptyThen.ql.

  3. Если вы еще не добавили пользовательские запросы в пакет CodeQL, создайте пакет CodeQL. Например, если пользовательские запросы Java хранятся в , добавьте qlpack.yml файл со следующим содержимым в :custom-queries/java/queries``custom-queries/java/queries

    name: my-custom-queries
    dependencies:
      codeql/java-queries: "*"
    

    Дополнительные сведения о пакетах CodeQL см. в разделе Сведения о пакетах CodeQL.

  4. Создайте пакет CodeQL для тестов Java, добавив qlpack.yml файл со следующим содержимым custom-queries/java/testsв dependencies , обновив в соответствии с именем пакета пользовательских запросов CodeQL:

    В следующем qlpack.yml файле указано, что my-github-user/my-query-tests зависит my-github-user/my-custom-queries от версии, больше или равной 1.2.3 и меньше 2.0.0. Он также объявляет, что CLI должен использовать Java extractor при создании тестовых баз данных. В строке tests: . объявляется, что все .ql файлы в пакете должны выполняться как тесты при codeql test run выполнении с параметром --strict-test-discovery . Как правило, тестовые пакеты не содержат version свойства . Это не позволит вам случайно опубликовать их.

      name: my-github-user/my-query-tests
      dependencies:
        my-github-user/my-custom-queries: ^1.2.3
      extractor: java
      tests: .
    
  5. В пакете тестирования Java создайте каталог, содержащий тестовые файлы, связанные с EmptyThen.ql. Например, custom-queries/java/tests/EmptyThen.

  6. В новом каталоге создайте EmptyThen.qlref , чтобы определить расположение EmptyThen.ql. Путь к запросу должен быть указан относительно корня пакета CodeQL, содержащего запрос. В этом случае запрос находится в каталоге верхнего уровня пакета CodeQL с именем my-custom-queries, который объявляется как зависимость для my-query-tests. EmptyThen.qlref Поэтому должен просто содержать EmptyThen.ql.

  7. Создайте фрагмент кода для тестирования. Следующий код Java содержит пустой if оператор в третьей строке. Сохраните его в custom-queries/java/tests/EmptyThen/Test.java.

    class Test {
    public void problem(String arg) {
     if (arg.isEmpty())
     ;
     {
         System.out.println("Empty argument");
     }
    }
    
    public void good(String arg) {
     if (arg.isEmpty()) {
         System.out.println("Empty argument");
     }
    }
    }
    

Выполнение теста

Чтобы выполнить тест, перейдите в custom-queries каталог и выполните команду codeql test run java/tests/EmptyThen.

При выполнении теста выполняется следующая команда:

  1. Находит один тест в каталоге EmptyThen .

  2. Извлекает базу данных CodeQL из файлов, .java хранящихся в каталоге EmptyThen .

  3. Компилирует запрос, на который EmptyThen.qlref ссылается файл.

    Если этот шаг завершается ошибкой, это связано с тем, что CLI не может найти пользовательский пакет CodeQL. Повторно выполните команду и укажите расположение пользовательского пакета CodeQL, например:

    codeql test run --search-path=java java/tests/EmptyThen

    Сведения о сохранении пути поиска в рамках конфигурации см. в разделе Указание параметров команд в файле конфигурации CodeQL.

  4. Выполняет тест путем выполнения запроса и создания EmptyThen.actual файла результатов.

  5. Проверяет наличие EmptyThen.expected файла для сравнения с файлом .actual результатов.

  6. Сообщает о результатах теста — в данном случае это сбой: 0 tests passed; 1 tests failed:. Сбой теста, так как мы еще не добавили файл с ожидаемыми результатами запроса.

Просмотр выходных данных теста запроса

CodeQL создает в каталоге следующие файлы EmptyThen :

  • EmptyThen.actual— файл, содержащий фактические результаты, созданные запросом.
  • EmptyThen.testproj— тестовая база данных, которую можно загрузить в VS Code и использовать для отладки неудачных тестов. После успешного завершения тестов эта база данных удаляется на этапе обслуживания. Этот шаг можно переопределить, выполнив команду test run с параметром --keep-databases .

В этом случае сбой был ожидаемым и его легко исправить. Если открыть EmptyThen.actual файл, вы увидите результаты теста:

| Test.java:3:5:3:22 | stmt | This if statement has an empty then. |

Этот файл содержит таблицу со столбцом для расположения результата, а также отдельные столбцы для каждой select части предложения, выводимой запросом. Так как результаты являются ожидаемыми, мы можем обновить расширение файла, чтобы определить его как ожидаемый результат для этого теста (EmptyThen.expected).

Если вы повторно запустите тест сейчас, выходные данные будут похожими, но они будут завершены путем создания отчета: All 1 tests passed..

Если результаты запроса изменяются, например при изменении инструкции select для запроса, тест завершится ошибкой. Для неудачных результатов выходные данные ИНТЕРФЕЙСА командной строки содержат унифицированный дифф файлов EmptyThen.expected и EmptyThen.actual . Этих сведений может быть достаточно для отладки тривиальных сбоев тестов.

Для сбоев, которые труднее отлаживать, можно импортировать EmptyThen.testproj в CodeQL для VS Code, выполнить EmptyThen.qlи просмотреть результаты в Test.java примере кода. Дополнительные сведения см. в разделе Анализ проектов в справке CodeQL для VS Code.

Дополнительные материалы