Что такое артефакт (artifact) в контексте языка Java?

Что такое артефакт (artifact) в контексте языка Java? Так же интересно чем Артефакты(Artifacts) отличаются от библиотек(Libraries) в настройках проекта.
Отслеживать
81.1k 7 7 золотых знаков 72 72 серебряных знака 153 153 бронзовых знака
задан 28 ноя 2018 в 11:43
Andrey Zinovich Andrey Zinovich
309 2 2 серебряных знака 11 11 бронзовых знаков
2 ответа 2
Сортировка: Сброс на вариант по умолчанию
Артефакты не относятся к языку Java, а являются результатом вашей работы.
Артефакт — это сборка активов вашего проекта, которые вы собрали для тестирования, развертывания или распространения вашего программного решения или его части. Примерами являются набор скомпилированных классов Java или приложения Java, упакованных в архив Java, веб-приложение в виде структуры каталогов или архива веб-приложений и т. д.
Библиотеки же являются зависимостями, которые используются вашей программой в работе, и сделаны кем то другим.
Вы можете сколько угодно работать над проектом не генерируя ни одного артефакта. Но вряд ли у вас что то получиться, если вы не подключили нужные вам библиотеки, или подключили неподходящую версию.
Что такое артефакт java
На этом шаге рассмотрим понятие артефакта.
Артефакты живут в материальном мире битов и потому являются важнейшими строительными блоками при моделировании физических аспектов системы. Артефакт – это физическая и заменяемая часть системы.
Артефакты используются для моделирования таких физических сущностей, которые могут располагаться на узле, – например, исполняемых программ, библиотек, таблиц, файлов и документов. Обычно артефакт представляет собой физическую группировку таких логических элементов, как классы, интерфейсы и кооперации.
Вы осуществляете логическое моделирование для визуализации, специфицирования и документирования решений относительно словаря предметной области, а также структурных и поведенческих способов кооперации сущностей. Физическое же моделирование требуется для построения исполняемой системы. Если логические сущности «живут» в концептуальном мире, то физические пребывают в мире битов, то есть в конечном счете располагаются на физических узлах и могут быть исполнены непосредственно либо каким-то косвенным образом участвовать в работе исполняемой системы.
В UML все физические сущности моделируются как артефакты. Артефакт – это физическая сущность на уровне платформы реализации.
Многие операционные системы и языки программирования непосредственно поддерживают концепцию артефакта. Объектные библиотеки, исполняемые программы, компоненты .NET и Enterprise Java Beans, – все это примеры артефактов, которые могут быть представлены на UML. Но артефакты могут быть использованы и для представления других сущностей, которые принимают участие в работе исполняемых программ, – таких, как таблицы, файлы и документы.
В UML артефакты изображаются так, как показано на рис. 1.
Эта каноническая нотация позволяет визуализировать артефакт независимо от операционной системы и языка программирования. Используя стереотипы – один из механизмов расширения UML, можно приспособить эту нотацию для представления специфических разновидностей артефактов.
Артефакт – это физическая часть системы, которая существует на уровне платформы реализации. Изображается в форме прямоугольника с ключевым словом «artifact» внутри.
На следующем шаге рассмотрим имена артефактов в UML.
Основные определения и понятия
В контексте данного руководства под артефактом понимается файл (обычно JAR или ZIP), содержащий исполняемый или другой код, получившийся в результате сборки проекта. Артефакт имеет соответствующее некоторым правилам имя и версию, и может хранится в репозитории артефактов.
Б
БД
Реляционная база данных
Браузер сущностей
Экранная форма, на которой размещается таблица со списком сущностей, а также кнопки создания, редактирования, удаления сущности.
В
Внедрение зависимости
Известно также как принцип Inversion Of Control (IoC). Механизм для получения ссылок на используемые объекты, при котором объект только декларирует, от каких объектов он зависит, а контейнер создает нужные объекты и инжектирует в зависимый объект.
Г
Главный пакет сообщений
З
Загрузка по требованию
И
Источник данных
К
Контейнер
Контейнер управляет жизненным циклом и конфигурацией программных объектов. Является базовым компонентом технологии Dependency Injection (или Inversion of Control).
В платформе CUBA используется контейнер Spring Framework . Для получения более подробной информации см. «Дополнительные материалы»
Контроллер экрана
Java класс, содержащий логику инициализации и обработки событий экрана. Связан с XML-дескриптором экрана.
Л
Локальный атрибут
Атрибут сущности, не являющийся ссылкой или коллекцией ссылок на другую сущность. Значения всех локальных атрибутов сущности, как правило, хранятся в одной таблице (исключение составляют некоторые стратегии наследования сущностей).
П
Пакет локализованных сообщений
Персистентный контекст
Набор экземпляров сущностей, загруженных из базы данных или только что созданных. Персистентный контекст является кэшем данных в рамках текущей транзакции. При коммите транзакции все изменения сущностей в персистентном контексте сохраняются в БД.
Представление
Р
Рабочий каталог
Локальный каталог файловой системы, в котором содержится проект приложения. Содержит скрипты сборки build.gradle , settings.gradle и проектные файлы IDE .
Репозиторий артефактов
Сервер, осуществляющий хранение артефактов в определенной структуре. В процессе сборки некоторого проекта из репозитория загружаются артефакты, от которых зависит данный проект.
С
Сущность
Основной элемент модели данных, см. Раздел 4.2.1, «Модель данных»
Э
Жадная загрузка
Загрузка данных подклассов и связанных объектов одновременно с основной запрашиваемой сущностью.
A
Application Tiers
Application Properties
Свойства приложения − именованные данные различных типов, определяющие всевозможные аспекты конфигурации и функционирования приложения.
Application Units
D
Datasource
E
Eager Fetching
EntityManager
Программный компонент среднего слоя, служащий для работы с персистентными сущностями.
I
Interceptor
Элемент AOP (Aspect Oriented Programming), позволяющий изменить или расширить обычный вызов метода объекта.
J
Java EE Web Profile
Упрощенный профиль Java Enterprise Edition, разработанный для веб-приложений, для которых не требуются такие технологии как EJB, JTA и т.д.
JMX
Java Management Extensions − технология, которая предоставляет инструменты для управления приложениями, объектами системы, устройствами. Определяет стандарт для написания JMX-компонентов − MBeans.
JPA
Java Persistence API — стандартная спецификация технологии объектно-реляционного отображения (ORM). В платформе CUBA используется фреймворк Apache OpenJPA , реализующий эту спецификацию.
JPQL
Платформо-независимый объектно-ориентированный язык запросов, определенный как часть спецификации JPA.
L
Lazy loading
M
Managed Beans
Программные компоненты Middleware , содержащие бизнес-логику приложения.
MBeans
Managed Beans, имеющие JMX-интерфейс. Как правило, имеют внутреннее состояние (например, кэш, конфигурационные данные или статистику), к которому нужно обеспечить доступ через JMX.
Middleware
Средний слой − уровень приложения, содержащий бизнес-логику, работающий с базой данных, и предоставляющий общий интерфейс для верхних (клиентских) уровней приложения.
O
Optimistic locking
Оптимистичная блокировка — способ управления совместным доступом к данным различными пользователями, при котором предполагается, что возможность одновременного изменения ими одного и того же экземпляра сущности мала. В этом случае блокировка как таковая отсутствует, вместо нее в момент сохранения изменений производится проверка, нет ли в БД более новой версии данных, сохраненной другим пользователем. Если есть, выбрасывается исключение, и текущий пользователь должен снова загрузить данный экземпляр сущности.
ORM
Object-Relational Mapping — объектно-реляционное отображение — технология связывания таблиц реляционной базы данных с объектами языка программирования.
P
POJO
Plain Old Java Object − «простой Java-объект в старом стиле» − Java-объект, не унаследованный ни от какого специфического класса и не реализующий никаких служебных интерфейсов сверх тех, которые нужны для описания бизнес-логики.
S
Services
Сервисы среднего слоя предоставляют интерфейс для вызова бизнес-логики клиентами и образуют границу Middleware . Сервисы могут содержать бизнес-логику внутри себя, либо делегировать выполнение Managed Beans.
Single Sign-On, SSO
Технология, при использовании которой пользователь переходит от одного приложения к другому без повторной аутентификации. Интеграция CUBA-приложения с Active Directory позволяет пользователям Windows входить в приложение без ввода имени и пароля.
Soft deletion
U
UI
User Interface — пользовательский интерфейс
V
View
X
XML-дескриптор
Файл в формате XML, содержащий описание источников данных и расположения визуальных компонентов экрана.
- Предисловие
- Целевая аудитория
- Дополнительные материалы
- Обратная связь
- Обзор платформы
- Технические требования
- Release Notes
- Установка CUBA Studio
- Интеграция CUBA Studio с IDE
- Описание задачи
- Создание проекта
- Создание сущностей
- Создание таблиц базы данных
- Создание экранов пользовательского интерфейса
- Экраны управления Покупателями
- Экраны управления Заказами
- Меню приложения
- Экран редактирования Покупателя со списком Заказов
- Архитектура
- Уровни и блоки приложения
- Модули приложения
- Базовые проекты
- Состав приложения
- Модель данных
- Базовые классы сущностей
- Аннотации сущностей
- Аннотации класса
- Аннотации атрибутов
- Использование
- Политика обработки связей
- Ограничение уникальности на уровне БД
- Интерфейсы метаданных
- Формирование метаданных
- Datatype
- Пример форматирования даты в UI
- Примеры форматирования дат и чисел в коде приложения
- Пример специализированного Datatype
- Создание представлений
- Создание бина
- Использование бина
- Создание JMX-бина
- JMX-бины платформы
- CachingFacadeMBean
- ConfigStorageMBean
- EmailerMBean
- PersistenceManagerMBean
- ScriptingManagerMBean
- ServerInfoMBean
- Configuration
- Messages
- MessageTools
- MetadataTools
- Запросы с distinct
- Последовательная выборка
- Доступ к свойствам
- Хранение свойств в файлах
- Хранение свойств в базе данных
- Конфигурационные интерфейсы
- Использование
- Типы свойств
- Значения по умолчанию
- Пакеты сообщений
- Главный пакет сообщений
- Локализация названий сущностей и атрибутов
- Локализация enum
- UserSession
- Вход в систему
- SecurityContext
- Классы исключений
- Передача исключений Middleware
- Обработчики исключений клиентского уровня
- Типы СУБД
- Поддержка произвольных СУБД
- Версия СУБД
- Структура SQL-скриптов
- Структура Groovy-скриптов
- Сервисы
- Создание сервиса
- Использование сервиса
- DataService
- PersistenceTools
- PersistenceHelper
- DbTypeConverter
- EntityManager
- Состояния сущности
- Загрузка по требованию
- Выполнение JPQL запросов
- Поиск подстроки без учета регистра
- Макросы в JPQL
- Программное управление транзакциями
- Декларативное управление транзакциями
- Примеры взаимодействия транзакций
- Откат вложенной транзакции
- Чтение и изменение данных во вложенной транзакции
- Особенности реализации для различных СУБД
- Экраны
- Типы экранов
- Фрейм
- Простой экран
- Экран выбора
- Экран редактирования
- AbstractFrame
- AbstractWindow
- AbstractLookup
- AbstractEditor
- Инжекция зависимостей контроллеров
- Компаньоны контроллеров
- Компоненты
- Button
- Bulk Editor
- CheckBox
- DateField
- Embedded
- FieldGroup
- FileMultiUploadField
- FileUploadField
- Filter
- Использование фильтра
- Описание компонента Filter
- Права пользователей
- Внешние параметры для управления фильтрами
- Последовательное наложение фильтров
- BoxLayout
- ButtonsPanel
- GridLayout
- GroupBoxLayout
- IFrame
- ScrollBoxLayout
- SplitPanel
- TabSheet
- Formatter
- Presentation
- Timer
- Validator
- Создание источников данных
- Декларативное создание
- Программное создание
- Собственные классы реализации
- Возвращаемые значения
- Параметры запроса
- Фильтр запроса
- Поиск подстроки без учета регистра
- Декларативное создание действий
- Стандартные действия
- Стандартные действия с коллекцией
- CreateAction
- EditAction
- RemoveAction
- RefreshAction
- AddAction
- ExcludeAction
- ExcelAction
- LookupAction
- ClearAction
- OpenAction
- Диалоговые окна
- Уведомления
- Использование фоновых задач
- Настройка окружения
- Тема в веб-приложениях
- Использование существующих тем
- Расширение существующей темы
- Создание новой темы
- Работа с компонентами Vaadin
- Компоновка главного окна приложения
- Работа с компонентами Swing
- Использование сторонних компонентов Vaadin
- Интеграция компонентов в Generic UI
- Базовая функциональность
- REST API
- Включение в проект
- Описание функций
- Логин
- Логаут
- Загрузка экземпляра персистентного объекта из базы данных по идентификатору
- Выполнение JPQL запроса для выборки данных
- Коммит новых и измененных экземпляров, удаление
- Загрузка файла из хранилища
- Получение описания модели данных в формате HTML
- Cоздание новых представлений на сервере
- Вызов сервисов
- Вызов сервиса с помощью GET запроса
- Вызов сервиса с помощью POST запроса
- Поддерживаемые типы параметров метода сервиса
- Результат вызова сервиса
- Выполнение задач по расписанию
- Spring TaskScheduler
- Назначенные задания CUBA
- Регистрация задания
- Управление обработкой заданий
- Особенности реализации
- Методы отправки
- Вложения
- Настройка параметров отправки email
- Управление динамическими атрибутами
- Категоризируемые сущности
- Динамические атрибуты в REST API
- Блокировка редактирования сущностей
- Блокировка произвольных процессов
- Мониторинг блокировок
- Настройка журналирования
- Отображение журнала
- Сохранение снимков
- Отображение снимков
- Загрузка файлов
- Выгрузка данных
- Стандартная реализация хранилища
- Папки приложения
- Папки поиска
- Наборы
- Расширение сущности
- Расширение экранов
- Расширение бизнес-логики
- Рекомендуемый стиль кода
- Файловая структура проекта
- Описание скриптов сборки
- Структура build.gradle
- Запуск задач сборки
- Сборка на сервере Continuous Integration
- Создание схемы БД
- Подключение к HSQLDB внешними инструментами
- Подключение с помощью Squirrel SQL
- Подключение с помощью IntelliJ IDEA Ultimate
- Настройка логгирования в Tomcat
- Настройка логгирования в десктоп клиенте
- Подключение отладчика
- Отладка виджетов в веб-браузере
- Тестирование
- Модульные тесты
- Интеграционные тесты Middleware
- Интеграционные тесты клиентского уровня
- Получение локализованных сообщений
- Присвоение начальных значений
- Инициализация полей сущности
- Инициализация с помощью CreateAction
- Использование метода initNewItem
- Реализация композиции
- Глубокая композиция
- Пример использования стороннего компонента Vaadin
- Пример интеграции компонента Vaadin в Generic UI
- Каталоги приложения
- Конфигурационный каталог
- Рабочий каталог
- Каталог журналов
- Временный каталог
- Каталог скриптов базы данных
- Быстрое развертывание в Tomcat
- Использование Tomcat при эксплуатации приложения
- Настройка кластера Web Client
- Установка и настройка Load Balancer
- Настройка серверов Web Client
- Настройка обращения к кластеру Middleware
- Настройка взаимодействия серверов Middleware
- Встроенная JMX консоль
- Настройка удаленного доступа к JMX
- Tomcat JMX под Windows
- Tomcat JMX под Linux
- Использование механизма выполнения скриптов БД сервером
- Инициализация и обновление БД из командной строки
- Компоненты подсистемы безопасности
- Окно входа в систему
- Пользователи
- Замещение пользователей
- Ограничения
- Атрибуты сессии
- Базовая интеграция с Active Directory
- Настройка аутентификации с использованием Jespa
- Подключение библиотеки
- Настройка конфигурации
- Настройка ролей
- Создание локальных администраторов
- context.xml
- datatypes.xml
- dispatcher-spring.xml
- menu.xml
- metadata.xml
- permissions.xml
- persistence.xml
- remoting-spring.xml
- screens.xml
- spring.xml
- views.xml
- web.xml
Маленький Билд и его друзья
Помните фильм “Пятый элемент”? Там была сцена, когда Зорг опрокидывает стакан на пол и роботы тут же начинают уборку помещения. Всего лишь одно маленькое действие привело в жизнь десяток машин, которые сразу же начали подметать и мыть полы, а в конце еще и налили воды хозяину.
Что-то похожее происходит в коллективе с налаженным build процессом, когда разработчик коммитит изменения в систему контроля версий.
О пользе налаженного процесса билда известно много. Но “путь на production” не прост. После того как код написан и перед тем как он будет запущен на production’е было бы неплохо сделать следующие вещи:
- откомпилировать код если вы используете компилируемый язык (удивил, да?);
- прогнать модульные и интеграционные тесты если они у вас есть;
- выполнить статический анализ кода и/или другие проверки которые позволяет выполнить ваша платформа и которые имеют смысл для вашей команды (code style check, code coverage, цикломатическая сложность, dependency matrix и т.д.);
- собрать артефакт приложения (желательно в виде одного файла), содержащий в себе весь код и ресурсы необходимые для запуска приложения на целевой платформе;
- выполнить приемочное тестирование, если оно у вас есть;
- опубликовать артефакт в репозитории (предположительно локальном), чтобы другие члены комманды могли им воспользоватся в своих целях (особенно актуально, если вы разрабатываете билиотеку, а не приложение);
- в случае если вы разрабатываете приложение а не библиотеку, произвести deploy в окружение staging тестирования чтобы команда и менеджеры могли оценить текущее состояние проекта.
Этот список действий не догма и варьируется от потребностей проекта. Я же расскажу что и как делаем мы. Сразу отмечу что у нас в проекте используется две платформы: PHP и Java. Я преимущественно буду описывать как мы собираем Java проекты, так как за счет поддержки инструментария билд процесс там получается более целостный и вразумительный. Я думаю, этот опыт будет полезен читателям.
Итак код закоммичен в систему контроля версий. С этого момента начинается его маленькое путешествие на production. Но для начала давайте познакомимся с главными героями. Для того чтобы успешно проводить автоматизированною сборку проекта необходим определенный инструментарий.
В главных ролях Link to heading
Система контроля версий (VCS) Link to heading
Какую VCS систему использовать решать вам. Это может быть старый проверенный временем subversion, или модно-распределенный git/mercurial. Но она должна быть. Если на вашем календаре уже 2011 год и вы все еще не пользуетесь какой-либо системой контроля версий, то я настоятельно советую вам переоценить принципы согласно котрым вы принимаете решения.
В контексте обсуждения процесса сборки выбор системы контроля версий настолько неважен, что я даже не буду говорить какую используем мы 🙂
Система сборки проектов (build tool) Link to heading
Основная задача системы сборки состоит в автоматизации задач связанных с созданием релиза из исходных кодов. Среди программистов работающих с интепретируемыми языками распространено мнение что исходный код и есть релиз. Связано это судя по всему с тем, что в таких языках нет выделенной фазы компиляции. Я считаю, что даже в этом случае разделение между исходниками и релизами нужно, потому что вне зависимости от того на каком языке программирования написано приложение, релиз должен обладать следующими свойствами, которыми не обладают исходные коды:
- любой релиз в отличии от исходных кодов должен работать. Подтверждатся это должно каким-либо видом тестирования (хотя бы ручным). Исходные коды же могут находится некоторое время в нерабочем состоянии (например, во время рефакторинга);
- релиз может содержать third party библиотеки и программное обеспечение, которое разрабатывается и поддерживается третьими лицами. Хранить все это в системе контроля версий может быть не самым удобным решением;
- платформа на которой работает приложение может иметь ограничения на формат релиза. Например, может быть строго определен формат архива с приложением (например, rpm или deb). Хранить исходные коды в VCS в том же формате может быть очень неудобно c точки зрения разработки.
Выражаясь математически: релиз = ƒ(исходники).
Для сборки мы используем Apache Maven, – это довольно зрелая и продвинутая система сборки, которая впрочем не так проста в изучении как ее более “легковесные” братья вроде ant и gradle (хотя ant — это скорее бабушка, а gradle внучатый племянник). Gradle в последнее время получил довольно много положительных отзывов и продолжает набирать популярность, поэтому вам определенно стоит посмотреть на него, если вы определяетесь с вопросом выбора системы сборки Java-проекта.
Для того чтобы использовать maven более эффективно, у нас есть определенная экосистема для его поддержки.
Во-первых, это репозиторий артефактов о котором я расскажу ниже.
Во-вторых, у нас есть общий POM-дескриптор для всех проектов компании, который определяет настройки компилятора, сразу делает доступными библиотеки повсеместно используемые в нашей компании (TestNG, hamcrest, logback и т.д.), а также настраивает плагины для статического анализа кода и логгирования и т.д.
В третьих, у нас есть несколько прототипов проектов (archetype в терминологии maven), которые позволяют одной командой из консоли создать новый проект. Эдакий hello world с уже настроенным логированием, Jetty для тестирования, ActiveMQ и Spring Integration для обработки сообщений, Spring в качестве web-framework’а и много еще чем. Все это очень сильно упрощает старт, особенно людям не знакомым с премудростями настройки всего этого “зоопарка”.
Репозиторий артефактов Link to heading
Еще один вопрос связанный с системой билда — куда ложить его результат? После того как мы собрали приложение и протестировали его, нам надо опубликовать релиз. Необходимо общее централизованное место где бы хранились все артефакты, чтобы любой разработчик знал где искать последний релиз продукта. Позже вы можете достать его и использовать для deploy’я на production или в окружение staging тестирования. Если вы разрабатываете библиотеку то релиз нужен другим членам команды, для того чтобы использовать ее в своем приложении.
В простейшем случае роль репозитория может играть web-сервер. Его настройка для этих задач не займет у вас много времени. Либо это может быть FTP-сервер или сетевой диск доступный всем разработчикам. Так же эту роль может играть continious integration сервер, речь о котором пойдет ниже.
В более сложных случаях удачным решением может быть специализирванное ПО. Особенно это актуально если вы используете Maven, который специфицирует формат репозиториев и протокол работы с ними (поверх HTTP).
Мы используем Artifactory в качестве репозитория, который выполняет несколько ролей в нашей экосистеме:
- хранит артефакты делая их (и их исходники) доступными для использования любым программистом в любое время;
- кеширует third party библиотеки используемые программистами. Если вы начинаете новый проект и хотите использовать какую-то библиотеку, с высокой долей вероятности она уже есть в локальном репозитории и вы получите ее моментально не дожидаясь загрузки из интернета.
Continuous Integration сервер Link to heading
Не смотря на грозное название, CI-сервера по своей сути — это триггеры билд процесса которые предоставляют разработчикам удобный способ контроллировать процесс и результат сборок. Они делают несколько вещей:
- позволяют конфигурировать политику запуска сборки (при коммите в VCS, через заданные интевалы времени, после успешной сборки зависимого проекта, вручную, и т.д.);
- предоставляют возможность следить за процессом сборки публикуя ее логи через web-интерфейс;
- предоставляют отчеты по результатам билда (проваленные тесты, предупреждения статического анализатора и т.д.);
- строят тренды на основании истории сборок (количество тестов, время затраченное на исправление билда, процент успешных сборок и т.д.);
- могут успешно играть роль репозитория артефактов.
Строго говоря использование CI-сервера не обязательно. Более того, на начальных этапах я бы рекомендовал делать сборки на машинах разработчиков. Это позволит сэкономить вам время в процессе допиливания build-процесса, которое на начальных стадиях неизбежно.
Мы до сих пор не используем CI-сервер для сборки билиотек. Библиотеки собираются и релизятся самим программистами. Несмотря на то что этот подход имеет ряд недостатков, он существенно проще.
В качестве CI-сервера мы используем TeamCity, бесплатной версией которой мы полностью довольны. Одна из привлекательных фич этого продукта состоит в том что он предоставляет неплохую статистику по билдам, включая success rate сборок, количество тестов и т.д.

