Среда разработки¶
Приложение Glarus BI состоит из двух основных компонентов:
Бэкенд, написанный на Clojure, который содержит REST API, а также весь соответствующий код для общения с базами данных и обработки запросов.
Внешний веб-интерфейс, написанный как одностраничное приложение Javascript.
Оба компонента создаются и собираются вместе в один файл JAR. В каталоге, где вы запускаете JAR, вы можете создать файл JAR (если Glarus BI ещё не создала его) и добавить туда драйверы (драйверы также являются JAR).
Быстрый старт¶
Чтобы запустить среду разработки, запустите:
yarn dev
Эта команда запустит фронтенд и бэкенд. Но вы можете запускать их в раздельных окнах или вкладках терминала.
Фронтенд¶
Glarus BI зависит от запуска сторонних библиотек, поэтому вам необходимо поддерживать их в актуальном состоянии. Clojure CLI автоматически извлечёт зависимости, когда это необходимо. Однако с зависимостями JavaScript вам нужно будет запустить процесс установки вручную.
# javascript dependencies
$ yarn
Запустите процесс сборки фронтенда с помощью
yarn build-hot
См. Разработка фронтенда.
Бэкенд¶
Запустите свой локальный сервер с помощью
clojure -M:run
См. бэкенд-разработка.
Фронтенд-разработка¶
Мы используем эти технологии для нашего процесса сборки FE, чтобы позволить нам использовать модули, синтаксис es6 и переменные css.
webpack;
babel;
cssnext.
Задачи внешнего интерфейса выполняются с использованием yarn
. Все доступные задачи можно найти в package.json
в разделе scripts.
Чтобы запустить без горячей загрузки изменений, вы можете использовать:
$ yarn build
Если вы работаете непосредственно с фронтендом, вы, скорее всего, захотите перезагрузить изменения при их внесении, а в случае с компонентами React сделать это, сохранив состояние. Чтобы запустить сборку с горячей перезагрузкой, используйте:
$ yarn build-hot
Обратите внимание, что в настоящее время, если вы изменяете переменные CSS, эти изменения вступят в силу только при перезапуске сборки.
Существует также возможность перезагрузить изменения при сохранении без горячей перезагрузки с помощью
$ yarn build-watch
В некоторых системах могут возникнуть проблемы с обнаружением изменений в файлах фронтенда. Вы можете включить опрос файловой системы, раскомментировав предложение watchOptions
в файле webpack.config.js
. Если вы сделаете это, возможно, стоит заставить git игнорировать изменения в конфигурации веб-пакета, используя git update-index --assume-unchanged webpack.config.js
Мы исключаем загрузчик ESLint в режиме разработки по умолчанию, чтобы в семь раз ускорить первоначальные сборки. Вы можете включить его, экспортировав переменную среды:
$ USE_ESLINT=true yarn build-hot
По умолчанию эти процессы сборки полагаются на кэш памяти. Процесс сборки с включенным загрузчиком ESLint использует большой объем памяти и может занять значительное время для запуска (1-2 минуты и более). Разработчикам FE (или всем, кто часто перезапускает сборки FE) рекомендуется использовать параметр кэша файловой системы webpack для улучшения производительности при запуске:
$ FS_CACHE=true yarn build-hot
При использовании FS_CACHE=true
вам может потребоваться удалить каталог node_modules/.cache
, чтобы исправить сценарии, в которых сборка может быть неправильно кэширована, и вы должны запустить rm -rf node_modules/.cache
, чтобы сборка смогла корректно работать при чередовании между открытым исходным кодом и сборкой кодовой базы корпоративной ветки.
Тестирование интерфейса¶
Запустите все юнит-тесты и end2end-тесты Cypress с помощью
yarn test
Тесты Cypress и некоторые модульные тесты находятся в каталоге frontend/test
. Новые файлы модульных тестов добавляются рядом с тестируемыми файлами.
Если вы используете FS_CACHE=true
, вы также можете использовать FS_CACHE=true
с yarn test
.
Отладка интерфейса¶
По умолчанию мы используем простой вариант сопоставления источников, оптимизированный для скорости.
Если у вас возникнут проблемы с точками останова, особенно внутри jsx, перед запуском сервера установите для переменной env BETTER_SOURCE_MAPS
значение true.
Пример:
BETTER_SOURCE_MAPS=true yarn dev
Сквозные тесты Cypress¶
Сквозные тесты (или (e2e-тесты) имитируют реалистичные последовательности действий пользователя. Узнайте больше о том, как мы подходим к сквозному тестированию с помощью Cypress.
Сквозные тесты Cypress используют принудительное соглашение об именах файлов <test-suite-name>.cy.spec.js
, чтобы отделить их от модульных тестов.
Модульные тесты Jest¶
Модульные тесты обрабатывают изолированные части бизнес-логики.
Модульные тесты используют принудительное соглашение об именах файлов <test-suite-name>.unit.spec.js
, чтобы отделить их от сквозных тестов.
yarn test-unit # Run all tests at once
yarn test-unit-watch # Watch for file changes
Бэкенд-разработка¶
Clojure REPL — это основной инструмент разработки для серверной части. Ниже приведены некоторые указания о том, как настроить REPL для упрощения разработки.
И, конечно же, ваш сервер разработки Jetty доступен через
clojure -M:run
Вы также можете запустить REPL иначе, например, в вашем редакторе кода, затем выполнить команду:
(do (dev) (start!))
Она запустит сервер как localhost:3000
. Это действие также затронет базу данных приложения: она будет обновлена или создана. Чтобы полноценно использовать приложение, запустите также фронтенд (например, командой yarn build-hot
).
База данных приложения¶
По умолчанию Glarus BI использует H2 как базу данных приложения, но мы рекомендуем Postgres. Это можно настроить в переменных окружения или в deps.edn
. Пример с deps.edn:
;; ~/.clojure/deps.edn
{:aliases
{:user
{:jvm-opts
["-Dmb.db.host=localhost"
"-Dmb.db.type=postgres"
"-Dmb.db.user=<username>"
"-Dmb.db.dbname=<dbname>"
"-Dmb.db.pass="]}}}
Вы также можете передать полную строку подключения как mb.db.connection.uri
:
"-Dmb.db.connection.uri=postgres://<user>:<password>@localhost:5432/<dbname>"
Сборка драйверов¶
Большинство драйверов, которые Glarus BI использует для подключения к внешним базам данных хранилища, представляют собой отдельные проекты в рамках подкаталога modules/
. При запуске Glarus BI через clojure
вам нужно будет собрать эти драйверы, чтобы иметь доступ к ним. Вы можете собрать драйверы следующим образом:
# Build the 'mongo' driver
./bin/build-driver.sh mongo
(или)
# Build all drivers
./bin/build-drivers.sh
Включение путей драйверов для разработки или других задач¶
Для разработки при выполнении различных задач Clojure вы можете добавить псевдонимы drivers
и drivers-dev
, чтобы объединить
зависимости драйверов и исходные пути в проект Glarus BI:
# Install dependencies, including for drivers
clojure -P -X:dev:ci:drivers:drivers-dev
Запуск модульных тестов¶
Запустите модульные тесты с помощью
# OSS tests only
clojure -X:dev:test
# OSS + EE tests
clojure -X:dev:ee:ee-dev:test
или конкретный тест (или пространство имён тестов) с помощью
# run tests in only one namespace (pass in a symbol)
clojure -X:dev:test :only metabase.api.session-test
# run one specific test (pass in a qualified symbol)
clojure -X:dev:test :only metabase.api.session-test/my-test
# run tests in one specific folder (test/metabase/util in this example)
# pass arg in double-quotes so Clojure CLI interprets it as a string;
# our test runner treats strings as directories
clojure -X:dev:test :only '"test/metabase/util"'
Как в любом другом проекте clojure.test, вы можете запускать модульные тесты из REPL. Некоторые практические примеры запуска тестов:
;; run a single test with clojure.test
some-ns=> (clojure.test/run-test metabase.util-test/add-period-test)
Testing metabase.util-test
Ran 1 tests containing 4 assertions.
0 failures, 0 errors.
{:test 1, :pass 4, :fail 0, :error 0, :type :summary}
;; run all tests in the namespace
some-ns=> (clojure.test/run-tests 'metabase.util-test)
Testing metabase.util-test
{:result true, :num-tests 100, :seed 1696600311261, :time-elapsed-ms 45, :test-var "pick-first-test"}
Ran 33 tests containing 195 assertions.
0 failures, 0 errors.
{:test 33, :pass 195, :fail 0, :error 0, :type :summary}
;; run tests for a set of namespaces related to a feature you are working on (eg pulses)
some-ns=> (let [namespaces '[metabase.pulse.markdown-test metabase.pulse.parameters-test]]
(apply require namespaces) ;; make sure the test namespaces are loaded
(apply clojure.test/run-tests namespaces))
Testing metabase.pulse.markdown-test
Testing metabase.pulse.parameters-test
Ran 5 tests containing 147 assertions.
0 failures, 0 errors.
{:test 5, :pass 147, :fail 0, :error 0, :type :summary}
;; but we also have a lovely test runner with lots of cool options
some-ns=> (metabase.test-runner/find-and-run-tests-repl {:namespace-pattern ".*pulse.*"})
Running tests with options {:mode :repl, :namespace-pattern ".*pulse.*", :exclude-directories ["classes" "dev" "enterprise/backend/src" "local" "resources" "resources-ee" "src" "target" "test_config" "test_resources"], :test-warn-time 3000}
Excluding directory "dev/src"
Excluding directory "local/src"
Looking for test namespaces in directory test
Finding tests took 1.6 s.
Excluding directory "test_resources"
Excluding directory "enterprise/backend/src"
Looking for test namespaces in directory enterprise/backend/test
Excluding directory "src"
Excluding directory "resources"
Running 159 tests
...
;; you can even specify a directory if you're working on a subfeature like that
some-ns=> (metabase.test-runner/find-and-run-tests-repl {:only "test/metabase/pulse/"})
Running tests with options {:mode :repl, :namespace-pattern #"^metabase.*", :exclude-directories ["classes" "dev" "enterprise/backend/src" "local" "resources" "resources-ee" "src" "target" "test_config" "test_resources"], :test-warn-time 3000, :only "test/metabase/pulse/"}
Running tests in "test/metabase/pulse/"
Looking for test namespaces in directory test/metabase/pulse
Finding tests took 37.0 ms.
Running 65 tests
...
Тестирование драйверов¶
По умолчанию тесты запускаются только для драйвера h2
. Вы можете указать, с какими драйверами запускать тесты, с помощью переменной окружения DRIVERS
:
DRIVERS=h2,postgres,mysql,mongo clojure -X:dev:drivers:drivers-dev:test
Некоторым драйверам при тестировании требуются дополнительные переменные среды, поскольку их невозможно запустить локально (например, Redshift и Bigquery). Тесты завершатся ошибкой при запуске и дадут вам знать, какие параметры указать, если это необходимо.
Если тесты запущены из REPL, вы можете запросить:
(mt/set-test-drivers! #{:postgres :mysql :h2})
Большая часть драйверов должна иметь возможность загружать некоторые данные (статические наборы данных), и все драйверы должны подключаться к экземпляру этой базы данных. Вы можете узнать, что требуется в каждом конкретном пространстве имён теста драйвера, которое следует шаблону metabase.test.data.<driver>
.
Должна быть реализация мультиметода tx/dbdef->connection-details
, которая предоставляет способ подключения к базе данных. Вы можете увидеть, что требуется.
Ниже приведён пример для postgres в metabase.test.data.postgres
:
(defmethod tx/dbdef->connection-details :postgres
[_ context {:keys [database-name]}]
(merge
{:host (tx/db-test-env-var-or-throw :postgresql :host "localhost")
:port (tx/db-test-env-var-or-throw :postgresql :port 5432)
:timezone :America/Los_Angeles}
(when-let [user (tx/db-test-env-var :postgresql :user)]
{:user user})
(when-let [password (tx/db-test-env-var :postgresql :password)]
{:password password})
(when (= context :db)
{:db database-name})))
Как видно, выполняется поиск в окружении:
хоста («localhost» по умолчанию);
порта (defaults to 5432);
пользователя;
пароля.
Имена функций показывают, бросают они исключения или нет:
(tx/db-test-env-var :postgresql :password)
будет искать в словаре env/env значение по ключу :mb-postgres-test-password
, которое будет установлено переменной окружения MB_POSTGRESQL_TEST_PASSWORD
.
some-ns=> (take 10 (keys environ.core/env))
(:mb-redshift-test-password
:java-class-path
:path
:mb-athena-test-s3-staging-dir
:iterm-profile
:mb-snowflake-test-warehouse
:mb-bigquery-cloud-sdk-test-service-account-json
:tmpdir
:mb-oracle-test-service-name
:sun-management-compiler)
Запуск линтеров¶
clj-kondo
должен быть установлен отдельно.
# Run Eastwood
clojure -X:dev:ee:ee-dev:drivers:drivers-dev:eastwood
# Run the namespace checker
clojure -X:dev:ee:ee-dev:drivers:drivers-dev:test:namespace-checker
# Run clj-kondo
./bin/kondo.sh
# Lint the migrations file (if you've written a database migration):
./bin/lint-migrations-file.sh
Непрерывная интеграция¶
Все внешние и внутренние линтеры и тесты могут быть выполнены с
$ yarn ci
Также возможно выполнять проверки фронтенда и бэкенда отдельно.
$ yarn ci-frontend
$ yarn ci-backend