Поезд отправляется Link to heading
Итак как это все происходит на практике.
За системой контроля версий следит continuous integration сервер. Как только он замечает какие либо изменения, он делает checkout свежей версии и инициирует процесс сборки проекта.
TeamCity позволяет очень детально настроить с какими параметрами будет запущен build. Вы можете предопределить значения системных переменных нужных вашему процессу билда. Эти переменные могут использоваться например для того чтобы специфицировать на какой БД будет выполнятся тестирование.

Затем в работу вступает Maven. Он компилирует исходники, запускает модульные тесты. Если они провалились, то генерирует отчеты по проваленным тестам, которые будут затем показаны на персональной странице билда, а сам билд завершается и считается проваленным:

Если тесты проходят, то “состав движется дальше”. Следующим шагом является сборка артефактов. В терминах continious integration артефакт это любой результат процесса сборки, главная черта которого — воспроизводимость. Для нас это означает что артефакт является процессом работы машины, а не ручных действий человека.
Обратите внимание, что в смежных областях знаний, например в configuration management, термин “артефакт” имеет немного отличные значения.
Воспроизводимость артефакта — очень важное его свойство. Оно позволяет в любой момент времени из любого среза VCS попытатся собрать приложение и посмотреть что из этого получится.
Воспроизводимость артефакта служит хорошей поддержкой для так популярных в наше время итеративных методов разработки, смысл которых состоит в идее “давайте начнем стрелять, а потом будем корректировать огонь”. Когда патроны дешевле чем время, это хороший подход. Налаженный процесс автоматического производства артефактов в этом контексте можно сравнить с автоматическим станком по производству патронов. Чем лучше он у вас отточен, тем дешевле ваши патроны, и тем быстрее вы можете стрелять и получать фидбек критически важный для следующей итерации.
После того как артефакт собран Maven принимается за интеграционное и приемочное тестирование. Здесь необходимо отметить зачем разделение между модульными, интеграционными и приемочными тестами.
Модульные тесты тестируют классы в изоляции от других частей системы, а также в изоляции от внешних систем, таких как базы данных и веб-сервисы. Их задача состоит в том чтобы давать программисту быстрый фидбек относительно того, работает система или нет безотносительно того верно ли она интегрируется с внешними источниками данных. Фактически, любой программист должен иметь возможность сделать checkout исходников проекта, запустить модульные тесты на абсолютно не подготовленной машине (например, без базы данных) и тесты должны выполнится. Единственная причина почему они могут не выполнится, это если в коде приложения допущена ошибка.
Таким образом, у модульных тестов не должно быть зависимостей, отличных от тех которые тест может удовлетворить сам. По личному опыту могу сказать: тех кто не соблюдаете это правило ждет не очень приятное будущее.
В сухом остатке. Модульные тесты должны:
- выполнятся быстро. Потолок 15-20 секунд, затем их просто перестают использовать. Здесь нужно обратить внимание на то, что модульные тесты должны выполнятся именно на стороне программиста и как можно чаще. И конечно же обязательно перед коммитом в систему контроля версий. На CI-сервере они выполнятся лишь для полноты тестирования;
- быть изолированными от внешнего окружения и выполнятся даже на машине без сети.
В отличии от модульных, интеграционные тесты проверяют как приложение дружит с внешними системами, и как следствие, обладают следующим рядом особенностей:
- могут требовать довольно сложное окружение для своего выполнения (конкретную БД, возможно даже конкретной версии);
- могут быть довольно медленными, так как включают в себя взаимодействие по сети, зачастую с системами производительность которых находятся под контролем третьих лиц;
- являются гораздо более хрупкими чем модульные, потому что опираются на заранее установленное окружение, а также на программное обеспечение которое скорее всего меняется без оглядки на ваше конкретное приложение.
Тем не менее тестировать все равно надо, поэтому такие тесты выделяются в отдульную группу и запускаются на CI-сервере. Настроить и поддерживать в актуальном состоянии сложное окружение проще один раз на сервере, чем десять раз на машинах разработчиков. Разработчик может запустить интеграционные тесты у себя, но для этого он должен настроить хотя бы часть окружения на своей машине, что может быть довольно непросто. Частично эти проблему можно решить при помощи виртуализации и таких инструментов как puppet.
Обычно интеграционные тесты на стороне разработчика запускаются только в случае если менялся интеграционный код системы и как правило только тесты на изменившуюся часть системы. С точки зрения maven (а именно, maven-surefire-plugin) интеграционные тесты отличаются от модульных только постфиксом ( *Test у модульных, *IT у интеграционных). После того как тесту задан соответствующий постфикс, он автоматически начинает запускатся на нужной фазе сборки проекта.
Если с интеграционными тестами все хорошо, то запускаются приемочные. Приемочные тесты проверяют систему по типу черного ящика. Если вы разрабатываете web-приложение, то оно запускается на web-сервере и тест под видом обыкновенного пользователя начинает ходить по нему и проверять его работоспособность. Пожалуй, это один из самых сложных видов тестирования. В нем довольно легко наделать ошибок, которые могут существенно увеличить стоимость поддержки тестовой инфраструктуры. Это в конце концов делает процесс тестирования менее эффективным. Впрочем, тема приемочного тестирования выходит далеко за рамки моего поста, поэтому я не буду заострять на этом сейчас внимание. Людям искушенным очень советую прочитать книгу Джеза Хамбла и Девида Ферли Continuous Delivery.
Ну а мы отправляемся дальше. Следуюшая остановка — статический анализ кода. Мы используем findbugs для анализа кода. Статические анализаторы действительно находят ошибки и потенциальные уязвимости, так почему бы не делать это при каждом изменении наших исходных файлов.

Можно указать TeamCity чтобы при превышении опредленного порога по количеству найденных проблемных ситуаций, билд считался проваленным.
Но, данный шаг можно порекомендовать не всем. Во-первых, для этого требуется существенная поддержка инструментов. Например, для php нет ничего подобного. Во-вторых, получаемая от статического анализатора информация должна оцениваться прагматически. Помните что анализатор показывает риски с формальной точки зрения. У каждого риска есть вероятность материализации и стоимость исправления. Вероятность материализации — это вероятность с которой риск превратится в проблему (то есть вы сможете наблюдать его воочию). Стоимость исправления — это сколько ресурсов (например, в виде человеко часов) нам надо будет потратить если риск все же материализуется в проблему. Перемножив эти два числа мы получим математическое ожидание проблемы. Может оказаться так, что математическое ожидание проблемы гораздо меньше чем стоимость внесения изменений в код здесь и сейчас. Некоторые проблемы дешевле исправлять пост фактум.
После того как статический анализ кода законечен, закончен и процесс непосредственно сборки. Теперь нам осталось опубликовать артефакт в общедоступный репозиторий и можно рапортовать об успешности билда.
Деплой у нас происходит в два этапа. Первый этап это деплой в локальный репозиторий артефактов. Второй этап включает в себя автоматическую доставку приложения на production сервера. Обратите внимание, доставку, но не deploy. Deploy осуществляется только по инициативе и под контролем разработчика. Таким образом, если разаботчик работает над проектом search-service версии 1.0 и на TeamCity успешно выполнился билд под номером 134, то на production кластере в папке проекта автоматически появляется файл search-service-1.0.134.war , который содержит в себе все необходимое для работы приложения и готов к развертыванию по команде разработчика. Это позволяет свести к минимуму участие человека в процессе билда. Человек привлекается только там где его внимание и возможность принимать решения не может заменить машина.
Вот пожалуй и все. Некоторые моменты остались за кадром. Например, как происходит запуск (deploy) приложения на production серверах. Но это тема совсем другого разговора.
Буду рад услышать отзывы и success stories читателей.
- Стандартные действия с коллекцией
- Типы экранов