Русский
Русский
English
Статистика
Реклама

Документация

HowToCode Адаптация системного подхода к разработке для React и TypeScript

07.03.2021 00:21:34 | Автор: admin

Наверное, каждый программист рано или поздно начинает задумываться о качестве своего кода. И, скорее всего, я не ошибусь, если скажу, что добрая половина разработчиков им вечно недовольна. Мне мой код тоже нравился редко: функции, казалось, можно было бы делать и покороче, лишние вложенности было бы неплохо тоже убирать. Было бы здорово писать тесты и документацию, но на них времени не оставалось почти что никогда.

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

Кардинальным образом ситуация изменилась после того, как я прошел курс HowToCode[ссылка удалена модератором, т.к. нарушает правила]. В курсе описан системный и, как всё гениальное, простой и красивый подход к разработке, который сводит воедино анализ, проектирование, документацию, тестирование и разработку кода. Весь курс построен на использовании функциональной парадигмы и языка Scheme (диалекта Lisp), тем не менее, рекомендации вполне применимы и для других языков, а для JavaScript и TypeScript, к которым я постарался их адаптировать, так и вообще подходят отлично.

Результаты мне очень понравились:

  • Во-первых, наконец-то мой код стал читаемым, появилась внятная документация и тесты

  • Во-вторых, заработал подход TDD, к которому я делал несколько подходов, но никак не мог начать ему следовать

  • В-третьих, я практически избавился от отладки: того самого процесса, когда код уже написан, но ещё не работает или работает не так как надо, чем дико раздражает

  • Ну и ещё одно очень приятное наблюдение: я не боюсь что-то забыть или пропустить, потому что в каждый момент времени я работаю над одной конкретной небольшой задачей, а все остальные задачки - записаны

  • Да, и, предвидя вопросы, скажу - по ощущениям время разработки если и замедлилось, то не сильно, даже с учётом написания тестов и документации. А экономия на поддержке кода - просто колоссальная.

Но давайте уже перейдём к сути и посмотрим, как этот подход устроен.

Общая идея

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

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

Этапы проектирования

Подход включает 3 этапа:

  1. Анализ задачи и предметной области

  2. Проектирование структур данных

  3. Проектирование функций

Анализ задачи и предметной области

Анализ задачи необходим для того, чтобы понять, что мы, собственно, будем делать.

Входными данными для этого этапа является постановка задачи. Она может выглядеть как угодно: устная формулировка, пара предложений в тикете Jira или полноценное ТЗ на десятки страниц. На самом деле это не так уж и важно.

Действительно важен тот факт, что есть 2 стороны: заказчик и исполнитель. И в голове заказчика уже есть некоторое представление о желаемом результате, а в голове исполнителя - его нет. И лучшее, что мы можем сделать на этом этапе - это воспроизвести у себя картинку, максимально близкую к изображению в голове заказчика и убедиться в том, что мы сделали это правильно.

Процедура анализа задачи

Для того, чтобы быстро и качественно проанализировать задачу, воспользуемся специальным алгоритмом. Для его выполнения нам потребуются только карандаш и бумага.

Алгоритм

В общем виде алгоритм выглядит так:

Шаг 1. Представить задачу в динамике

Шаг 2. Выделить константы, переменные и события.

Шаг 1. Представить задачу в динамике

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

  • в исходном состоянии

  • в различных промежуточных состояниях: возможно, появляется загрузка, или раскрываются какие-то списки или открываются какие-то окна

  • при окончании работы

Иллюстраций должно быть достаточно для того, чтобы отобразить на них все основные элементы. Если есть макеты от дизайнера - прекрасно, возможно, и рисовать ничего не придётся, но вникнуть в логику переходов между экранами, понять все ли состояния указаны на макете или что-то пропущено, обязательно стоит.

Пример

Допустим, первоначальная постановка задачи звучала как: "Реализовать для web-портала раскрывающийся список, который бы показывал перечень сотрудников, входящих в учебную группу. Для каждого сотрудника должно быть указано ФИО и дата его рождения."

Звучит неплохо, но что делать, пока ещё непонятно. Берем карандаш, бумагу и, если есть возможность, самого заказчика и начинаем рисовать (Ну а я буду рисовать в редакторе).

Начальное состояни

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

Промежуточные состояния

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

Когда список открывается, мы должны показать список сотрудников, входящих в группу, и изменить состояние индикатора. Скорее всего, выглядеть наше приложение станет как-то так:

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

Шаг 2. Выделить константы, переменные и события

Теперь давайте пойдём дальше: выделим 3 группы параметров, которые лежат в основе описания приложения на языке компьютера: константы, переменные и события.

Константы

Константы - это данные приложения, которые во время его выполнения не изменяются. Как правило, к ним можно отнести различные настройки, например:

  • оформление: цвета, шрифты, расстояния, логотипы и иконки, размеры сетки и экрана и т.д.

  • сетевые данные, например, адреса серверов,

  • строковые константы: названия, заголовки и т.п.

Пример выделения констант

Давайте внимательно посмотрим на схемы и выделим то, что у нас в приложении постоянно. У меня получился следующий список:

  • Адрес сервера, с которым работает наше приложение

  • Название приложения, которое отображается в виде заголовка

  • Оформление

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

Переменные

Следующий пункт нашего небольшого анализа - это выявление переменных. Переменные, в противоположность константам - это то, что в приложении меняется в зависимости от разных условий. Это могут быть:

  • координаты объектов

  • значения таймера

  • различные переменные, отражающие состояние элементов интерфейса и т.д.

Пример выделения переменных

Вернёмся к нашим схемам и ещё раз внимательно на них поглядим: какие элементы приложения меняются от схемы к схеме? В общем, ищем всё, что появляется и исчезает, меняет размеры, форму, цвета или ещё каким-то образом вносит изменения в приложение.

У меня получился следующий список:

  • Состояние загрузки приложения: загружается или данные уже загружены

  • Группа, для описания которой нам, скорее всего, понадобится её идентификатор, название, статус открытия списка группы

  • Список участников группы, который, наверняка, в будущем будет являться свойством группы

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

Переменные, как и константы мы записываем отдельной колонкой под схемами:

События

Последний тип параметров, которые нас интересуют - это события, влияющие на поведение программы. То есть то, что меняет переменные, которые мы определили на прошлом шаге.

Событиями могут быть:

  • Изменения этапов жизненного цикла приложения или его отдельных компонентов: инициализация, обновление, удаление, и т.п.

  • Пользовательский ввод: события мыши или клавиатуры

  • Таймер

  • Получение данных с сервера и т.д.

Ну а в нашем приложении такими событиями, на мой взгляд, будут:

  • загрузка данных приложения и

  • открытие и закрытие списка сотрудников по клику мыши на шапку группы

Как и раньше, список событий мы записываем отдельной колонкой под схемами приложения.

Теперь мы уже существенно продвинулись вперед:

  1. Во-первых, мы уже покрутили задачу в голове и более или менее её поняли

  2. Во-вторых, мы сделали её куда как более конкретной, свели все возможные варианты реализации списков к одному

  3. В-третьих, мы получили наглядное представление нашего решения, которое уже можем обсуждать, править и согласовывать. А правки на этом этапе, как вы знаете, самые ценные, потому что практически бесплатные.

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

Проектирование структуры данных

Теперь мы можем переходить ко второму этапу нашего алгоритма - проектированию структур данных.

На этом этапе мы берем константы, переменные и события, которые выявили в ходе анализа и думаем, каким образом нам представить их в программе.

Назначение

Для чего нам это надо?

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

  2. Во-вторых, эти структуры станут основой для типов TypeScript, которые мы будем дальше использовать в клиентской части приложения.

  3. И в-третьих, если структуры данных описать полностью и с примерами, как рекомендует алгоритм, то примеры становятся очень неплохим подспорьем для unit-тестов.

Алгоритм

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

  1. Фиксируем название структуры

  2. Описываем её тип

  3. Пишем интерпретацию структуры - описание того, как преобразовать реальные данные в указанный тип.

  4. Придумываем один - два примера заполненной структуры.

На этом этапе уже начинают играть роль используемые технологии. В нашем случае появляются TypeScript и JSDoc, но для других языков и платформ вполне может использоваться и что-то другое. Ну а раз мы говорим о веб-разработке и библиотеке React JS, то надо сразу отметить, что мы дальше будем использоваться понятия свойств (props) и состояний (state), характерных для React. Ничего страшного, если вы с этими понятиями не знакомы, думаю, что всё будет и так понятно.

Примечание: В курсе HowToCode приводится ещё один, дополнительный шаг описания структуры - написание шаблона функции с одним аргументом, которая будет работать со структурой данного типа. Но мы сейчас этот шаг пропустим, для его изложения потребуется как минимум отдельная статья, если не целая серия.

Пример

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

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

Фиксируем название структуры. Название должно отражать суть структуры. В нашем случае, назовём её AppState - состояние приложения:

export interface AppState {}

Описываем тип структуры. Для этого мы возвращаемся к нашим переменным, константам и событиям, внимательно смотрим на них и думаем, какие из этих данных нам бы следовало разместить на верхнем уровне нашего приложения. У меня получилась вот такая комбинация:

Описание

Название переменной

Источник

Тип данных

Обязательность

Комментарий

Название приложения

title

Константы

Строка

+

Адрес сервера

backendAddress

Константы

Строка

+

Флаг загрузки данных

isLoading

Переменные

Логическое значение

+

true - данные загружаются

false - данные загружены

Данные об отображаемой группе

group

Переменные

Объект типа Group

-

На момент загрузки данные о группе не определены

Метод загрузки данных

loadData

События

Функция

+

Фиксируем это в коде:

export interface AppState {        title: string;        backendAddress: string;    isLoading: boolean;    group?: Group;    loadData: Function;}

Пишем интерпретацию структуры

TypeScript дает отличное представление того, что из себя структура представляет, но всё же, часть информации теряется. Поэтому, давайте сразу зафиксируем, что подразумевается под каждым из полей структуры и каким образом мы можем представить информацию из реального мира в виде такой структуры. Для этого нам пригодится ещё один инструмент из мира JavaScript - JSDoc.

/** * Общее состояние приложения * @prop title - заголовок приложения * @prop backendAddress - адрес сервера * @prop isLoading - флаг загрузки данных (true - загружаются, false - загружены) * @prop group - данные об отображаемой группе. На момент загрузки данных group не определена * @method loadData - метод загрузки данных */export interface AppState {    title: string;    backendAddress: string;    isLoading: boolean;    group?: Group;    loadData: Function;}

Внимательный читатель может заметить появление в описании AppState некой ранее не описанной структуры Group. И действительно, в процессе работы над AppState стало понятно, что данные о группе - это тоже, в свою очередь, сложный тип данных. При этом мы ни в коем случае не бросаемся сейчас же его описывать. Рекомендуется сделать для новой структуры заглушку, после чего вернуться и закончить текущую задачу. Это позволяет всегда концентрироваться только на одном конкретном деле и не распылять своего внимания.

Для заглушки достаточно правильно указать имя новой структуры, описать, что она будет собой представлять и поставить отметку TODO - как правило IDE автоматически распознают отметки TODO и формируют из них удобные списки задач

/** * Общее состояние приложения * @prop title - заголовок приложения * @prop backendAddress - адрес сервера * @prop isLoading - флаг загрузки данных (true - загружаются, false - загружены) * @prop group - данные об отображаемой группе. На момент загрузки данных group не определена * @method loadData - метод загрузки данных */export interface AppState {    title: string;    backendAddress: string;    isLoading: boolean;    group?: Group;    loadData: Function;}/** * Данные об отображаемой группе*///TODOexport interface Group {}

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

Делать это мне всегда тяжело, потому что кажется, что примеры - это пустая трата времени. И каждый раз, когда я дохожу до написания unit-тестов, я радуюсь тому, что я всё-таки их написал. В примерах вместо методов я указываю заглушки и вместо содержания вложенных структур, в нашем случае group - ссылки на переменные нужного типа, для которых временно тоже делаю заглушки. Получается что-то вроде:

/** * Общее состояние приложения * @prop title - заголовок приложения * @prop backendAddress - адрес сервера * @prop isLoading - флаг загрузки данных (true - загружаются, false - загружены) * @prop group - данные об отображаемой группе. На момент загрузки данных group не определена * @method loadData - метод загрузки данных */export interface AppState {    title: string;    backendAddress: string;    isLoading: boolean;    group?: Group;    loadData: Function;}//Пример 1const appState1: AppState = {    title: "Заголовок 1",    backendAddress: "/view_doc.html",    isLoading: true,    group: undefined,    loadData: () => {}}//Пример 2const appState2: AppState = {    title: "Заголовок 2",    backendAddress: "/view_doc_2.html",    isLoading: false,    group: group1, //Заглушка для вложенной структуры    loadData: () => {}}/** * Данные об отображаемой группе*///TODOexport interface Group {}//TODOconst group1 = {}

Итак, первая структура у нас готова, она хорошо описана, поэтому разобраться в ней - проще простого. Можно сделать перерыв, налить чаю, размять спину, а после - взять и описать следующую структуру, отмеченную у нас "тудушкой".

Когда у нас закончатся все TODO и константы, переменные и события, описанные в ходе анализа, мы получим документ с подробным описанием большинства данных, циркулирующих по нашей системе.

Можно сделать ещё один шаг и описать простой контракт между клиентом и сервером нашего приложения. Для этого достаточно выделить из описанных структур те данные, которыми приложение обмениваемся с сервером, и сформировать, например, описание класса - сервиса:

export default abstract class AbstractService {           /**     * Метод загрузки данных о группе с сервера     * @fires get_group_data - имя действия, вызываемого на сервере     * @returns данные о группе     */    abstract getGroupData(): Promise<Group>;}

На клиенте останется только реализовать этот класс, а на сервере - реализовать нужные действия и отдавать данные, которые сервис ожидает, формат их уже для всех ясен.

Теперь наше приложение уже достаточно обросло деталями, чтобы можно было приступать к реализации.

Проектирование функций

Только теперь мы, наконец, переходим к разработке.

Как и для других этапов, для проектирования функций у нас есть свой рецепт - алгоритм:

Алгоритм первоначального проектирования функций

  1. Создаем заглушку. Заглушка - это определение функции, которое:

    • отражает правильное название функции

    • принимает правильное количество и типы параметров

    • возвращает произвольный результат, но корректного типа

  2. Описываем входные, выходные данные и назначение функции

  3. Пишем тесты. Тесты должны иллюстрировать поведение функции и проверять корректность выходных данных при разных входных данных.

  4. Пишем тело функции.

  5. Если в процессе написания функции необходимо обращаться к другой функции, то мы:

    1. сразу описываем функцию и добавляем заглушку

    2. добавляем отметку (TODO), помечающую нашу функцию как объект списка задач

Алгоритм повторяется до тех пор, пока не будут реализованы все задачи в списке задач

Пример проектирования функции

В нашем конкретном случае мы будем понимать под функциями как отдельные React - компоненты с их методами жизненного цикла, так и отдельные дополнительные методы внутри компонентов.

Двигаться, как всегда, мы будем сверху вниз - начиная с самых общих компонентов и постепенно уточняя их, шаг за шагом реализуя вложенные компоненты.

Шаг 1 - Создаем заглушку

Заглушка функции - это минимальное работоспособное её описание, в котором есть:

  • правильное название функции,

  • правильное количество и тип параметров и

  • возвращаемое значение, произвольное по содержанию, но правильного типа.

Для простой функции на TypeScript будет вполне достаточно написать что-то вроде:

export const getWorkDuration = (worktimeFrom: string, worktimeTo: string): string => {    return "6ч 18мин";}

где:

  • getWorkDuration - правильное название фукнции, то есть то, которое мы и дальше будем использовать

  • worktimeFrom: string, worktimeTo: string - два строковых параметра. Именно столько параметров и такого типа функция должна принимать

  • : string после закрывающей круглой скобки - тип возвращаемого значения

  • return "6ч 18мин" - возврат произвольного значения, но правильного типа из функции

Несмотря на то, что такая функция ещё ничего не делает, у неё всё же есть одно очень важное свойство - она уже может выполняться в unit - тестах, что нам и требуется.

В случае с реактом у нас появляются ещё 2 вида заглушек: для функциональных компонентов и компонентов - классов. Выглядят они следующим образом:

Для функциональных компонентов:

const componentName = (props: PropsType) => { return <h1>componentName</h1> }

Для компонентов классов:

class componentName extends React.Component<PropsType, StateType>{    state = {        //произвольные значения для всех обязательных свойств состояния    }    render() {                return <h1>componentName</h1>     }}

где:

  • PropsType - это описание типа передаваемых свойств

  • StateType - описание типа состояния компонента

Ну и реакт-компоненты возвращают нам заголовки с именами этих компонентов, чтобы мы сразу видели в браузере, что они отрисовываются на странице.

В нашем приложении с выпадающим списком сотрудников, самым верхним компонентом является компонент App. У него, как мы поняли из описания типов, есть состояние, значит это будет компонент-класс. Заглушка для него будет выглядеть следующим образом:

interface AppProps {}export default class App extends Component<AppProps, AppState> {    state = {        title: "Отображение списка групп",        backendAddress: "",        isLoading: true,        loadData: this.loadData.bind(this)    }    /**     * Метод загрузки данных с сервера     */    //TODO    loadData() {    }    render() {        return <h1>App</h1>    }}

Надо отметить пару особенностей этой реализации:

  1. В компонент App не передаётся никаких свойств "сверху", поэтому интерфейс AppProps пустой

  2. Тип состояния компонента AppState мы импортируем напрямую из описания типов, которое мы создали, когда проектировали структуры

  3. Состояние предусматривает метод loadData, поэтому мы тут же делаем заглушку для этого метода, отмечаем её маркером TODO, чтобы позже к ней вернуться

Шаг 2 - Описываем входные и выходные данные

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

Для обычных функций мы сначала описываем входные параметры, потом выходные, а потом, глядя на них, пытаемся придумать лаконичную формулировку, которая бы описывала, что функция делает. Тут же мы можем дать краткие пояснения к функционалу, если это необходимо:

/** * Рассчитывает количество часов и минут между указанным начальным и конечным временем * Если время начала работы больше времени конца, то считается, что конечное время - это время следующих суток * @param worktimeFrom - время начала работы в формате ЧЧ:ММ (от 00:00 до 23:59) * @param worktimeTo - время конца работы в формате ЧЧ:ММ (от 00:00 до 23:59) * @return количество часов и минут между переданным временем в формате Хч Y?мин, например 6ч 18мин или 5ч, если количество часов полное *///TODOexport const getWorkDuration = (worktimeFrom: string, worktimeTo: string): string => {    return "6ч 18мин";}

И обязательно отмечаем нашу функцию маркером TODO, чтобы сразу бросалось в глаза, что функция не закончена.

Для реакт-компонентов я, как правило, такое описание не делаю, потому что входные и выходные параметры у всех компонентов одинаковые, да и назначение понятно. Но для всех нестандартных методов компонента и вспомогательных функций, которые не относятся к методам жизненного цикла или хукам реакта, я стараюсь писать документацию, аналогичную приведенной выше, - занимает пару минут, а экономит - часы.

Шаг 3. Тестирование

После того, как назначение и входные и выходные данные определены, можно начать продумывать поведение функции. Лучшее средство для этого - unit-тесты. Есть пара рекомендаций о том, как лучше их писать:

  • unit-тесты должны, как минимум, один раз проходить по каждой ветке внутри функции - то есть проверять все ветвления, если они есть

  • начинать писать и запускать unit-тесты надо с самых простых сценариев, например при которых выполнение функции сразу прерывается. Если даже эти тесты не проходят, то нет смысла тратить время и ресурсы на проверку более сложных вариантов

  • количество и содержание тестов определяются типов данных, с которыми они работают.

Последний пункт надо пояснить отдельно. Для этого давайте посмотрим, как это работает в функциональном программировании.

Зависимость содержания функций и тестов от типов данных в функциональном программировании

В функциональном программировании есть понятие "шаблона функции" - абстрактной схемы внутреннего устройства функции, которая зависит только от типа входных данных.

Допустим, у нас есть структура данных, описывающая состояние светофора. Эта структура называется "перечисление" или enum. То есть переменная этого типа может находиться в нескольких дискретных значениях:

type TrafficLights = "красный" | "желтый" | "зеленый";

Это значит, что любая чистая функция, которая на вход получает один параметр типа TrafficLights будет построена по одной и той же схеме: в ней будет выполняться проверка на текущее значение параметра и, в зависимости от текущего значения, будет выполняться какая-то операция:

function trafficLightsFunction (trafficLights: TrafficLights) {    switch (trafficLights) {        case "красный":            ...        case "желтый":            ...        case "зеленый":            ...    }}

Это и есть шаблон. Если нам понадобится написать очередную чистую функцию, в которой входным параметром будет структура типа TrafficLights - мы можем скопировать шаблон, заменить название функции, подставить нужные операции вместо "..." и вуаля, функция готова.

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

Получается, что тип входных данных определяет и внутреннюю структуру функции - шаблон, и сценарии тестирования.

Но такое утверждение полностью справедливо только для чистых функций, в то время как далеко не все функции у нас - чистые. Многие имеют побочные эффекты, на сервере - это запросы к БД или логирование, на клиенте - сетевые запросы или компоненты с состояниями. А в этом случае использовать подход с шаблонами "в лоб" не получается. Но, тем не менее, свою стратегию тестирования можно формировать с оглядкой на то, как это устроено для чистых функций, внося поправки на побочные эффекты. Что мы и будем делать.

Но сначала давайте посмотрим на взаимосвязь между типами данных и тестами для чистых функций:

Тип данных

Описание

Пример данных

Правила тестирования

1

Атомарные данные

Данные, которые не могут быть разбиты на более мелкие части. При этом они независимы от других и сами не накладывают на другие данные ограничений

Строка

Логическое значение

Число

Для строк допустим 1 сценарий тестирования

для логических значений - 2 (true / false)

Для чисел - 1 сценарий, но может потребоваться дополнительный сценарий для значения 0

2

Перечисления

Данные, которые могут принимать одно из нескольких состояний.

Цвета светофора

Пятибальная шкала оценок

Размеры одежды

и т.д.

Для тестирования нужно, как минимум, столько сценариев, сколько классов значений в перечислении.

Поэтому, если вам нужно протестировать 100-бальную шкалу оценок, но при этом вы понимаете, что значения группируются в 4 класса:

1 - 25,

26 - 50,

51 - 75,

76 - 100

То вам понадобится только 4 сценария.

3

Интервалы

Числа в определённом диапазоне

Скорость автомобиля (0 - 300]

Температура воздуха

и т.д.

Необходимо протестировать:

значение внутри диапазона

граничные значения

4

Детализация

Данные, состоящие из двух или более частей, по крайней мере одна из которых зависима от другой

Подразделение расформировано или нет? Если расформировано, то какова дата расформирования

В данном случае дата расформирования - атрибут, который зависит от признака, расформировано подразделение или нет. Если подразделение активно, то этой даты просто не существует

Тестовый вопрос. В зависимости от типа вопроса может быть указана разная структура вариантов ответа. Если тип вопроса "множественный выбор" - есть массив вариантов ответа с признаками правильности. Если тип вопроса - ввод числа, то есть только один правильный ответ, без вариантов.

Должно быть, как минимум, столько тест-кейсов, сколько комбинаций подклассов может быть.

Для примера с подразделением должно быть минимум 2 сценария:

подразделение нерасформировано и

подразделение расформировано и указана дата расформирования

А для примера с типами вопросов - как минимум, по одному для каждого типа.

5

Сложный тип (объект)

Данные, состоящие из нескольких независимых частей

Объект "Сотрудник" имеющий поля:

id

ФИО

Дата рождения

Пол

и т.д.

Как минимум 2 сценария. При этом надо изменять значения всех полей

6

Массив

Набор данных, объем которых может изменяться

Список сотрудников

Массив учебных курсов, назначенных сотруднику

Как правило, несколько сценариев:

один, проверяющий работу функции при пустом массиве

один, проверяющий работу функции при массиве с одним элементом

один или несколько, проверяющих работу функции, когда элементов в массиве 2 и больше

Примеры тестов

Давайте вернемся к нашим функциям и посмотрим, какие наборы тестовых кейсов нам стоило бы для них написать.

/** * Рассчитывает количество часов и минут между указанным начальным и конечным временем * Если время начала работы больше времени конца, то считается, что конечное время - это время следующих суток * @param worktimeFrom - время начала работы в формате ЧЧ:ММ (от 00:00 до 23:59) * @param worktimeTo - время конца работы в формате ЧЧ:ММ (от 00:00 до 23:59) * @return количество часов и минут между переданным временем в формате Хч Y?мин, например 6ч 18мин или 5ч, если количество часов полное *///TODOexport const getWorkDuration = (worktimeFrom: string, worktimeTo: string): string => {    return "6ч 18мин";}

Итак, функция расчёта рабочего времени. Пусть вас не смущает тип string у параметров, каждый из параметров - это время, представленное в виде строки ЧЧ:ММ, то есть не атомарный тип, а интервал от 00:00 до 23:59. Согласно таблице, для интервалов надо проверить граничные значения и значения внутри диапазона. А так как параметра два, то это справедливо для каждого из них. Для этого нам потребуется 3 тест-кейса:

  1. Первый параметр выходит за граничное значение, а второй нет

  2. Второй параметр выходит за граничное значение, а первый - нет

  3. Оба параметра - в пределах нормальных значений

И ещё в документации есть отметка о том, что рабочее время считается по разному в зависимости от соотношения значений. Вместо одного тест-кейса, где параметры находятся в пределах нормы, напишем 3 кейса, где первый параметр меньше, больше и равен второму, итого 5

Название

worktimeFrom

worktimeTo

Ожидаемое значение

1

Проверка корректности worktimeFrom

Граничное значение, не входящее в диапазон, например

"24:00"

Нормальное значение, например

"18:00"

Исключение

2

Проверка корректности worktimeFrom

Нормальное значение, например

"18:00"

Граничное значение, не входящее в диапазон, например

"24:00"

Исключение

3

Нормальная работа,

worktimeFrom < worktimeTo

Нормальное значение, меньшее чем worktimeTo, например

"00:00"

Нормальное значение, большее чем worktimeFrom, например,

"23:59"

23ч 59мин

4

Нормальная работа,

worktimeFrom > worktimeTo

Нормальное значение, большее чем worktimeTo, например

"18:49"

Нормальное значение, меньшее чем worktimeFrom, например,

"10:49"

16ч

5

Нормальная работа worktimeFrom = worktimeTo

Нормальное значение, например,

"01:32"

Нормальное значение, например,

"01:32"

Тест-кейсы мы к тому же составили так, чтобы одновременно проверялись выводимые значения: с минутами и без. Остается только написать сами тесты. Я их пишу при помощи Jest и Enzyme - стандартной комбинации для React JS. В самом написании тестов особых премудростей нет, поэтому приведу только один пример:

describe('Тестирование расчёта времени между началом и концом работы', () => {        it('Когда начало и конец смены совпадают, функция возвращает 0ч', ()=>{        const result = getWorkDuration("01:32", "01:32");        expect(result).toBe("0ч");    });        //Подобным образом описываем все сценарии    ...});

Тестирование реакт-компонентов практически не отличается от тестирования обычных функций: поведение функциональных компонентов точно так же определяется входными параметрами, как и у чистых функций, поэтому и тестируются они точно так же. А вот поведение компонентов-классов, определяется помимо входных параметров собственным состоянием компонентов, и методами жизненного цикла, поэтому для их тестирования нам требуется специализированный инструмент - библиотека enzyme.

Давайте протестируем компонент App. Заглушка для него выглядела следующим образом:

interface AppProps {}export default class App extends Component<AppProps, AppState> {    state = {        title: "Отображение списка групп",        backendAddress: "",        isLoading: true,        loadData: this.loadData.bind(this)    }    /**     * Метод загрузки данных с сервера     */    //TODO    loadData() {    }    render() {        return <h1>App</h1>    }}

Данные в этот компонент не передаются, а его поведение полностью определяется его состоянием, структуру которого мы определили ранее как:

/** * Общее состояние приложения * @prop title - заголовок приложения * @prop backendAddress - адрес сервера * @prop isLoading - флаг загрузки данных (true - загружаются, false - загружены) * @prop group - данные об отображаемой группе. На момент загрузки данных group не определена * @method loadData - метод загрузки данных */export interface AppState {    title: string;    backendAddress: string;    isLoading: boolean;    group?: Group;    loadData: Function;}

Для начала определимся, к какому типу данных относится эта структура:

  • Во-первых, это сложная структура, состоящая из нескольких полей и членов.

  • Во-вторых, среди полей есть зависимые. Так, наличие поля group зависит от состояния загрузки, пока данные не загружены, данных о группе - нет. Если есть зависимые данные, то можно смело относить эти данные к типу "Детализация".

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

  • для сложных типов (объектов) нужно написать как минимум 2 теста, изменяя при этом значения полей

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

Таким образом, нам следует написать 4 отдельных теста:

  • 2 - изменяя значения всех полей, чтобы проверить, что в нашем компоненте ничего жестко не "зашито" и он, действительно, реагирует на изменения значений

  • 2 - изменяя статус загруженности и соответствующие данные, чтобы проверить, правильность поведения компонента в этом случае

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

И у нас остался ещё метод loadData - если вернуться назад к результатам анализа приложения, то мы увидим, что этот метод у нас появился из-за того, что мы хотели реагировать на конкретное событие в нашем приложении - загрузку данных сразу после появления приложения. Поэтому, желательно, в тесты добавить проверку, что событие, действительно, обрабатывается.

Начнём с простого - с вызова метода loadData при загрузке компонента:

import React from 'react';import Enzyme, { mount, shallow } from 'enzyme';import Adapter from 'enzyme-adapter-react-16';Enzyme.configure({ adapter: new Adapter() });import App from './App';describe('App', () => {    test('Когда компонент App смонтирован, вызывается функция loadData', () => {        //Добавляем слушателя к функции loadData        const loadData = jest.spyOn(App.prototype, 'loadData');                //Монтируем компонент        const wrapper = mount(<App></App>);                //Проверяем количество вызовов функции loadData        expect(loadData.mock.calls.length).toBe(1);    });}

Здесь мы подключили enzyme к нашему файлу с тестами, импортировали сам компонент и написали первый тест. Внутри теста мы:

  1. добавили слушателя к функции loadData внутри компонента,

  2. смонтировали компонент в тестовой среде (то есть сымитировали его появление в приложении) и

  3. проверили, что компонент в ходе монтирования вызвал нашу функцию загрузки данных

Теперь реализуем следующий сценарий - отображение компонента во время загрузки данных.

test('Когда данные загружаются, отображаются только заголовок и спиннер', () => {        //Монтируем компонент        const wrapper = mount(<App></App>);        //Подменяем состояние компонента на нужное для тестирования        wrapper.setState({            title: "Заголовок 1",            backendAddress: "/view_doc.html",            isLoading: true,            group: undefined,            loadData: () => {}        })        //Проверяем правильность отображения компонента        //Проверяем наличие и содержание заголовка        expect(wrapper.find('h1').length).toBe(1);        expect(wrapper.find('h1').text()).toBe("Заголовок 1");        //Заглушка, отображающаяся в процессе загрузки        expect(wrapper.find(Spinner).length).toBe(1);        //Компонент, отображающий группу отображаться не должен        expect(wrapper.find(Group).length).toBe(0);    });

Этот сценарий мы реализуем по следующей схеме:

  1. Монтируем компонент

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

  3. Проверяем правильность отображения компонента

Пока мы писали тест, стало понятно, что для нашего приложения потребуются ещё 2 компонента, которые мы пока не реализовывали:

  • заглушка для отображения в процессе загрузки - спиннер и

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

В этом случае, как и прежде, мы сразу создаём для них заглушки и на время забываем о них.

Реализуем третий сценарий по аналогичной схеме:

test('Когда данные загружены, отображается заголовок и группа. Спиннер не отображается', () => {        const wrapper = mount(<App></App>);        wrapper.setState({            title: "Заголовок 2",            backendAddress: "/view_doc_2.html",            isLoading: false,            group: {                id: "1",                name: "Группа 1",                listOfCollaborators: []            },            loadData: () => {}        })        expect(wrapper.find('h1').length).toBe(1);        expect(wrapper.find('h1').text()).toBe("Заголовок 2");        expect(wrapper.find(Spinner).length).toBe(0);        expect(wrapper.find(Group).length).toBe(1);    });

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

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

Шаги 4 и 5. Реализация функций и формирование списка задач

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

  • во-первых, старайтесь писать более высокоуровневый код,

  • во-вторых, избегайте коварной ошибки, которая называется Knowledge Shift (сдвиг области знаний).

Высокоуровневый код

Не торопитесь сразу приступать к реализации. Для начала подумайте не о том, как реализовать алгоритм, а о том, какие крупные шаги в нем могут быть и что вы хотите получить на каждом из этих шагов. Подумайте, можно ли без ущерба вынести каждый такой шаг в отдельную функцию, и если это сделать можно - смело выносите.

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

/** * Рассчитывает количество часов и минут между указанным начальным и конечным временем * Если время начала работы больше времени конца, то считается, что конечное время - это время следующих суток * @param worktimeFrom - время начала работы в формате ЧЧ:ММ (от 00:00 до 23:59) * @param worktimeTo - время конца работы в формате ЧЧ:ММ (от 00:00 до 23:59) * @return количество часов и минут между переданным временем в формате Хч Y?мин, например 6ч 18мин или 5ч, если количество часов полное *///TODOexport const getWorkDuration = (worktimeFrom: string, worktimeTo: string): string => {    return "6ч 18мин";}

Очевидно, что для того, чтобы получить разницу во времени между двумя параметрами, каждый из которых представляет собой строку в формате "ЧЧ:ММ", и вернуть эту разницу тоже в строковом формате, нам надо выполнить несколько действий:

  1. Привести параметры к числовым значениям, например, минутам, прошедшим с 00:00

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

  3. Привести получившуюся разницу к формату Xч Y?мин, который и вернуть из функции

И тут мы могли бы пойти двумя путями:

  • сразу начать делить параметры на части по разделителю ":", проверяя входные значения и умножая часы на минуты и т.д. или

  • выделить каждый шаг в отдельную функцию.

В результате мы бы получили такую картину:

/** * Рассчитывает количество часов и минут между указанным начальным и конечным временем * Если время начала работы больше времени конца, то считается, что конечное время - это время следующих суток * @param worktimeFrom - время начала работы в формате ЧЧ:ММ (от 00:00 до 23:59) * @param worktimeTo - время конца работы в формате ЧЧ:ММ (от 00:00 до 23:59) * @return количество часов и минут между переданным временем в формате Хч Y?мин, например 6ч 18мин или 5ч, если количество часов полное */export const getWorkDuration = (worktimeFrom: string, worktimeTo: string): string => {    const worktimeFromInMinutes = getWorktimeToMinutes(worktimeFrom);    const worktimeToInMinutes = getWorktimeToMinutes(worktimeTo);    const minutesDiff = calcDiffBetweenWorktime(worktimeFromInMinutes, worktimeToInMinutes);    return convertDiffToString(minutesDiff);}/** * Вычиcляет количество минут, прошедших с начала суток * @param worktimeFrom - время в формате ЧЧ:ММ (от 00:00 до 23:59) * @returns количество минут, прошедших с 00ч 00минут *///TODOexport const getWorktimeToMinutes = (worktime: string): number => {    return 0;}/** * Вычисляет количество минут между началом и концом рабочего дня с учётом суток * @param worktimeFrom - время начала рабочего дня в виде количества минут, прошедших с начала суток * @param worktimeTo - время конца рабочего дня в виде количества минут, прошедших с начала суток * @returns количество минут между началом и концом рабочего дня с учётом суток *///TODOexport const calcDiffBetweenWorktime = (worktimeFrom: number, worktimeTo: number): number => {    return 0;}/** * Преобразовывает количество минут во время в формате Хч Y?мин * @param minutes - количество минут * @returns время в формате Хч Y?мин, например 6ч 18мин или 5ч *///TODOexport const convertDiffToString = (minutes: number): string => {    return "6ч 18мин";}

Основная функция здесь распадается на несколько вложенных, определяя, по сути, только верхнеуровневый алгоритм преобразования. Сами же детали реализации алгоритма вынесены в отдельные функции. Согласно нашей технологии, для каждой новой функции сразу пишется только заглушка и маркер TODO, который формирует наш список задач. Сами функции будут реализовываться позже. Вложенные функции, в свою очередь, могут дробиться на ещё более мелкие по тем же принципам.

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

Knowledge Shift

Говоря о проектировании функций, конечно же, нельзя обойти стороной такую ошибку как Knowledge Shift.

Чтобы понять, что это за ошибка, мы снова обратимся к чистым функциям, которые, как вы знаете, работает только с теми структурами данных, которые передаются ей в качестве параметров - эти структуры составляют её область знаний (домен) . Но часто случается так, что структуры, поступающие на вход функции сами являются сложными, то есть содержат внутри себя вложенные объекты или массивы.

В этом случае, мы рискуем столкнуться с ситуацией, когда функция начинает выполнять какие-то операции над входными структурами, а затем переключается на работу с вложенными, как бы сдвигая фокус с родителя на дочерний объект. Это и есть Knowledge Domain Shift или просто Knowledge Shift.

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

Чтобы этого избежать, рекомендуется передавать обработку внутренних сложных структур в отдельные функции, как мы сделали это при реализации нашего реакт-компонента App:

export default class App extends Component<AppProps, AppState> {    state = {        title: "Отображение списка групп",        backendAddress: "",        isLoading: true,        group: undefined,        loadData: this.loadData.bind(this)    }    /**     * Метод загрузки данных с сервера     */    //TODO    loadData() {}    componentDidMount() {        //Вызываем метод loadData при загрузке приложения        this.loadData();    }    render() {        const {isLoading, group, title} = this.state;        return (            <div className="container">                <h1>{title}</h1>                {                    isLoading ?                    <Spinner/>                    //Структуру типа Group передаем на обработку отдельному компоненту                    : <Group group={group}></Group>                }            </div>        );    }}

Мы добавили в компонент реализацию метода жизненного цикла componentDidMount, который вызовет наш метод загрузки данных при отображении компонента. Но основной функционал у нас содержится в методе render. В нем мы выводим заголовок и, в зависимости от статуса загрузки, рисуем либо заглушку - спиннер, либо компонент Group.

Обратите внимание, что мы напрямую используем только простые данные, относящиеся к структуре cостояния компонента. Сложную вложенную структуру group мы просто передаем в отдельный компонент, потому что не хотим, чтобы компонент App знал о ней что-то кроме того, что она вообще есть. Таким образом, структуры данных определяют, по сути, не только реализацию конкретного компонента, но и, частично, структуру приложения и его разбиение на компоненты.

Теперь, нам остаётся только удостовериться, что все написанные нами тесты проходят. После чего, мы берем следующую задачку, отмеченную маркером TODO и реализовываем её по точно такой же схеме: тесты + реализация функции. И так мы продолжаем до тех пор, пока ни одной TODO в нашем списке не останется.

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

Вот в общем-то и весь подход. Он не сложен, но требует привычки и дисциплины. Как и в любом сложном деле, самая большая проблема - начать и не поддаваться желанию бросить его на первых парах. Если это удастся, то через некоторое время вы и думать не захотите о том, чтобы писать код по старинке: без тестов, документации и с длинными непонятными функциями. Успехов!

Подробнее..

Как сделать, чтобы базой знаний начали пользоваться человеческие люди

13.04.2021 10:07:06 | Автор: admin

Корпоративная база знаний это не только и не столько площадка на базе какого-нибудь вики-движка, сколько люди и процессы, стоящие за ней. При внедрении вики-платформы самое сложное это не тонкая настройка движка или попутных расширений: самое сложное это сделать так, чтобы коллеги наконец начали пользоваться поднятой вами базой знаний.

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

Мой лучший портретМой лучший портрет

Про меня и мою базу знаний

В людях живал свету видал: топор на ногу обувал, топорищем подпоясывался

Ahoj. Меня зовут Коля, я QA тимлидер в компании Veeam. QA в нашей компании включает в себя не только тестирование, но и обеспечение качества в самом широком смысле. И среди этих смыслов затесалась такая штука, как управление знаниями. Я занимаюсь внутренней корпоративной базой знаний компании практически с самого ее появления, при этом поддержка базы знаний не входит в список моих обязанностей: это скорее что-то вроде pet-проекта. Долгое время у вики был статус поделочки, а мои попытки навязать вики коллегам приводили лишь к пополнению корпоративного стикер-пака моей фотографией.

Впрочем, время идет, времена меняются. Сейчас вики насчитывает 700 пользователей, 11 000 страниц, 56 000 правок и 688 000 слов (примерно полтора романа "Война и мир", если говорить только о тексте). Всего-то в 2 000 раз меньше русскоязычной Википедии, и это при условии работы на исключительно добровольных началах: никто не принуждает сотрудников пользоваться нашей вики.

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

Общий подход

Ищи себе прибыли, а другому не желай гибели

Давайте я сразу это проговорю: серебряной пули нет. Все, что я здесь описываю, может сработать, а может не сработать. Не устраивайте из моих советов карго культ. Вы лучше меня знаете своих коллег и лучше понимаете, какой подход подойдет в вашей компании, в вашем коллективе. Есть какие-то более-менее универсальные вещи, но и они в некоторых случаях могут не работать.

Главный совет, который я бы хотел дать в этой статье, звучит так: относитесь к проекту базы знаний как к публичному проекту. Скажем, если бы вы придумали Википедию или Хабрахабр, как бы вы продвигали их в массы? Реклама? Уникальный контент? Холодные как хвост вашей бывшей звонки на случайные номера из телефонной книги? Возможны любые варианты продвижения, но не забывайте адаптировать их к реалиям вашей компании и вашего коллектива. А еще не забывайте, что в случае недобросовестной рекламы коллеги узнают, где вас найти. Не перегибайте палку.

Кроме прочего, подход к вики как к публичному проекту позволяет проще относиться к проблеме продвижения. Я часто слышал обиды и сетования, что, мол, коллеги не делятся знаниями, не пишут внутреннюю документацию. Но вы же не обижаетесь на пользователей за то, что они не скачивают ваше приложение или не покупают ваши чудо-подушки за $9,99? Вы ищете способ понравиться вашим пользователям, ищете путь к их теплокровному сердцу, а не способ подчинить их вашей воле.

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

Собирайте статистику

Красна птица перьями, а человек знанием

А начнем мы с того, что нам нужно как-то оценивать качество тех способов продвижения, что мы будем пробовать. В связи с этим первое, чем стоит озаботиться это сбор статистики. Скажем, я пользуюсь Matomo (которые раньше звались Piwik), но похожий функционал есть у десятков аналогов.

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

Помимо оценки эффекта продвижения, статистика предоставляет и пачку других плюшек:

  • Анализ поисковых запросов решает сразу несколько проблем:

    • Вы понимаете, что людям интересно, что они хотели бы видеть на вики. Если у вас нет статей по теме, которая интересна вашим коллегам, это отличный повод их туда добавить.

    • Кроме того, так вы можете понять, хорошо ли работает поиск, показывает ли он в поисковой выдаче правильные статьи. Если нет, то, возможно, стоит доработать поиск: убрать из индексинга ненужную информацию или добавить дополнительные ключевые слова в статью. А в особых случаях, возможно, имеет смысл задуматься о смене поискового движка.

  • Можно добавлять логирование конкретных действий, что позволит вам узнать, как часто пользуются тем или иным функционалом. Так вы не будете вкладывать силы в то, чем абсолютно никто не пользуется. И сможете продвигать базу знаний, подчеркивая в обсуждениях объективно самые популярные фичи.

Накопите критическую массу знаний

Там хорошо, где нас нет

Если вы лишь недавно начали развивать базу знаний, найдите способ наполнить ее контентом.

Вполне возможно, что информация о продуктах, технологиях и фичах уже есть где-то, но в разрозненном неструктурированном виде: почтовые треды, сообщения в Slack/Teams, сетевые папки десятилетней давности, Sharepoint-ы, осколки прошлых неудачных попыток завести единую базу знаний и так далее.

Но будьте внимательны к тому, что вы сохраняете на вики: внутренняя база знаний это источник необщедоступной информации. За общеизвестной информацией проще пойти в Гугл или Википедию, так что подобные статьи скорее всего окажутся мертвым грузом на вашем сайте.

Еще один очевидный источник контента ваши личные заметки и ваши личные знания. Об этом аспекте давайте поговорим поподробнее.

Вам надо вот сами и пользуйтесь

Не ищи в селе, а ищи в себе

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

Проанализируйте свои потребности: какая информация вам нужна в работе, какие знания значительно ускорили или улучшили бы вашу работу. Информация о сфере ответственности или компетенциях коллег? Детальные описания фичей и внутренних API? Правила оформления отпуска и процедура выпуска релиза? Найдите удобный способ хранить и обновлять информацию такого рода, поделитесь этим с коллегами. Наверняка это было не только вашей болью, но и их тоже.

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

Сделайте вики единой точкой доступа для поиска любых знаний

И чтец, и жнец, и на дуде игрец

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

  • Можно сделать просто каталог внутрикорпоративных сайтов (привет, девяностые). Да, подход, мягко говоря, не самый свежий, но и у вас в компании скорее всего не тысячи порталов. Для пары десятков сайтов и каталог обычно подходит неплохо.

  • Или же можно идти по пути Гугло-поисковика и встраивать себе поиск по другим сайтам. При этом необязательно писать свой краулер, можно обойтись и более дешевым решением. Например, воспользоваться поисковым API сторонних сайтов и выводить результаты поиска по другим сайтам, если на вашей вики результатов не нашлось.

При этом не забывайте, что поиск "любых знаний" не ограничивается знаниями техническими. Такие вещи, как процедуры оформления отпусков или контакты HR/бухгалтерии/охраны/etc могут оказаться не менее важной частью вашей базы знаний, чем описания фичей или продуктов.

Создавайте зону комфорта для окружающих

Не хвались теплом в нетопленой избе

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

  • Сделайте удобную главную страницу. У проектов Викимедиа особый подход к главным страницам, но мне он не нравится: их главные страницы перегружены информацией, они вызывают ужас и непонимание у неподготовленного пользователя.

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

  • Стандартизируйте и упростите процесс документирования типовых вещей. Формы и шаблоны позволяют не думать про форматирование и сосредоточиться только на содержании.

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

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

    Вам может показаться, что ваши коллеги с тремя высшими легко освоят очередной markdown, и в этом нет большой нужды, но вы ошибаетесь: они могут освоить ваш маркдаун за час, но не хотят. Им это неинтересно, так к чему плодить страдания без необходимости?

  • Моя любимая история про поиск. В Veeam используется невероятное количество внутрикорпоративного жаргона, равнодалекого от русского и английского языков. Звучать оно может примерно так: "Задизейбли шедул джобы и чекни базу вана, висит ли флаг". Адаптация к жаргону проходит не очень быстро, но это полбеды. Беда в том, что у разных отделов может отличаться терминология, так что не всегда мы понимаем друг друга. А еще мы почему-то очень любим трехбуквенные аббревиатуры, которых накопилось, наверно, больше сотни (и которые не всегда просто расшифровать).

    В базе знаний этот вопрос решился введением постоянно пополняемого словаря синонимов, аббревиатур и прочего. Словарь используется при поиске, так что пользователь всегда видит, что, например, по запросу "data mover" находится "VeeamAgent" компонент. Составлять словарь приходится вручную, так что иногда доводится выбираться в лингвистические экспедиции для сбора материала в соседние отделы.

    Конечно, остается проблема с тем, что одно и то же слово может означать сразу несколько вещей (скажем, "бекап" это резервная копия, задание резервного копирования, процесс резервного копирования, продукт Veeam Backup & Replication или отдел Backup QA в зависимости от контекста). Это пока что решаем по аналогии с Википедией: создаем страницу с термином и расписываем, что этот термин может значить.

  • На большой Википедии вместе с каждой страничкой создается страница для обсуждения. Я же со своей вики все страницы обсуждения убрал: на мой взгляд, реализация дискуссий на Википедии очень плохо подходит для внутрикорпоративных дискуссий. Куда лучше заставить людей пользоваться привычными средствами ведения дискуссий: почта, чаты и звонки в MS Teams. И вопрос решается быстрее, и негатива меньше.

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

Рассказывайте о новостях

Из серебряных речей пулю не отольешь

Никто не узнает о том, какая у вас крутая база знаний, если вы не будете об этом рассказывать. И желательно не один раз. Как говорил один мой университетский преподаватель:

Обычному человеку нужно повторить одно и то же десять раз, прежде чем он запомнит. Однако вы интеллектуальная элита страны, лучшие из лучших. Вам достаточно девяти.

Думаю, нас он на тот момент сильно переоценил, но мысль верная: недостаточно один раз рассказать про существование и назначение базы знаний, обо всем этом нужно периодически напоминать. Чтобы не выглядеть как умалишенный, стоит использовать разные поводы для этого, например:

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

  • В группах по фиче/продукту/проблеме рассказывайте о новых статьях по теме, написанных вашими коллегами. Русскоязычные айтишники скромный народ, мы обычно не любим хвастаться плодами своего труда. Сделайте это за них: во-первых, авторам будет чертовски приятно, а во-вторых, это будет поводом ввернуть пассаж про важность, пользу или даже просто про существование базы знаний.

Как и во всем, здесь стоит знать меру. Однако не пренебрегайте информированием коллег о том, что происходит с вашей базой знаний.

Угрозы, вымогательства

Воруй любовь, убивай скуку

Писать сложнее, чем читать. Знаю это по себе, ведь эту статью я собирался написать еще два года назад. Поэтому для того, чтобы мотивировать людей не только читать, но и писать, придется заморочиться чуть больше. Что у нас есть в арсенале?

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

    Расскажите про пресловутый bus factor и проиллюстрируйте примером, ведь наверняка вы с этим уже сталкивались на практике (надеюсь, впрочем, что не в такой трагичной форме).

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

  • Не стоит, впрочем, слишком давить на страх, ведь это не лучший источник мотивации. Стоит также обратить внимание коллег на то, какие плюсы это несет для них.

    Надоело до одури заниматься одним и тем же? Если это в ваши силах, рассмотрите возможность ротации людей между проектами. Для этого, впрочем, нужно будет подготовить почву: документация, вводные лекции, право на безлимитные консультации.

    Хочется меньше запросов от техподдержки? Поделитесь с ними знаниями, так вас будут меньше дергать по пустякам. Как правило, техподдержка очень охотно и быстро впитывает все знания, что им предоставляют.

    Все вышесказанное звучит логично, но совсем нет времени на то, чтобы описывать детали текстом? Попросите провести лекцию и перенесите на вики самостоятельно в текстовом или хотя бы в видео формате. Почему-то на лекцию обычно соглашаются охотнее, чем на статью. Если знаниями обладает один-единственный человек, то даже такой формат будет лучше, чем ничего, хоть здесь и не обойдется без времязатрат с вашей стороны. В конечном итоге это позволит ознакомиться с областью и другим коллегам, в том числе и более благосклонным к ведению документации.

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

Играйте на здоровом самолюбии

Птицу кормом, а человека серебряной пулей обманывают

Мы, люди, любим, когда нас хвалят, ставят лайки, когда о нашем труде знают и когда мы видим, что наши старания не проходят даром. Давайте же используем это во благо!

  • Добавьте блок новостей на главную страницу, где будет информация обо всех новых правках (или хотя бы обо всех новых статьях). Рядом с именем статьи непременно должен светиться ник автора правки.

  • Если вам позволяют ресурсы, можно попробовать варианты геймификации и добавить рейтинги или ачивки (например, за N статей/правок). Хотя есть мнение, что эти штуки сработают далеко не в каждом коллективе.

  • У меня не было столько времени, чтобы добавлять геймификацию, но я добавил блок "Your impact" на главную страницу. Там выводится 10 самых просматриваемых статей из числа отредактированных вами, а рядом с ними число просмотров с момента вашей первой правки.

    Идея эта не моя, я подсмотрел ее на MediaWiki хакатоне в Праге, где growth team рассказывали про свои исследования аналогичной фичи большой Википедии и предлагали поучаствовать в разработке. Конечно, мне пришлось переписать фичу с нуля, поскольку у меня совсем другие источники данных, чем у Wikipedia, но в остальном я старался следовать рекомендациям Growth team.

  • Маленькое расширение Thanks может послужить аналогом лайков для конкретных правок. Оно, конечно, не очень удобное, но лучше, чем ничего. И реагируют коллеги на такие "спасибо" обычно очень положительно.

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

Расскажу, как я начал заниматься базой знаний. На заре моего трудоустройства коллега организовал мини-конкурс: автор наибольшего вклада в развитие вики должен был получить награду, достойную чемпиона стакан черной смородины (напомню, Veeam IT компания с достойными зарплатами, мы тут не голодаем). Смородина та кончилась пять-шесть лет назад, а проектом я занимаюсь и поныне. Не могу сказать, что это был гениальный ход с его стороны, но он сработал, а это главное.

Присматривайте за другими

У семи нянек детеныш без серебряной пули

Я искренне считаю, что для внутренней базы знаний любая форма премодерации это огромный могильный камень. Необходимость что-то с кем-то согласовывать убивает всяческое желание вносить правки. Тем не менее, без модерации вики быстро превратится в помойку с огромным количеством дублирующегося и устаревшего разрозненного контента, который еще и не так просто найти. Решение есть: постмодерация. Дайте людям писать как им удобно, а затем приведите написанное в порядок.

Постмодерацией (патрулированием правок) нужно заниматься заниматься регулярно, в идеале каждый день. Да, это отнимает время, но это необходимо, чтобы вики не превращалась в помойку. Расставляйте категории, чините навигацию, исправляйте нестандартное форматирование, чистите текст от пассивно-агрессивных нападок и явных ошибок.

Помимо того, что патрулирование правок позволяет сохранить организацию контента, это также помогает вовремя обнаружить, что у кого-то возникли проблемы или вопросы. Когда в ответ на твои безуспешные попытки сделать что-то хитрое с документацией тебе пишет ответственный за базу знаний; показывает и рассказывает, как проще всего сделать то, что тебе нужно, исправляет косяки и вообще ведет себя как душка, это подкупает. Я сталкивался с таким отношением на других вики-проектах, и мне это показалось самым рабочим методом обучения новичков. Теперь стараюсь продвигать те же принципы у нас.

Вместо заключения или "насильно мил не будешь"

Лучше на гривну убытку, чем на алтын стыда

Ваша база знаний подойдет не для всего и не всем. Даже в моем случае MediaWiki самая популярная и большая внутренняя база знаний, но далеко не единственная. Есть команды, привыкшие на прошлых местах работы к Confluence/Sharepoint/впишите нужное. Отдельные команды все еще бойкотируют создание внутренней документации под теми или иными поводами. На мой взгляд, это нормально.

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

Пожелание "сделайте так, чтобы мою вики использовали, пожалуйста" мало чем отличается от "сделайте так, чтобы в мою игру играло много человек". Да, у продвижения разных сервисов и услуг есть свои особенности, но у них гораздо больше общего, чем может показаться. Чтобы продвигать базу знаний, попробуйте мыслить как SMM специалист и основатель стартапа в одном лице, а не как Пётр I, насильно сбривающий бороды (никаких претензий к Петру, просто подход другой). И хотя идеального способа продвижения нет и вероятно, никогда не появится, в ваших силах найти рабочие для вашей конкретной компании способы. Удачи!

Подробнее..

Справочный центр Selectel интерфейс, техническая реализация и возможности

19.08.2020 12:13:25 | Автор: admin

Каждой предоставляемой услугой Selectel можно управлять в личном кабинете панели управления. Многими нашими продуктами также возможно управлять через запросы к API. Инструкции по работе с продуктами и документация API доступны в едином справочном центре.

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

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

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

Около года назад мы обратили внимание на то, что существующая онлайн-справка не отвечает требованиям наших клиентов:

  • меню навигации разрасталось, как плодовое дерево, не знающее заботы садовника;
  • поиск перестал быть удобным;
  • визуальное оформление постепенно устаревало.

Ранее документации к API наших продуктов не было в открытом доступе часть была размещена в панели управления my.selectel.ru, что-то выдавалось по запросу, а что-то было и вовсе описано в текстовом формате, поддерживать который в актуальном состоянии было весьма проблематично. Теперь знания по автоматизации IT-инфраструктуры и взаимодействию с бэкендом сервисов Selectel на вкладке Документация API.

Небольшой экскурс в прошлое


Еще десять-пятнадцать лет назад мало кто из компаний, производящих программное обеспечение в России, мог похвастаться наличием онлайн-справки. Руководства по эксплуатации писали в формате Word с применением вечно съезжающих стилей, пытаясь применить ГОСТы, созданные в 70-х годах 20 века к современным и постоянно меняющимся требованиям.

В среде технических писателей всё ещё популярен мем:


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

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

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

  1. Пользователь заказал услугу.
  2. Столкнулся с неочевидными моментами при настройке.
  3. Хотел обратиться в техническую поддержку.
  4. Зашел в базу знаний и нашел нужную информацию самостоятельно.
  5. Не обратился в техническую поддержку.
  6. Профит!)

Зачастую бытует мнение, что справочная информация только помогает пользователям разбираться в услугах после их подключения. Вероятно, так было в те времена, когда выпускали печатные книги с информацией по работе в ОС Windows. Но сейчас становится настолько же важным открыто показывать потенциальным пользователям, как действует услуга до приобретения.


Большинство компаний, производящих ПО, на определённом этапе разрабатывают API как для внутреннего использования, так и для клиентов. Компании делятся набором вводных параметров, выпуская публичные API для того, чтобы дать клиентам возможность объединять свои сервисы и предлагаемые компанией продукты.

Многие пользовательские задачи можно автоматизировать, в том числе используя готовые куски кода как конструктор для создания максимально удобной в использовании инфраструктуры. Но куски кода без объяснений, что это такое, что оно делает и как этим пользоваться малополезны не будешь ведь перебором выяснять, какие есть методы и какие данные они ожидают на вход.
Что нужно сделать, чтобы публичным API было приятно пользоваться?
Приложить документацию!
В качестве документации к API обычно дают минимальный пример взаимодействия, в котором описаны методы (также их называют эндпоинтами) и приведены ответы от сервиса. Например, с помощью API Kubernetes можно автоматизировать работу с кластерами и нодами в Managed Kubernetes.

Какие задачи стояли перед нами


Наше визуальное решение перестало позволять легко находить нужные статьи, и существующее меню превратилось в нечитаемую простыню. Нечитабельная документация также плоха, как неактуальные тексты. Люди привыкли читать хорошо сверстанные материалы. Блоги, соцсети, медиа весь контент подается не просто красивым, но и удобным для чтения, приятным для глаза. В настоящее время нельзя игнорировать UX и UI требования, тем более для такого огромного массива текстов.

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

Часто возникающие проблемы с документацией


Вообще отсутствует или никто не знает о ее существовании
Инструкция, которую нельзя найти, ничем не лучше инструкции, которой нет.

Мы решали эту проблему следующим образом стали добавлять ссылки на полезные статьи в нашей ежемесячной рассылке, добавляем переходы на продуктовых страницах сайта, а также наладили оповещение всех заинтересованных сотрудников компании через специальный канал в корпоративном мессенджере.

Устаревает и вовремя не актуализируется
Процесс документирования не встроен в разработку продукта, документация делается по остаточному принципу.

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

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

Мы полностью пересмотрели конструкцию разделов нашей базы знаний, в некоторых случаях универсальные шаблоны не работали, поэтому нам надо было активно взаимодействовать за всеми заинтересованными сторонами, будь то менеджер продукта, техническая поддержка или команда фронтенд-разработки.

Вынесение документации API в публичное пространство
Одной из проблем использования документации API, сгенерированной в OpenAPI, Swagger или с помощью другого инструмента генерации, является сложная интеграция с остальной частью сайта. Нужно, чтобы пользователи имели беспроблемный доступ ко всем инструкциям и статьям неудобно, если эндпоинты отображаются в одном представлении, а текстовые описания тех же процессов на другой странице.


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

Как это работает теперь


Техническая реализация


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

Мы отказались от Confluence и перешли к принципу Documentation-as-Code. Сейчас все исходные тексты для базы знаний верстаются в формате Markdown и хранятся в системе хранения версий Git. Из хранилища с помощью генератора статических сайтов Hugo собирается сайт базы знаний.

Сайт генерируется из файлов, содержащихся в master-ветке Git-репозитория. Обновить данные можно только через pull-request, что позволяет проверять все новые разделы документации перед тем, как они будут опубликованы в общем доступе. Такая система также облегчает подход к внесению правок сотрудники компании всегда могут создать ветку и добавить в нее все нужные изменения.

Подробнее о Documentation as Code


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

  • языки разметки текста;
  • системы контроля версий;
  • code review.

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


Работа со swagger-файлами


Разработчики продуктов Selectel формируют API, и выгружают комментарии к коду в swagger-формате это текстовый файл в в формате *.yaml, с которым можно работать как с кодом. При обновлении API обновляется и swagger-файл, что позволяет упростить актуализацию документации.

Для документации API используется следующее техническое решение:

  • git-репозиторий с файлами swagger-спецификаций в формате *.yaml, сгруппированными по продуктам;
  • git-репозиторий с переводами swagger-спецификаций в формате *.json;
  • git-репозиторий с файлами в формате *.md;
  • файлы в формате *.md содержат текстовые описания и обернутые в специальные теги описания эндпоинтов, которые подтягиваются из git-репозитория с файлами в формате *.json;
  • генератор статических сайтов Hugo.

Кроме структуры репозитория были разработаны правила работы с ним:

  • подготовлен стайлгайд чек-лист для swagger-файлов, с которым сверяются разработчики при обновлении спецификаций API;
  • ветвь master git-репозитория с файлами в формате *.md отражает состояние актуальных спецификаций и де-факто находится на продакшене;
  • Pull-Request в master-ветку осуществляется при выпуске обновлений в боевую эксплуатацию.

Визуальная составляющая


Первым делом требовалось пересмотреть навигацию и создать правила, по которым бы формировались разделы базы знаний. Совместно с UX-проектировщиками мы подготовили информационную архитектуру. Структура должна быть максимально прозрачной, чтобы читатель не задумывался: А где можно найти эту статью?. Если обобщить, то есть два подхода:

  • От интерфейса. Содержание дублирует разделы панели (отдельно по услугам). Так было в предыдущей версии базы знаний.
  • От задач. Названия статей и разделов отражают задачи пользователей.

Для того, чтобы упорядочить структуру, мы применили комбинацию этих двух подходов. Даже в новых версиях панели управления с продуманным UX и UI необходимо давать пояснения, как минимум, к терминам, так как наши продукты технически сложные, а пользователи очень разные.

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

Каждая компания делает документацию API в соответствии с собственным видением стиля, структуры и чувства прекрасного. Если открыть 4-5 публичных API разных компаний, то, несомненно, мы сможем уловить некие общности: структура, объемные примеры кода и подсветка синтаксиса, длинные страницы. Но тем не менее все примеры будут обладать особенностями. Например, локализация описаний эндпоинтов встречается редко, притом что как раз структура описания эндпоинтов чаще всего выглядит одинаково.

Несколько рекомендаций к структурированию документации API:

Группировка эндпоинтов
Помимо предоставления информации для каждого эндпоинта, если эндпоинтов много желательно группировать их. Длинный сплошной список эндпоинтов затрудняет навигацию.

Отдельное описание методов
При одновременном использовании методов GET/POST в одной строчке должен быть описан только один метод.

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


Автоматизация внесения изменений
Упростить внесение изменений без ручного переформатирования каждого раздела в нашем случае мы переводим только текст swagger-файла, не трогая разметку благодаря автоматизации этого процесса, который настроили наши devops-специалисты.

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

Работа с кусками кода значительно удобнее, когда различные элементы окрашены соответствующим образом в зависимости от языка программирования.

Так как из коробки была доступна подсветка кода только для темного фона, frontend-разработчик дорабатывала это решение с помощью highlight.js до нашего корпоративного стиля.

Вместо заключения


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


(Льюис Кэрролл Алиса в Зазеркалье)
То, что мы уже сделали, лишь очередной шаг на пути совершенствования базы знаний. Постепенно мы будем добавлять новые инструкции и документацию к API других наших сервисов.
Подробнее..

Из песочницы Такие разные документы конструкторские vs. user-oriented

17.11.2020 14:16:28 | Автор: admin
Моим любимым русским техническим писателям посвящается

Работа технического писателя создавать документы на программные продукты, в основном всевозможные руководства пользователя. Разработка документа дело непростое. Есть очень много подходов и практик. Например, технические писатели в научно-производственных предприятиях часто пишут по ГОСТам или другим отечественным стандартам. Их цель точно и верно описать продукт. А technical writers в международных компаниях пишут по style guides (Microsoft Manual of Style, например). В этом случае цель, скорее, донести до пользователя, как продукт работает. Здесь фокус смещен с продукта на читателя.

Мне довелось побыть техническим писателем в разных местах, с разными правилами и политиками. Оглядываясь назад, могу сказать, что даже в НИИ тексты можно переориентировать на конечного пользователя, и документы от этого выиграют. Но в ГОСТах про это не пишут. А style guides, во-первых, на английском, а во-вторых, не афишируются в отечественных конторах типа НПП, КБ, и пр. Поэтому есть явная нехватка информации. Я попробую ее восполнить.

Чем отличаются доки для продуктов Yandex, Google, Microsoft, Apple, от old-school документации, созданной инженерами-конструкторами?

Классический инженер пишет так, чтобы продукт был описан максимально полно и правильно + в соответствии с ГОСТами и принятой терминологией. Причем многие термины и определения в ГОСТах устарели и совсем не красят документы. Но это не проблема для конструкторов никто и не думает, легко ли пользователю понять текст. А вот доки, сделанные для людей, отличаются: они написаны понятным языком и учитывают интересы пользователя. Вопрос приоритетов.

Эти приоритеты и цели автора очень влияют на то, какие получаются документы. Давайте на примерах посмотрим, как это выглядит в жизни:

Конструкторский подход User-oriented

Простота терминов
Щелчком ЛКМ манипулятора типа мышь нажмите на значок папки.
Щелкните по значку папки.
Квалификация читателя

Если писать по ГОСТам 20-го века, то нужно объяснять даже такие элементарные операции, как копирование. Потому что раньше это было непонятно.
Читатель знает, как пользоваться компьютером, и документы не объясняют элементарных вещей.
Подробность
Щелчком ПКМ нажмите на значок файла на рабочем столе. В открывшемся меню выберите Копировать. Затем в проводнике откройте папку, в которую вы хотите скопировать файл. Щелчком ПКМ откройте выпадающее меню и выберите Вставить.
Скопируйте файл в нужную папку.
Последовательность изложения Последовательное изложение от и до, без прикрас. Пользователь должен прочитать ВСЁ. Потом он должен сам догадаться, что ему нужно, а что нет.
Пользователь не хочет читать ВСЁ, он хочет перемещаться по темам нелинейно. Поэтому изложение разделено на отдельные самостоятельные статьи, чтобы из них читатель сложил свой собственный сценарий.
Навигация
Есть только содержание. Все остальное чтение по порядку, никаких перемещений.
Всевозможные интерактивные ссылки: на разделы, на серию разделов в одном сценарии, и т.д. Пользователь хочет перемещаться по темам не линейно, а по своему сценарию.

Тип контента
Все вперемешку: тут тебе и теория, и немного примеров, и процедура, и таблица, чтобы понятнее было.
Котлеты отдельно, мухи отдельно. Есть топики только процедурные, есть только объясняющие. И между ними, конечно, связь через ссылки.
Хочешь понять и подумать сначала почитай матчасть. Хочешь сделать бери и делай по шагам. Это разные топики, потому что и цели у них разные.

Такое бывает, что ты смотришь на документы, а они уже морально устарели. Как будто читаешь инструкцию к трактору 1950-х годов. Нужно как-то сделать их более актуальными, но это кажется невозможным. На самом деле, возможно всё. В следующих статьях я разберу пошагово, как именно от огромного устаревшего комплекта документации перейти к легким, понятным, современным докам. Каждый из пунктов таблицы мы разберем в отдельной статье.

Спойлер
Легко не будет.
Подробнее..

Прочти меня код, который не выбесит соседа

16.03.2021 12:09:05 | Автор: admin


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

Я расскажу о подходах, которые мы используем в Яндекс.Такси для написания читаемого кода на C++, Python, JavaScript и других языках.

Обычный рабочий процесс


Допустим, вы работаете в компании, пишете код. Написали функцию, начинаете обкладывать её тестами и понимаете, что что-то глючит. Ну что ж, отлаживаем Оказывается, что плохо работает не ваш код, а функция sample от другого разработчика, которую вы используете.

Выглядит функция sample как-то так:

std::string sample(int d, std::string (*cb)(int, std::string)) {  // Getting new descriptors from d with a timeout  auto result = get(d, 1000);  if (result != -13) {    // Descriptor is fine, processing with non bulk options    auto data = process(result, true, false, true);    // Passing processing result to the callback    return cb(data.second.first, data.second.second);  }  // Notifying callback on error  return cb(result, {});}

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

Нам повезёт, мы сможем исправить функцию, не разобравшись до конца в её работе.
Начинаем читать первый комментарий, где написано: получаем какие-то новые дескрипторы из d с заданным timeout, d дескриптор. То есть часть разбросанных по коду int на самом деле не int они относятся к отдельному классу данных.

Решаем заменить часть int на отдельный тип данных Descriptor в надежде, что компилятор сам найдёт ошибки и нам не придётся дальше отлаживать код. Зовём автора кода, просим его подсказать, где дескрипторы, а где числа. Он сейчас работает над другим проектом, но после долгих уговоров неохотно помогает и быстро ретируется:

enum class Descriptor : int {};std::string sample(Descriptor d, std::string (*cb)(Descriptor, std::string)) {  // Getting new descriptors from d with a timeout  auto result = get(d, 1000);  if (result != Descriptor(-13)) {    // Descriptor is fine, processing with non bulk options    auto data = process(result, true, false, true);  // <== ERROR    // Passing processing result to the callback    return cb(data.second.first, data.second.second);  // <== ERROR  }  // Notifying callback on error  return cb(result, {});}

И тут понеслось:

  • Компилятор нашёл сразу две ошибки. Это очень подозрительно, может, мы не так типы расставили?
  • А что вообще такое data.second.first и data.second.second? В комментариях не написано.

Делать нечего, придётся прочитать весь код и комментарии, чтобы понять, как исправить ошибки.

Боль


Поначалу казалось, что много комментариев это хорошо. Однако при отладке всё выглядит иначе. Код написан на двух языках: на английском и C++. Когда мы пытаемся понять, что происходит в коде, и отладить его, нужно прочитать английский, перевести его в голове на русский. Затем прочитать код на C++, его тоже перевести в голове на русский и сравнить эти два перевода. Убедиться, что смысл комментария совпадает с тем, что написано в коде, а если код делает что-то другое, то, возможно, там и кроется ошибка.

Ещё неприятно, что по коду разбросаны волшебные константы. Вот, например, -13 что это такое? Почему -13? Комментарии не помогают. Волшебные константы только смущают и делают разбор функции сложнее. Но это цветочки, сейчас пойдут ягодки.

Попробуйте угадать, что значат булевые флажки true, false, true в функции process? В комментариях о них ни слова. Чтобы разобраться, нужно пойти в header file, где объявлена функция process:

std::pair<Descriptor, std::pair<int, std::string>> process(bool, Descriptor, bool, bool);

И там мы увидим, что у булевых переменных нет осмысленных имён.

Чтобы понять, что происходит, нужно перейти в соседний файл, прочитать код функции process и разобраться в нём. Возможно, походить по соседним функциям и почитать их. На исследование смежных файлов тратится уйма времени, что мешает осознанию функции sample и портит настроение.

Наконец, data.second.first и data.second.second. Чтобы выяснить их назначение, нужно отмотать назад туда, где мы получаем переменную data. Пойти в место, где объявлена функция process, увидеть, что комментариев нет, а process возвращает пару от пары. Пойти в исходники, узнать, что обозначают переменные int и string, и на всё это снова уходит очень много нашего времени.

Ещё одна маленькая боль код обработки ошибок перемешан с основной логикой. Это мешает ориентироваться. Обработка ошибок функции sample находится внизу, а в середине, внутри цикла if, с большими отступами находится happy path.

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

Выжимка проблем


  • Код написан на двух языках:
    Его в два раза больше.
    При отладке возникают проблемы со сверкой двух языков.

  • Комментариев всё ещё недостаточно:
    Приходится читать код смежных функций.
    Есть магические константы.

  • Код обработки ошибок и основной логики перемешаны:
    Большие блоки кода с большими отступами.

Читаемый код


Перепишем sample. Постараемся сделать её настолько хорошей, чтобы всё было понятно из кода самой функции, без необходимости залезать в соседние файлы, читать документацию или комментарии.

Поехали:

std::string Sample(Descriptor listener,                              std::string (*cb)(Descriptor, std::string)){  UASSERT_MSG(cb, "Callback must be a non-zero function pointer");  const auto new_descriptor = Accept(listener, kAcceptTimeout);  if (new_descriptor == kBadDescriptor) {    return cb(kBadDescriptor, {});  }  auto data = Process(Options::kSync, new_descriptor);  return cb(data.descriptor, data.payload);}

В первой же строчке проверяем входные параметры. Это мини-подсказка/документация по тому, какие данные ожидаются на входе функции.

Следующая правка: вместо функции с непонятным именем Get появляется Accept, широко известная в кругах сетевых программистов. Затем страшную константу 1000 превращаем в именованную константу с осмысленным читаемым именем.

Теперь строка прекрасно читается без дополнительных комментариев: из listener мы принимаем новый дескриптор, на эту операцию даётся kAcceptTimeout.

Вместо того, чтобы писать в коде -13, а потом удивляться, что это за страшное число, заводим именованную константу для плохого дескриптора. Теперь мы сразу видим, что получили новый дескриптор, и проверяем, плохой он или хороший.

Обработка ошибок также происходит сразу. Получили значение тут же проверяем его на невалидность. За счёт этого вложенность становится меньше, код становится чуть компактнее.

Специфика C++
Маленький бонус большинство компиляторов в C++ считают одиночные if без блока else холодным путём.

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

В итоге мы незначительно (а то и вовсе незаметно) ускорили приложение. Пустячок, но приятно.

Дальше. Функция process преобразовалась. Вместо true, false, true теперь есть перечисление возможных опций для process. Код можно прочитать глазами. Сразу видно, что из дескриптора мы процессим какие-то данные в синхронном режиме и получаем их в переменную data.

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

В результате код стал почти в два раза короче. Он стал понятнее. Больше не нужно ходить в соседние функции и файлы. Читать такой код куда приятнее.

Приёмы


Может показаться, что создание понятного кода требует больших стараний, каких-то трюков, особых хитростей и огромных временных затрат на причёсывание написанного.

На самом деле нет. Есть небольшой набор приёмов, и если их придерживаться, код уже будет получаться достаточно хорошим и читаемым. Расскажу о некоторых из них.

1) Compute(payload, 1023) нечитаемо. Что такое 1023?
Используйте именованные константы.
Compute(payload, kComputeTimeout)

Альтернативным решением может быть явное использование имён параметров. Например, Python позволяет писать:

Compute(payload=payload, timeout=1023);

Ну и C++20 не отстаёт:

Compute({.payload=payload, .timeout=1023});

Идеальный результат получается, если пользоваться сразу двумя приёмами:

Compute(payload=payload, timeout=MAX_TEST_RUN_TIME);

2) Compute(payload, false) нечитаемо. Что такое false?
Используйте перечисления или именованные константы вместо bool.
У bool не всегда понятна семантика. Введение перечисления даже из двух значений явно описывает смысл конструкции.

Compute(payload, Device::kGPU)

Именованные аргументы в этом месте не всегда спасают:

Compute(payload=payload, is_cpu=False);

Всё ещё непонятно, что False заставляет считать на GPU.

3) Compute(data.second.first, data.second.second) или Compute(data[1][0], data[1][1]) что вообще тут происходит?
Используйте типы с информативными именами полей, избегайте кортежей.
Compute(data.node_id, data.chunk_id)

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

Попробуйте угадать, какой смысл у возвращаемых int и std::string в коде.

std::tuple<int, std::string> Receive();

int это дескриптор устройства? Код возврата?

А вот так всё становится кристально ясно:

struct Response {    int pending_bytes;    std::string payload;};Response Receive();

4) void Accept(int , int); что это за два числа?
Заводите отдельные типы данных для разных по смыслу вещей.
void Accept(Descriptor, std::chrono::milliseconds)

Или для Python:

def Accept(listener: Descriptor, timeout: datetime.timedelta) -> None:

На самом деле это совет не столько про читаемость кода, сколько про отлов ошибок. Многие (но далеко не все) современные языки программирования позволяют статически проверять типы и узнавать об ошибках ещё до запуска приложения или тестов. В C++ эта функциональность доступна из коробки, в Python нужно пользоваться линтерами и typing.

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

5) void Compute(Data data) функция есть в модуле или заголовке, но должны ли мы ей пользоваться?
Используйте особый namespace или именование для служебных вещей.
namespace detail { void Compute(Data data); }

Или для Python:

def _compute(data: Data) -> None:

С namespace detail/impl или с особым наименованием пользователь поймёт, что функцию использовать не нужно.

6) d, cb, mut, Get что это?
Придумывайте информативные имена переменных, классов и функций.
descriptor, callback, mutator, GetDestination

Самый избитый, но важный совет давайте осмысленные и информативные имена переменным, функциям и классам.

Кажется, что писать код, в котором переменные короче, получается быстрее. Под каждую переменную пара символов, можно быстро всё это напечатать. Но простая истина гласит: Мы пишем код один раз, а читаем несколько раз. Потом, возможно, переписываем и снова несколько раз читаем.

Так вот, через неделю или месяц будет сложно вспомнить, что такое d или cd, что делает метод Get (или это вообще класс Get?). Что он возвращает?

Информативные имена вам очень помогут. При чтении будет сразу видно, где descriptor, callback и mutator, а где функция под именем GetDestination() возвращает какой-то Destination.

7) connection = address.Connect(timeout) отладчик завёл нас в эту строчку кода. Что там за переменные, откуда они и куда мы их присваиваем?
Закрепите разные стили за переменными класса, аргументами функций и константами.
Если закрепить отдельные стили за разными типами переменных, код читается лучше. В большинстве распространённых code style именно так и делают:

connection_ = address.Connect(kTimeout);

Мы сразу видим, что переменная address локальная, что мы пытаемся соединиться с kTimeout, который является константой. Результат соединения присваиваем переменной класса connection_. Поменяли буквально пару символов, а код стал понятнее.

Для Python стоит дополнительно придерживаться правила, что приватные поля начинаются с нижнего подчёркивания:

self._connection = address.Connect(TIMEOUT);

8) connection_ = address.Connect(timeout / attempts) есть ли тут ошибка?
Используйте assert, чтобы проверить, правильно ли используют ваш код.
Если количество attempts будет равно нулю, то нативное приложение, скорее всего, рухнет. Где-то возникнет stack trace или корка. С помощью дополнительных телодвижений можно добраться до stack trace и понять, что падение произошло именно в этой строчке.

Если attempts окажется отрицательным числом, оно будет передано внутрь функции Connect. В лучшем случае внутри будет проверка тогда мы сможем диагностировать проблему, вернувшись на пару шагов назад.

Однако если внутри Connect не будет проверки, всё станет сильно-сильно сложнее. Приложение не упадёт, но будет работать неправильно, не так, как мы ожидаем.

Коду явно не хватает проверок:

ASSERT(attempts > 0);

assert timeout > 0

Теперь ошибка будет сразу обнаружена, и разработчик легко определит неправильное использование.

Assert не только позволяет быстро находить ошибки, но и добавляет читаемости. Выражение assert timeout > 0 прямо говорит, что код ниже будет работать неправильно с отрицательными числами и 0.

8.1) connection_ = address.Connect(timeout / attempts) есть ли тут ошибка?
НЕ используйте assert для проверки пользовательского ввода.
Будет невежливо (и опасно!), если ваша библиотека уронит весь сервер потому, что кто-то на сайте ввёл неправильное число. Здесь стоит использовать другие механизмы для сообщения об ошибках:

if (attempts <= 0) throw NegativeAttempts();

if (attempts <= 0) raise NegativeAttempts();

Как отличить неправильное использование функции программистом от неправильного ввода?

Вот несколько примеров:

  • функция init() должна быть вызвана перед первым использованием функции foo() assert,
  • мьютекс не должен дважды захватываться из одного и того же потока assert,
  • баланс на карте должен быть положительным НЕ assert,
  • стоимость поездки не должна превышать миллиона доллларов НЕ assert.

Если не уверены не используйте assert.

Ещё один хороший приём использовать в отладочных сборках assert, а в релизе другой механизм информирования об ошибках. Пример с attempts идеально ложится на этот случай:

ASSERT(attempts > 0);if (attempts <= 0) throw NegativeAttempts();

9) v = foo(); bar(v); baz(v); assert(v); а функциям bar() и baz() точно хорошо?
Не тяните с обработкой ошибок, не несите их в блок else.
Как только получили значение сразу проверяйте и обрабатывайте ошибки, а дальше работайте как ни в чём не бывало.

Такой подход поможет избежать излишней вложенности конструкций за вашей мыслью будет проще следить.

Пример:

if (value != BAD) {    auto a = foo(value);    auto b = bar(value);    if (a + b < 0) {         return a * b;    } else {         return a / b + baz();    }}return 0;

Сравните:

if (value == BAD) {    return 0;}auto a = foo(value);auto b = bar(value);if (a + b < 0) {     return a * b;}return a / b + baz();

10) [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]
Придерживайтесь вменяемой вложенности конструкций.
Если в вашем коде есть if, внутри которого for, внутри которого if, внутри которого while, это сложно читать. Стоит разнести какие-то внутренности на отдельные функции и дать функциям осмысленные имена. Так код станет красивее и приятнее для чтения.

11) Самая важная часть, самая большая хитрость, о которой мало где написано!
Если вам хочется поставить комментарий...
Попробуйте переделать код так, чтобы не хотелось.

Как правило, если у вас получается, код становится проще воспринимать. Если нет ничего страшного, бывает, ставьте комментарий. Иногда без этого не обойтись.

Вместо заключения


Разумеется, это общие советы. У каждого языка есть своя специфика. В C++ важно писать понятные имена шаблонных параметров, в Python не стоит злоупотреблять тем, что переменные предоставляют возможности для общего модифицирующего владения.

Даже в рамках одной компании практики могут расходиться (например, в userver у нас пожёстче с наименованями и bool).

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

Какие навыки можно прокачать на проекте c большой кодовой базой

07.08.2020 18:11:02 | Автор: admin


Как жить и развиваться на проектах с историей. Что дает разработчику опыт работы c большой кодовой базой, и почему не нужно стремиться переписать все с нуля, если даже если очень хочется.


Содержание



  1. Для кого этот текст
  2. Чему вы можете научиться на проекте с историей
  3. Какие вопросы задавать на собеседовании
  4. Советы тем, кто только начал работу с легаси-проектом
  5. Кратко


Я Павел Новиков, участвую в разработке мобильных приложений МойОфис Документы и МойОфис Почта. Это приложение для совместной работы с документами и почтовый клиент, которые начали создаваться в 2013 году, поэтому можно их назвать проектами с большой кодовой базой, где есть место и легаси в том числе.

Описанный тут опыт применим не только к работе над мобильными приложениями и масштабируется на разработку приложений вообще.

Disclaimer для самых маленьких


В этой статье я собрал размышления о своей работе на основе того опыта, который у меня есть на сегодняшний день. Любые статьи подобного рода всегда являются крайне субъективными. Я уверен, что существуют люди с опытом, который противоречит моим наблюдениям. Буду рад обсудить эти расхождения в комментариях.

Для кого этот текст


Текст рассчитан как на тех, кто причисляет себя к уровню Junior, так и на тех, кто попадает под категорию Midde/Senior.
В работе с долгоживущими проектами можно многому научиться на любом из уровней разработки. Чтобы быть на одной волне в понимании уровней, прочитайте посты Вастрика: Войти вайти и К Команда. Мне нравится его классификация уровней разработчиков, и я буду ее придерживаться в дальнейшем.
В следующем блоке разберем кратко, в чем польза для развития каждого из уровней на долгих проектах.

Junior


Задача Junior разработчиков максимальное развитие технических навыков. В ход идет все: языки, фреймворки, библиотеки, подходы к разработке и т.д. На любом проекте с сильной командой вы сможете учиться решать разные задачи.

Но на зрелых проектах у вас, во-первых, будет возможность более глубоко погружаться в какую-либо область и, во-вторых, вы сможете изучать примеры удачных и неудачных решений. Обучение на чужих ошибках дорогого стоит. Особенно если рядом есть более опытные коллеги, которые могут вам подробно объяснить смысл этих ошибок и как их можно избежать.

Middle


Задача Middle разработчика повышение своей автономности. Вы должны стать членом команды, которому можно доверить практически любую задачу на проекте. Это значит, что чем более разнообразные задачи есть на проекте, тем больше у вас потенциальных направлений роста.

Senior


Задача Senior разработчика полное осознание, что вам платят не за код, а за решение проблем. Иногда (пока все таки чаще) через написание кода, иногда через управление другими разработчиками, иногда через общение с не-разработчиками. Зрелые проекты просто кладезь задач, которые можно и нужно решить.

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

Причем тут легаси?


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

Майкл Фезерс (Michael Feathers), основатель R7K Research & Conveyance, утверждает, что легаси код это код, не покрытый тестами. Преимущество такого подхода в том что, с первого взгляда, он претендует на объективность. Но в реальности могут быть два сценария:

  • Тесты есть, но написаны плохо: запутанные, хрупкие, неочевидно структурированные.
  • Тестов нет, но код очень хорошо спроектирован. Это дает возможность относительно безопасно его менять и, в случае чего позволит быстро написать к нему тесты в будущем.


Еще один взгляд на то, что такое легаси от разработчика Дро Хелпера (Dror Helper): No longer engineered continuedly patched and hacked (Легаси-код код код, который постоянно ломают и подпирают костылями вместо того, чтобы его развивать).

Веб-разработчик Николас Карло (Nicolas Carlo) считает, что легаси код это код, с которым некомфортно работать.

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

Еще одна относительно объективная характеристика для оценки легаси ответ на вопрос есть ли в проекте какие-то неподдерживаемые зависимости. Код может собираться только какими-то конкретными устаревшими версиями компилятора. Или авторы самостоятельно пропатчили какую-то внешнюю библиотеку, и она теперь стала частью основного проекта. В этом случае, действительно, проект становится специфическим, и для его поддержки нужны дополнительные усилия.

В общем, если проекту больше полугода, то скорее всего в нем будет легаси.

Чему вы можете научиться на проекте с историей?





Итак, вы приняли решение и устроились в компанию, где до вас уже писался код и происходило еще много чего. Добавлю, что вам необязательно идти в новое место, чтобы прокачивать свои профскилы. Легаси скорее всего, есть в каждом проекте, надо лишь знать, как его оценить. И то, о чем я рассказываю, наверняка можно применить к тем вещам, над которыми вы работаете сейчас.

В каких областях прокачка будет полезна одинаково и вам, и проекту? Тут нужно понимать, что ситуация, когда вы развиваетесь там, где болит у проекта это идеальная среда для обоюдного роста. Потому что если вы будете развиваться в работе над какими-то левыми вещами, то это может быть плюсом лично для вас, но при этом будет сложно объяснять, зачем компании вам в этом помогать.

Анализировать проект


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

Самое главное, что могу посоветовать для углубления в тему анализа проекта прочесть книгу Эффективная работа с легаси-кодом Майкла Физерса. Она старая и известная. В ней описывается большое количество практик по работе с унаследованным кодом.

И еще один совет зайти на сайт Understand Legacy Code. Это блог, посвященный одной тематике работой с легаси. Важно, что там можно подписаться на рассылку. Уверен, многие Android-разработчики знают про рассылки Android Weekly и Kotlin Weekly. Рассылка ULC тоже очень полезна. Она не навязчивая, с практическими статьями про рефакторинг и написание кода.

Делать рефакторинг


Легаси-проекты это отличное место для того, чтобы качать навык рефакторинга. Вы приходите на проект, в котором скорее всего есть проблемы, и вам его нужно не только менять, но и улучшать, расширять и пилить новые фичи. От того, насколько хорошо и эффективно вы умеете рефакторить (быстро и с маленьким количеством регрессий), зависит то, насколько вы будете полезным и хорошим разработчиком.
В зрелом проекте со здоровой инженерной культурой рефакторинг должен быть постоянной частью разработки.
Вам должен нравиться продукт, над которым вы работаете. Совсем отлично, если вы сами можете им пользоваться. В этом случае случае у вас будет внутренняя мотивация долгосрочно работать над улучшением его качества.

Проектировать и создавать архитектуру


Этот пункт вытекает из предыдущего вам неизбежно нужно будет прокачиваться в проектировании ПО и архитектуре. При правильной культуре разработки у вас не будет необходимости принимать серьезные архитектурные решения в сжатые сроки. У вас будет время на проработку архитектуры и ваша ответственность будет в том, чтобы сделать это хорошо. Что я тут всегда советую? Читайте книги.

Я считаю книги не менее важными, чем другие источники информации. Чем больше опыта вы наберетесь из книг, тем больше и быстрее будете понимать, как решать типовые проблемы. К типовым/типичным проблемам всегда есть типичные решения, которые можно найти в книгах. Работа с любым видом легаси так же предполагает решение типовых проблем.

Книги по архитектуре

Роберт Мартин (Robert C Martin). Чистая архитектура, Чистый код
Мартин Фаулер (Martin Fowler). Рефакторинг. Улучшение проекта существующего кода


Инструменты
для проектирования архитектуры


UML используем для проектирования.
PlantUML (PUML) библиотека и сервис, которые позволяют в текстовом виде описывать UML-диаграмму. Его можно хранить в git, следовательно можете к процессу обновления и обсуждения этих диаграмм подключить те инструменты, которые используете для работы с обычным кодом.


Декомпозировать


Когда вы работаете с продуктом, который для вас не полностью понятен, вам, так или иначе, нужно будет научиться оценивать ту работу, которую предстоит сделать. И всегда у вас будет что-то, чего вы не знаете, какие-то подводные камни.
Умение разбить большую и сложную задачу на набор небольших взаимосвязанных частей очень ценный навык. Один из способов его развить состоит в постоянной ретроспективной работе над ошибками декомпозиции и оценки. В процессе анализа из часто встречающихся ошибок можно составить чек-лист. В дальнейшем он сможет помочь вам не допустить эти ошибки повторно.

Автоматизировать и уметь применять CI/CD


Вам нужно понимать, что происходит с вашим кодом от момента, когда вы его пишете, до момента, когда он достигает устройства пользователя. И у вас будет возможность автоматизацию и CI/CD настроить, поддерживать и улучшать. В компаниях, где нет выделенной инфраструктурной команды, эти операции могут и должны (я в этом убежден) решать члены основной команды разработки. Современные инструменты (cloud CI, Docker) не обладают невероятной сложностью, но очень сильно упрощают жизнь команды. Вы сможете принести ей много пользы, если овладеете этими навыками.

Общаться


Чем больше у вас будет ответственности, тем с большим количеством людей вам придется общаться. Разработка ПО давно перестала быть уделом одиночек: почти все крупные проекты делаются командами. Опять же, чем эффективнее вы научитесь взаимодействовать с окружающими, тем больше пользы сможете принести.

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

Я считаю, что развитие навыков общения можно свести к развитию чувства эмпатии. Чем лучше вы научитесь понимать мотивацию и цели окружающих людей, тем быстрее вы сможете стать полезными для них. Например, объясняя бизнесу пользу рефакторингов и работы над техническим долгом, вы должны использовать термины бизнеса, а не программиста. Очевидная, казалось бы, идея, но я неоднократно видел, как одни умные люди общаются с другими умными людьми и не могут друг друга понять.

Какие вопросы задавать на собеседовании





Здесь я буду отталкиваться от того, какие вопросы я бы задал, перед тем, как идти работать на проект, о котором мало знаю.

Как устроен рабочий процесс и почему именно так


Обычно сейчас работают по системам Scrum или Kanban. Но при этом часто адаптируют их под себя: взяли лучшее, ненужное выкинули. Вопрос: что именно они выкинули, а что оставили? Потому что в Scrum guide, на основе которого строится процесс разработки, есть довольно интересные и полезные практики.

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

Например, если команда работает по Scrum, я бы спросил, что обсуждали на последней ретроспективе. Насколько команда вообще активна на этой встрече? Решаются ли поднятые проблемы?

Другой интересный для меня вопрос по внутренним процессам: как в команде проводится code review? Есть ли какие-то внутренние правила проведения review, которые помогают сократить его время? Существует ли общая база знаний, в которую заносят результаты холиваров, чтобы не устраивать их каждый раз?

Как происходит планирование, кто участвует и насколько активна команда


Этот вопрос я бы задал, чтобы посмотреть, насколько сильна инженерная культура внутри команды. Бывает вариант, когда планирует только тимлид, а команда у него на подхвате.
Другой вариант это когда вся команда участвует в планировании. И когда приходит задача, ее берется расписать тот, у кого достаточно экспертизы в этом вопросе. А дальше все обсуждают и принимают решение. В этом случае команда получается более самоорганизованной, а рабочий процесс более приятным.

Сколько в команде людей, которые обладают всей картиной


Здесь возможны две крайности. Первая крайность это когда вы приходите в команду, которая работает над продуктом последние 2-4 года. Если при этом команда не сильно менялась, а только расширялась, то это очень хорошо, потому что у вас всегда будут люди, к которым вы сможете обратиться за помощью. Они смогут что-то подсказать, объяснить причину, рассказать вам историю проекта. Знать контекст и почему все устроено так, а не иначе очень важно.

Вторая крайность это когда вы приходите в команду, в которой нет никого из тех, кто был на старте. Например, проект был заморожен, его разморозили, и осталась большая кодовая база. С нуля переписывать нельзя. Соответственно, нужно восстанавливать разработку. То есть вы получаете проект, в котором заново нужно будет все раскапывать.

На основе этой информации вы сможете принять более взвешенное решение о том, хотите вы туда или нет, и, может быть, переоценить какие-то ваши требования к предложениям, на которые вам нужно ответить.

Как ведется бэклог технического долга


Проблемы есть в любом проекте, и важно понимать, как именно команда с ними работает. О работе с техническим долгом очень хорошо написал alexanderlebedev в статье Ланнистеры всегда платят свои долги! (и технические тоже).

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

Советы тем, кто только начал работу с легаси-проектом





Боритесь с соблазном броситься переписывать все с нуля


Обычная ситуация: вы начали работу над уже существующим приложением и видите, что там все сделано не так. И с этим не так вам нужно работать дальше. Вполне естественное желание в этом случае взять и переписать все это заново. Это нормальная реакция.

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

Если вы заметили, что вас посещают такие мысли, задайте себе несколько вопросов:
В коде точно есть достаточно проблем, или вы его просто пока не понимаете?
Вы уверены, что точно понимаете все точки интеграции переписываемого кода?
Вы достаточно хорошо знаете проект, чтобы верно спрогнозировать предстоящее время на работу?

Пока я убежден, что намерение сразу броситься все переписывать с нуля плохая идея. Улучшения должны быть итеративными и контролируемыми.
Однажды я стал свидетелем того, когда команда сказала, что Все фигня, давайте перепишем, переписывали полгода и не переписали. В итоге сложилась довольно интересная ситуация, когда проект нужно было опять лидить с нуля, набирать новую команду, потому что старая команда отвалилась. Старайтесь погасить это абсолютно естественное желание переделать все с нуля.

Прогнозируйте изменения проекта


Вам нужно научиться быть немножко оракулом. Работая с проектом долго, вы научитесь понимать его продуктовую составляющую, научитесь понимать бизнес, как этот проект зарабатывает, за счет чего он живет. Это даст возможность оценивать долгосрочную перспективу тех решений, которые вы принимаете.

Весьма полезный навык, потому что плоха ситуация, когда к вам приходит product owner и просит сделать что-то простое с его точки зрения. Например, добавить новый критерий для сортировки списка. А с вашей стороны это будет означать, что нужно весь этот компонент переписать заново. Этого не случилось бы, если бы вы заранее подумали, что разные способы сортировки того списка вполне логичная функция. Хотя ее и не просили сделать в первую очередь.

Только не нужно впадать в крайность и пытаться всегда делать как можно более универсальные решения. Это прямой путь к растягиванию сроков и проблемам с дальнейшей поддержкой таких решений. Весь смысл этого навыка как раз и состоит в поиске баланса.

Проводите исследования


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

Уделяйте время документации


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

Когда вы принимаете какое-либо архитектурное решение, вам оно кажется очевидным. Зачем его как-то пояснять? Через полгода-год в этом архитектурном решении возникают проблемы. И вы думаете: А почему я его принял? Какой был контекст?. Если вы научитесь записывать эти архитектурные решения, то это станет отличной инвестицией и сыграет вам на руку в будущем.

Одним из способов ведения таких записей является Architecture Decision Records. Его основная идея состоит в том, что для каждого нетривиального архитектурного решения нужно создать файл с несколькими элементами: заголовок, дата, контекст, описание решения, предполагаемые последствия. Этот файл хранится вместе с кодом и не меняется после создания. Его главная ценность в том, что когда придет время менять это архитектурное решение, будет гораздо проще понять мотивацию, которая к нему привела.

Кратко


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


Текст подготовлен по материалам моего доклада на митапе GDG.
Подробнее..

Представление модели предметной области (МПО) и точек интеграции

16.01.2021 14:23:21 | Автор: admin
Как известно, описание архитектуры состоит из множества представлений, для соответствующих точек зрения, интересов и заинтересованных сторон.

В этой статье я расскажу о способе создания представления (диаграммы) модели предметной области (МПО), дополненное связями с точками интеграции, на базе которых построена функциональность системы: хранимыми процедурами, функциями и веб-сервисами. Таким образом, данное представление хорошо подойдёт проектам с большим количество точек интеграциий и поможет разработчикам и аналитикам быстрее ориентироваться в проекте, порой даже не заходя в код.

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

Возможности, которые даёт такое представление:
диаграмма МПО позволяет быстро получить понимание о функциональности, которая существует в системе, какие сущности пристутствуют в системе и какие операции с ними можно выполнять;
связь сущностей МПО с точками интеграции ускоряет поиск нужного участка кода при модификации функционала. Понимая какую операцию и по какому объекту надо модифицировать, можно быстро найти точку интеграции, а отталкиваясь от неё проанализировать весь стек вызова;
удобно накапливать информацию о предметной области в простом наглядном стиле;

Вопросы, на которые отвечает такое представление:
какие сущности МПО существуют в системе?
как сущности МПО друг с другом связаны?
какие действия можно выполнять с сущностями МПО?
с помощью каких точек интеграции выполняются те или иные действия?

Представление сущности МПО



Представление строится на основе диаграммы классов. Для отображения сущности МПО используется класс. Сама сущность МПО представляет из себя абстракцию, которой может не существовать в реализации в описанном виде.

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

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

Методы бизнес-модели содержат все возможные действия, над данной моделью. Это могут быть CRUD и какие либо ещё возможные методы. Выделение метода зачастую ориентируется на точку интеграции, которая используется в данном методе. Есть смысл так же выносить производные методы, для понимания предметной области.

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

Точки интеграции это могут быть хранимые процедуры, функции или веб-сервисы. Описываются по формату %схема/веб-сервис%: хп/хф/метод веб сервиса. Стрелкой сояединяются с соответствующим методом.

image
Рисунок 1. МПО на примере одной сущности

Пример того, как описывается одна сущность МПО изображён на Рисунке 1.

Представление МПО



Итоговое представление МПО может выглядеть примерно как на рисунке. В примере я привёл значительно упрощённую модель. В реальной модели было в 10-15 раз больше сущностей с значительно большим количеством методов и точек интеграции. Однако даже с большими размерами МПО было достаточно просто ориентироваться. Свою роль сыграливозможностям Enterprise Architect и Visual Paradigm, однако в первую очередь помог логический поиск Функциональность->Сущность->Метод->Точка интеграции

image
Рисунок 2. Пример полного представления МПО.

На рисунке 2 изображён пример полного представления МПО. По этому рисунку уже можно сложить мнение о том, какая функциональность реализована в приложении.

Как представление МПО + точки интеграции может упростить разработку



Для наглядности я приложил диаграмму компонентов (Рисунок 3), распределённых по приложениям инфораструктуры проекта:
UIWebSite
MainOnlineBackendService
PCIDSSOnlineBankLogicService

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

image
Рисунок 3. Диаграмма компонентов.

Задача 1:
Допустим, что у нас стоит задача модифицировать функциональность открытия счёта и мы не знакомы с кодом проекта. В такой задаче может прийтись исследовать стэк вызова, а учитывая, что в каждом приложении существует свой набор компонентов, стэк вызова при клике на кнопку Открыть счёт может состоять из 8 уровней:
1 ReactUI
2 RestApiController
3 AccountCachedController
4 AccountServiceWrapper
5 MainOnlineBackendServiceImplementation
6 AccountServiceWrapper
7 OnlineBankLogicServiceImplementation
8 sheme1: sp_createAccount

Анализ сверху-вниз при помощи отладчика в такой ситуации может занять значительное время, так как на каждом слое, метод может содержать множество строк и ещё вложенные методы, которые будут либо возращать обратно либо вести к другим точкам интеграции. Поэтому чтобы найти точку интеграции (а именно она выполняет действие), нужно будет прошарить отладчиком почти все строки стэка вызова.

В случае, если мы используем диарамму МПО, то по соответствующему действию можно получить название хранимой фукнции, а через неё, с помощью глобального поиска по проекту, найти нужный участок кода и поставить на ней точку останова. Дальше остаётся только вызвать эту точку и идти по стэку вызова снизу-вверх, что значительно проще.

Задача 2:
Допустим, что у нас стала возникать ошибка при выполнении какого-либо действия. Для проектов с множеством интеграций частой причиной ошибок является ошибки внешних систем, например было выполнено обновление хранимой процедуры, отключение/недоступность веб-сервиса. На уровне пользователя такие ошибки совсем не очевидны и возникает ощущение, что проблема конкретно в системе, с которой работает пользователь. Чтобы локализовать ошибку чаще всего необходимо проанализировать стэк вызова.

В случае, если мы используем диаграмму МПО, то по действию, с которым происходит ошибка мы находим точку интеграции, ставим на неё точку останова и делаем вызов.
Если точку не поймали, то проблема лежит до вызова.
Если точку поймали, делаем вызов и смотрим прошёл ли вызов без ошибок. Очень часто на этом этапе находятся все ответы.
Если точку поймали и действие выполнилось, тогда идём по стэку снизу-вверх, пока не найдём ошибку.

Это две типовые распространённые задачи, при которых требуется находить точки интеграции.

Задача 3:
Другое множество, где диаграмма была полезна это различные вопросы:
какая внешняя система отвечает за ту или иную функциональность
какая точка интеграции используется для выполнения того или иного действия
где получить номер карты по её Id
кто отвечает за функционаность со стороны другой системы

Задача 4:
Вы исследуете систему и вам необходимо накапливать информацию о всех понятиях и функционале системы. Диаграмма помогает это выполнять в достаточно локаничном виде. В дальнейшем такая декомпозиция/композиция позволяет спроектировать архитектурные слои
Подробнее..

АнтиBIMing

22.05.2021 20:11:20 | Автор: admin
image
Сама по себе автоматизация лишь инструмент и как каждый инструмент у нее есть своя область применения, своя техника безопасности внедрения и применения, а так же свои преимущества и негатив. Традиционно бизнес стремится внедряться IT-разработки там, где существуют достаточно высокая маржа, а значит проще получить прибыль и уменьшать издержки, однако существуют области в которых давно назрела необходимость что-нибудь внедрить с тем что бы упростить и тогда все сформируется. Речь о личном опыте решения таких задач при составлении исполнительной документации в строительстве.

Программа, в которой описываются основные понятия и определения встречающиеся в тексте
Состав ПСД. Приемо-сдаточная документация#1 делится на:
1. Разрешительная документация, включая ППР;
2. Исполнительная документация.

Вся структура приемо-сдаточной документации субподрядной организации по спецмонтажным работам будет выглядеть так:
Разрешительная документация#2 термин, используемый для обозначения документации, оформляемой в соответствии со статьями 45 51 Градостроительного кодекса РФ вплоть до получения разрешения на строительство (ст. 51 ГрКРФ), а также получение разрешения на ввод объекта в эксплуатацию (ст. 55 ГрКРФ).
Исполнительная документация (ИД)#2 представляет собой текстовые и графические материалы, отражающие фактическое исполнение проектных решений и фактическое положение объектов капитального строительства и их элементов в процессе строительства, реконструкции, капитального ремонта объектов капитального строительства по мере завершения определенных в проектной документации работ.

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

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

АОСР Акт освидетельствования скрытых работ. Некоторые работы после окончания строительства невозможно проверить. Это касается работ, проведенных внутри строительных конструкций и коммуникаций, например:
установки арматуры в бетонных стенах,
грунтования поверхности перед окрашиванием,
толщины песочной подложки под брусчаткой,
укладки труб перед засыпанием грунтом,
гидро, звуко-, теплоизоляции и т.п.

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

Действие Первое. В котором рассказывается про предпосылки для автоматизации и проблемные рутины в Строительстве

Ты что делаешь?
Анекдоты читаю.
А отчет?
Час назад уже у тебя на столе лежит.
Погоди, тогда почему твой предшественник на его подготовку тратил три часа?
Послушай, я тоже могу тратить три часа на его подготовку. Если хочешь, я могу читать анекдоты в столовой. Но результат будет тот же.
Структура договорных отношений между участниками строительства #1
Обычно Инвестор нанимает организацию, занимающуюся управлением строительства, она может называться заказчиком. Этот заказчик нанимает проектный институт (лицо, осуществляющее подготовку проектной документации), чтобы тот ему нарисовал проект, бывает, так же нанимает генпроектировщика, а тот нанимает субчиков. Потом играют в тендер (кстати, то же самое может быть и с институтом) и выбирают генподрядчика это ответственный за строительную площадку (лицо, осуществляющее строительство) и заключает с ним договор. Для заказчика существует только генподрядчик (подрядчик) так как им так легче и удобней работать. Генподрядчик уже без тендера выбирает себе субподрядчиков (лицо, выполняющее работы), обычно по видам работ и заключает с ними договора. Субподрядчик или даже сам генподрядчик так же часто себе набирает субчиков, но уже не официально как бы под своим флагом. Заказчик нанимает технический надзор или сам может выполнять данную функцию (представитель заказчика или технический надзор заказчика). Если объект подпадает под государственный строительный надзор (ГСН), то и следит за всем этим он в виде инспекторов, их уведомляет заказчик о начале строительства, те приезжают со своей инспекцией, пишут замечания и уезжают. Все отношения регулируются договорами и действующим законодательством.

Строительство ведется по рабочим чертежам (заверенных печатью В производство работ) теми материалами и оборудованием, что договорились, их может поставлять как заказчик с генподрядчиком, так и субподрядчик. Строительство ведется в определенные сроки по графику. Каждый месяц Заказчик платит Подярдчику, а Позрядчик Субподрядчику и т.д. по цепочке, за построенные объемы работ денежку, из которой в т.ч. платится зарплата, а представители Подрядчика/Судподрядчика отчитываются за материалы и оборудование, которые были переданы (все это обговорено в договоре). Проверяет объемы и качество выполненных работ технический надзор, авторский надзор так же может следить за соответствием выполняемых работ по проекту и рассматривает возможность изменений в проекте (если с институтом был подписан на это договор и на опасном производственном объекте он должен быть по любому).

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

По окончанию строительства назначается рабочая комиссия обычно из всех представителей, все проверяют и, если все хорошо, через десять дней приемочная комиссия (обычно из тех же представителей) принимает объект. Раньше была еще государственная приемочная комиссия, но сейчас такая происходит только на бюджетных стройках.

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


Согласно Википедии
BIM (англ. Building Information Model или Modeling) информационная модель (или моделирование) зданий и сооружений, под которыми в широком смысле понимают любые объекты инфраструктуры, например инженерные сети (водные, газовые, электрические, канализационные, коммуникационные), дороги, железные дороги, мосты, порты и тоннели и т. д.

Информационное моделирование здания это подход к возведению, оснащению, эксплуатации и ремонту (а также сносу) здания (к управлению жизненным циклом объекта), который предполагает сбор и комплексную обработку в процессе проектирования всей архитектурно-конструкторской, технологической, экономической и иной информации о здании со всеми её взаимосвязями и зависимостями, когда здание и всё, что имеет к нему отношение, рассматриваются как единый объект.

Трёхмерная модель здания, либо другого строительного объекта, связанная с базой данных, в которой каждому элементу модели можно присвоить все необходимые атрибуты. Особенность такого подхода заключается в том, что строительный объект проектируется фактически как единое целое: изменение какого-либо из его параметров влечёт за собой автоматическое изменение связанных с ним параметров и объектов, вплоть до чертежей, визуализаций, спецификаций и календарного графика.

Что касается документации и информационной модели на стройке и откуда она там берется. Как правило Заказчик передает Подрядчику проект со штампом В производство работ на бумажном носителе (очень редко в формате pdf и почти никогда в dwg) для того что бы последний в соответствии с контрактом за оговоренную сумму произвел некоторые работы. Прораб/мастер/нач.участка заказывает через снабженцев (привет бухгалтерия и 1С) материалы согласно потребностям, проекту и графику производства работ, нанимается техника, она же ремонтируется, под нее покупается ГСМ и прочие расходы связанные с объектом, часть из которых связана с машинами и механизмами, часть с материалами которые будут монтироваться. Затем на объекте ведутся на бумажном носителе: журнал входного контроля, общий журнал работ и прочие специализированные журналы которые зависят от видов выполняемых работ. К концу каждого операционного цикла подготавливается исполнительная документация, которая представляет из себя акты и схемы выполненных работ (схемы по сути копируют проект, ибо отступление от проекта, без согласования с Заказчиком и контролирующими органами, недопустимо и будет означать лишь проблемы для Подрядчика). Такие акты и схемы на бумажном носителе подписываются представителями Подрядчика, Заказчика, контролирующих органов и организаций и только после того как пройдет успешная защита составляются финансовые акты (обычно по форме КС-2 и КС-3, но это не обязательно, достаточно к договору приложить свой шаблон), на основании которых в особо упоротых случаях бухгалтерия Заказчика может позволить списать материалы бухгалтерии Подрядчика (помимо актов выполненных работ составляются так же акты входного контроля и все вместе это передается Заказчику) в соответствии со сметными расценками.

Сегодня, в отличие от СССР, прораб/мастер/нач.участка не составляют исполнительную документацию. Это не означает что они не заполняют и не составляют бумаг, просто они другие, больше связаны с непосредственной организации управленческих процессов (открытие и закрытие нарядов, журналы инструктажа, выдачи заданий, заявки, письма и т.п.) объем бумаг достаточно большой и это нормальная (в том плане, что распространенная практика) брать в штат сотрудников с высшим (!) инженерным образованием инженеров ПТО, которые будут заниматься всей остальной документацией, а проще говоря исполнять работу технического секретаря. (На самом деле порог вхождения в процессию очень низок, т.к. базового школьного курса Черчения достаточно, что бы читать строительные чертежи и даже перерисовывать схемы, конечно потребуется навык работы с Word/Excel/Paint/AutoCAD/Компас, но это не так сложно как может показаться и потому такая специальность утилизирует людей как с профильным образованием, так и с гуманитарным менеджеров/юристов/учителей и т.д. и т.п.)

Как правило рабочее место, которое может быть и удалено (вагончик в поле), оборудовано МФУ, Wi-Fi точкой, раздающей 3G интернет, ноутбуком. В отсутствие сис.админа все это работает в меру сил и понимания инженера ПТО, который за все это отвечает, который выполняет не только прямые обязанности, но и те от которых не удалось отбрыкаться по разным причинам. Надо ли говорить, что общая техническая грамотность страдает. Обычно на ноутбуки установлен, хорошо если заботливо, Windows, MS Office, редактор для векторной графики, GIMP, программа оптического распознавания текстов. Такой скудный выбор связан с тем, что з/п и оснащение такого инженера находится в составе Накладных Расходов, а не в статьях Общей Заработной Платы, как в случае, например, рабочих, т.е. разные статьи расценок сметы.

Действие Второе. В котором рассказывается про предпосылки для автоматизации и проблемные рутины в Строительстве

Исаак Ньютон:
От флюенции возьму флюксию и обратно.
Лейбниц:
Могу делать то же самое!

Идея создания Программы родилась спонтанно, после 3-х закрытых объектов в 2016году ПАО Транснефть. Помимо сбора и компоновки информации большой блок времени отнимали задачи, связанные с банальным заполнением документов по шаблону, среди которых преобладали Акты входного контроля и Акты освидетельствования скрытых работ. Особенно много времени уходило на проверки в случае описок или различного рода неточностей. Т.к. если они выявлялись, то приходилось заново открывать и проверять такие акты. Иногда, как в ситуации в 2018году, когда Ростехнадзор поменял форму актов скрытых работ, их счет шел на десятки. Но так родилась идея: А что, если я соберу все данные, необходимые для заполнения актов, в таблицу, а уже Программа будет прописывать их в шаблоны за меня?.

Самой простой и пригодной из доступных для этого является MS Office с макросами VBA. Учитывая тот факт, что в 90-е годы я в школе ударно изучал QBasic 4.5 и Borland Pascal 7.0, то выбор платформы оказался более чем очевиден. Пробелы в синтаксисе помог закрыть Гугл. Сама Идея не нова, но в 2016-м году в открытом доступе, так сказать в open source, я нашел только один вариант через Слияние, который тогда, в далеком 2016-м году меня не устроил. И вот я начал разрабатывать свой велосипед:

1. Самое главное и без чего не имело все дальнейшее смысл это без наглядности и удобства в работе. Поэтому для варианта с экспортом в Excel был выбран путь перебора текста в ячейках с целью поиска комбинаций текстовых маркеров, которые априори не встречаются в русскоязычных регламентных формах актов, с последующей авто подстановкой значений из таблицы. (Например, f1, d3, b8 и т.д. и т.п.) Для того что бы не пришлось перебирать всю матрицу я ввел упрощение, при создании шаблона если в первой ячейке за областью печати располагается символ арабской единицы, то только в этом случае макрос ищет текст во всех ячейках этой строки. Позднее я решил вопрос как получить в макрос диапазон ячеек, отправляемых на печать.

В случае с экспортом в World тут все гораздо проще Закладки и ссылки на содержимое закладок, при повторном упоминании содержимого в тексте.

2. В отличие от многих конкурентов с более проработанными приложениями я пошел дорогой структурирования информации (привет BIM) и наглядного представления данных, а потому, не смотря на то что тот же Access, Visual Studio, 1С и т.п. предоставляет большие возможности и функционал все эти программы грешат тем, что в них нельзя протянуть строку или столбец с одинаковыми данными, а переключение между полями ввода требует большей точности при позиционировании (выбор поля через TAB или позиционирование курсора с кликом проигрывает в удобстве перемещению стрелками по ячейкам таблицы, не говоря про то, что копировать ячейками проще, чем из через выделения текста из поля ввода)

Следующий шаг это формирование логики заполнения данных, т.е.:

А) Данные организаций и участников строительства, а также общие характеристики объекта;

Б) Данные для формирования Актов входного контроля, т.е. в первую очередь определяемся не с работами, а с материалами

В) Затем определяемся с месячно-суточным графиком, в котором делаем привязку не только к сметам (т.е. сперва вводим сметные расценки в Заголовки), а уже затем формируем перечень работ из ВР (Ведомости объемов работ по РД (Рабочей документации)), соблюдая очередность работ. Т.е. алгоритм после проставления в графике объемов работ сам определит, в рамках каждого отчетного периода, какие Акты скрытых работ и в какой последовательности под каким номером, от каких дат необходимо будет оформить. Пользователю останется лишь внести сопутствующую информацию, которая является больше рутиной. Кроме того, благодаря связям Пользователь может видеть сколько материалов было списано по предыдущим Актам скрытых работ, что

уменьшает кол-во накладок и ошибок, связанных с проведенными материалами и использованными при строительстве (по сути это техническая ошибка, которой можно и нужно избегать).

И вот таким образом ПК/ноутбук превращаются из печатной машинки в помощника, который берет часть обязанностей на себя. Т.е. то, что часто многими упускается из виду при создании программ.

3. Но ведь регламентных форм актов сильно больше чем указанных мною выше 2-х шт., пусть они и представляют собой свыше 50% всех актов Исполнительной документации. Значит нужно создать, и это было сделано, аналогичную программу, которая могла бы заполнять таким же образом любой Пользовательский шаблон, а затем такие шаблоны можно было бы импортировать в основную программу, с тем что бы можно было увязывать текущие данные с новыми формами. А раз новые формы, то значит нужна и в меру удобная навигация. Все эти задачи были решены.

И вот теперь такая программа распространяется абсолютно безвозмездно, т.е. даром. Не смотря на долгий срок разработки одним человеком с длительными перерывами в нерабочее время с 2017-го года по 2021-й год, когда появились все эти Алтиусы, Адепты и прочий платный софт той же тематики я хочу сказать следующие слова критики:

1. Зачастую архитектурные ограничения методов ограничивают юзабилити пользователей. Потому что разработчик не является исполнителем, который в дальнейшем будет пользоваться этой программой, и не изучают технологические операции конкретной специальности, взамен формируя свои технологические-схемы работ с таким софтом, которые не всегда являются удобнее аналогов.

2. Пользователю, т.е. инженерам-ПТО, нужен такой продукт и помощь, который будет прост, удобен и понятен, а еще по совместительству предложит такую схему работы, ошибок при которой будет меньше, чем без нее и трудоемкость уменьшится.

3. Зачастую люди, которым нужна автоматизация, не могут за нее заплатить, т.к. их оклад не такой уж и большой, а в их опыте даже нет рабочих примеров, когда софт облегчал им рабочую рутины, да еще и уменьшал ИХ КОЛИЧЕСТВО ОШИБОК. В то время как цены на такие программы сравнимы со стоимостью Сметных-комплексов. Но без сметных комплексов очень трудно обойтись, а вот без автоматизации Исполнительной документации элементарно.

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

Действие третье. В котором рассказывается о том как кристаллизовалась программа


На стройке самое важное что? График производства работ и ключевые даты на нем (врезка, подключение, начало работ и окончание работ и некоторые другие). На участке ведется ОЖР, в котором записывается вручную что было выполнено за каждый конкретный рабочий день. Но если взять график (Месячно-суточный график) и заполнять его, то мы получим графическое представление, который и легче воспринимается и, затем, легче автоматизируется, служа исходными данными для актов и аналитики.

Рис.1 Пример Месячно-суточного графика

Теперь думаем дальше, если ввести только один раз и дальше расставить ссылки, на ответственных, описание объекта, контракта и организаций, участников строительства, то это зело упростит Работу. Ввел один раз и далее только развешиваешь ссылки.

Следующий Важный момент в строительстве это Материалы. Они должны соответствовать проекту и при их приемке осуществляется Входной контроль комиссией с оформлением бумаг (Акт входного контроля и Журнал Входного контроля). Это держим в уме. А дальше большая часть ИД в строительстве составляют Акты скрытых работ или полностью, Акт освидетельствования скрытых работ. Работы, их очередность и данные подтягиваем с Месячно-суточного графика, а материалы из перечня актов Входного контроля теперь еще и наглядно мониторить можно какие материалы в каком количестве списываются по актам АОСР.

А что если нам нужно иметь гибкость, что бы Пользователь добавлял свои формы актов, делал их вручную или использовал текущие? И это возможно, но обсудим мы это в

Действие четвертое. В котором речь пойдет о макросах VBA

Далее пойдут спойлеры с кодом, призванные решить те или иные вопросы/проблемы.
Немного ускоряем MS Excel при работе с макросами
'Ускоряем Excel путём отключения всего "тормозящего" Public Sub AccelerateExcel()   'Больше не обновляем страницы после каждого действия  Application.ScreenUpdating = False   'Расчёты переводим в ручной режим  Application.Calculation = xlCalculationManual   'Отключаем события  Application.EnableEvents = False   'Не отображаем границы ячеек  If Workbooks.Count Then      ActiveWorkbook.ActiveSheet.DisplayPageBreaks = False  End If   'Отключаем статусную строку  Application.DisplayStatusBar = False   'Отключаем сообщения Excel  Application.DisplayAlerts = False  End Sub

а теперь возвращаем настройки обратно
'Включаем всё то что выключили процедурой AccelerateExcelPublic Sub disAccelerateExcel()   'Включаем обновление экрана после каждого события  Application.ScreenUpdating = True   'Расчёты формул - снова в автоматическом режиме  Application.Calculation = xlCalculationAutomatic   'Включаем события  Application.EnableEvents = True   'Показываем границы ячеек  If Workbooks.Count Then      ActiveWorkbook.ActiveSheet.DisplayPageBreaks = True  End If   'Возвращаем статусную строку  Application.DisplayStatusBar = True   'Разрешаем сообшения Excel  Application.DisplayAlerts = True End Sub

Заполнение шаблонного файла в формате MS Excel
Здесь очень важна наглядность! Очень много проектов встали на абсолютных ссылках, по-этому я изначально решил сделать все универсально. После долгих мытарств я открыл для себя тот факт, что формулой можно получить диапазон ячеек, который будет выводится на печать.


Рис.2 Пример файла шаблона в формате MS Excel

Здесь в ячейке А1 содержится формула:
=СЦЕПИТЬ(АДРЕС(СТРОКА(Область_печати);СТОЛБЕЦ(Область_печати);1;1);":";АДРЕС(СТРОКА(Область_печати)+ЧСТРОК(Область_печати)-1;СТОЛБЕЦ(Область_печати)+ЧИСЛСТОЛБ(Область_печати)-1;1;1))
Т.е. мы можем получить область печати, обратившись к переменной, фигурирующей в диспетчере имен. Полученные абсолютные границы печати, которые будут автоматически меняться, если нам придется увеличить или уменьшить область печати. Зачем? Здесь следует сделать отступление.


Рис.3 Пример листа с хранящимися данными для автоматического заполнения актов.

Дело в том, что мною был выбран способ-маркеров в тексте, т.е. при составлении шаблона маркеры (a1, b0, c7, d8 и т.д. и т.п.) однозначно характеризуют с одной стороны строку, из которой будут браться данные (порядковый номер элемента массива, который автоматически завязан на номер строки), с другой стороны в русскоязычных шаблонах в строительстве абсурдное сочетание букв латиницы с цифрой не используется. А значит это наглядно. После чего обычный перебор текста решает, НО (!) чем больше ячеек в области печати, тем медленнее будет работать алгоритм. Значит ему надо помочь и подсветить только те строки, в которых априори что-то есть.
Код макроса VBA осуществляющий экспорт в шаблон в формате MS Excel
          With Workbooks.Open(ThisWorkbook.Path + "\Шаблоны аддонов\" + NameShablonPrimer, ReadOnly:=True)               .Sheets(NameShablonPrimerList).Visible = -1               .Sheets(NameShablonPrimerList).Copy after:=wb.Worksheets(Worksheets.Count)                              Let НачальныйНомерСтрокиВФайле = .Sheets(NameShablonPrimerList).Cells(1, 2)       ' Начальный номер строки в файле шаблона               Let НачальныйНомерСтолбцаВФайле = .Sheets(NameShablonPrimerList).Cells(1, 3)      ' Начальный номер столбца в файле шаблона               Let КонечныйНомерСтрокиВФайле = .Sheets(NameShablonPrimerList).Cells(1, 4)        ' Конечный номер строки в файле шаблона               Let КонечныйНомерСтолбцаВФайле = .Sheets(NameShablonPrimerList).Cells(1, 5)       ' Конечный номер столбца в файле шаблона                              .Close True          End With       End If    End If    Do       ИмяФайла = BDList + " "                                                                  ' Префикс имени файла       wb.Worksheets(NameShablonPrimerList).Copy after:=Worksheets(Worksheets.Count)       Set новыйЛист = wb.Worksheets(NameShablonPrimerList + " (2)")              For X = НачальныйНомерСтолбцаВФайле To КонечныйНомерСтолбцаВФайле Step 1                  ' Перебираем столбцы в листе Примера формы-шаблона           For Y = НачальныйНомерСтрокиВФайле To КонечныйНомерСтрокиВФайле Step 1                ' Перебираем строк в листе Примера формы-шаблона               If Sheets(новыйЛист.Name).Cells(Y, КонечныйНомерСтолбцаВФайле + 1) = 1 Then       ' При наличии спец символа проверяем на совпадении строку                  Let k = CStr(Sheets(новыйЛист.Name).Cells(Y, X))                               ' Ищем только если в ячейке что-то есть                  If k <> "" Then                     For i = 1 To Кол_воЭл_овМассиваДанных Step 1                         ContentString = CStr(Worksheets(BDList + " (2)").Cells(i + 1, НомерСтолбца))                         If Len(arrСсылкиДанных(i)) > 1 Then                            If ContentString = "-" Or ContentString = "0" Then ContentString = ""                            Let k = Replace(k, arrСсылкиДанных(i), ContentString)                         End If                     Next i                     новыйЛист.Cells(Y, X) = k                  End If               End If           Next Y       Next X                     For Y = НачальныйНомерСтрокиВФайле To КонечныйНомерСтрокиВФайле Step 1           Sheets(новыйЛист.Name).Cells(Y, КонечныйНомерСтолбцаВФайле + 1) = ""       Next Y            

Заполнение шаблонного файла в формате MS Word
вывода в шаблон формата Word, и здесь на самом деле есть 2 способа вывода текста:

1. Это через функционал закладок,
            Rem -= Открываем файл скопированного шаблона по новому пути и заполняем его=-            Set Wapp = CreateObject("word.Application"): Wapp.Visible = False            Set Wd = Wapp.Documents.Open(ИмяФайла)                        NameOfBookmark = arrСсылкиДанных(1)            ContentOfBookmark = Worksheets("Данные для проекта").Cells(3, 3)            On Error Resume Next            UpdateBookmarks Wd, NameOfBookmark, ContentOfBookmark            Dim ContentString As String            For i = 4 To Кол_воЭл_овМассиваДанных Step 1                If Len(arrСсылкиДанных(i)) > 1 Then                   NameOfBookmark = arrСсылкиДанных(i)                   ContentString = CStr(Worksheets("БД для АОСР (2)").Cells(i, НомерСтолбца))                   If ContentString = "-" Or ContentString = "0" Then ContentString = ""                   ContentOfBookmark = ContentString                   On Error Resume Next                   UpdateBookmarks Wd, NameOfBookmark, ContentOfBookmark                End If            Next i                         Rem -= Обновляем поля, что бы ссылки в документе Word так же обновились и приняли значение закладок, на которые ссылаются =-            Wd.Fields.Update                         Rem -= Сохраняем и закрываем файл =-            Wd.SaveAs Filename:=ИмяФайла, FileFormat:=wdFormatXMLDocument            Wd.Close False: Set Wd = Nothing

Sub UpdateBookmarks(ByRef Wd, ByVal NameOfBookmark As String, ByVal ContentOfBookmark As Variant)    On Error Resume Next    Dim oRng As Variant    Dim oBm    Set oBm = Wd.Bookmarks    Set oRng = oBm(NameOfBookmark).Range    oRng.Text = ContentOfBookmark    oBm.Add NameOfBookmark, oRngEnd Sub


2. Если рисовать таблицы средствами Word, то к ним можно обращаться с адресацией в ячейку
 Rem -= Заполняем данными таблицы ЖВК =-       Dim y, k As Integer       Let k = 1       For y = Worksheets("Титул").Cells(4, 4) To Worksheets("Титул").Cells(4, 5)           Wd.Tables(3).cell(k, 1).Range.Text = Worksheets("БД для входного контроля (2)").Cells(6, 4 + y)           Let k = k + 1       Next y       End With       


Между выводами в файлы форматов Word и Excel есть огромная пропасть, которая заключается в следующем:

Шаблон Excel требует перед использованием настроить отображение под конкретный принтер, т.к. фактическая область печати разнится от модели к модели. Так же перенос строки текста возможен, но только в пределах ячейки/объединенных ячеек. В последнем случае не будте автораздвигания строки, в случае переноса текста. Т.е. Вам вручную придется заранее определит границы области, которые будут содержать текст, который в свою очередь в них еще должен убраться. Зато Вы точно задали границы печати и выводимого текста и уверены, что не съедет информация (но не содержание) с одного листа на другой.

Шаблон Word при настройке автоматически переносит текст на последующую строку, если он не убрался по ширине ячейки/строки, однако этим самым он вызывает непрогнозируемый сдвиг текста по вертикали. Учитывая тот факт, что по требованиям к Исполнительной документации в строительстве ЗАПРЕЩЕНО один акт печатать на 2х и более листах, то это в свою очередь так же рождает проблемы.


С проектом можно ознакомиться тут:
vk.com/softpto
Все программы распространяются абсолютно бесплатно. Всем Добра! ;)
Подробнее..

Как заголовок и навигация в документации помогают минимизировать стресс пользователя

18.09.2020 16:04:09 | Автор: admin


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


Первый. Перед вами система и 5 минут на то, чтобы выполнить в ней необходимую процедуру. Первым делом вы ищете нужную кнопку или пункт меню, не находите и начинаете нервничать, ведь время идёт, а хочется быть эффективным в любой своей деятельности. Напряжение делает вас расфокусированным, в этом состоянии вы продолжаете искать и в какой-то момент понимаете, что не сможете сами разобраться. Обращаетесь в техподдержку: набираете номер, играет приятная музыка и отрешённый голос сообщает вам, что вы пятнадцатый в очереди, напряжение растёт. Через какое-то время отвечает сотрудник техподдержки, он объясняет вам, что надо делать. Вы успокаиваетесь и выполняете свою задачу.



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





Меня как пользователя больше бы устроил второй сценарий, в нём очень важную роль играет руководство пользователя. Но далеко не каждое руководство поможет вам быстро разобраться в чем-то, есть ряд требований, которым оно должно соответствовать.





В этой статье мы разберём требования, которые относятся к названию разделов в руководстве или названиям инструкций. Также мы обсудим, какой должна быть навигация в пользовательской документации.


Хочешь, чтобы никто не нашел, назови не думая


Название инструкции это не название статьи в интернете. Ему не надо привлекать внимание и вызывать какие-то эмоции. Пользователь по названию должен понять, какая процедура описана в инструкции. Инструкцию надо называть так, чтобы её было несложно найти в интернете. Давайте более подробно разберёмся с этим.


Название инструкции не должно вызывать эмоции

Я использую два вида названий:


  • название-проблема;
  • название-процесс.

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


Что такое название-процесс


Цель инструкции с таким названием объяснить какой-то процесс.


Пример ситуации: пользователю надо в чём-то разобраться, у него есть достаточное количество времени и более менее спокойное состояние. По факту, его задача понять как что-то работает. Для инструкции, которая будет решать такую задачу я использую название-процесс.


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


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


Пример названия-процесса: Работа с программой Рутокен Диск.


Ситуация, когда будут искать эту инструкцию: пользователь купил устройство Рутокен с программой Рутокен Диск и хочет разобраться, как сохранить файл в защищённой флеш-памяти.

Его поисковый запрос: как сохранить файл в защищённом разделе или как работать с Рутокен Диском.


Он открывает инструкцию, выбирает свою операционную систему и раздел с названием Работа с защищённым разделом. Такой поиск у него займёт несколько секунд. Дальше он выполнит все действия этой процедуры и поймёт процесс.





Ещё один пример названия-процесса: Работа с Рутокен через КриптоПро CSP в macOS.


Ситуация, когда будут искать эту инструкцию: пользователь купил Рутокен с сертификатом КриптоПро и ему надо, чтобы всё это заработало на макбуке.


Его поисковый запрос: Рутокен КриптоПро macOS.


Он открывает инструкцию и выполняет последовательно все шаги из неё.





Пример плохого названия инструкции: Инструкция по форматированию Рутокена и установке нового PIN-кода для клиентов, переходящих с системы ДБО.


Ситуация, когда будут искать эту инструкцию: пользователю необходимо отформатировать токен перед тем как использовать его в другой системе или ему просто надо сменить PIN-код.


Мне это название не нравится по трём причинам:


  • Оно слишком длинное.
  • В нём фигурирует две процедуры: форматирование токена и смена PIN-кода.
  • Название сформулировано не так, как его будет искать пользователь.

И получается, что его может найти не только пользователь, который хочет отформатировать токен, но и тот, кто хочет сменить PIN-код. Пользователь откроет эту инструкцию, начнёт форматировать токен, а это приведёт к тому, что удалятся все сертификаты, которые стоят денег. Он хотел просто сменить PIN-код, а это надо было сделать иначе. Также у пользователя мог быть изначально пустой токен, тогда форматировать его не надо. На этом примере мы видим, что плохое название инструкции может привести даже к финансовым потерям. Эта инструкция подошла бы только в том случае, если пользователю надо было отформатировать Рутокен.


Плохое название может привести к финансовым потерям

Сейчас по запросу как изменить PIN-код Рутокена пользователь найдёт нашу инструкцию.


Что такое название-проблема


Цель инструкции с таким названием помочь решить проблему.


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


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


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


Пример такого названия: Недоступна смарт-карта Рутокен.


Ситуация, когда будут искать эту инструкцию: пользователь подключает смарт-карту Рутокен, а она не работает в системе, и он хочет разобраться, почему она не работает и, что сделать, чтобы заработала.


Его поисковый запрос: токены или смарт-карты недоступны. Он описывает проблему так, как она сформулирована в окне с ошибкой.


Он находит эту инструкцию и выполняет необходимые действия в системе.


Второй пример названия, но теперь уже раздела: Что делать, если PIN-код Пользователя заблокирован.


Ситуация, когда будут искать эту инструкцию: пользователь ввёл несколько раз неправильный PIN-код, на экране отобразилось сообщение о том, что он заблокирован.


Самая эмоциональная реакция может возникнуть, когда с этим сталкиваются первый раз. Чаще всего пользователю кажется, что всё, доступ к Рутокену уже не вернуть, но это не так.


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


Он откроет эту инструкцию, найдёт нужный раздел и разблокирует PIN-код.


Пример плохого названия инструкции: Рутокен вставлен, но красный диод не горит. Что делать?


Что мне не нравится в этом названии:


  • Оно слишком длинное, в нём указаны лишние подробности, а именно то, что Рутокен вставлен. За счёт этого можно было сократить название.
  • Я бы заменила слово диод, не каждый пользователь его знает.


Давайте сделаем общие выводы:


  1. Прежде чем придумывать название для инструкции необходимо понять для кого эта инструкция и в какой ситуации пользователь будет её искать.
  2. При составлении названий используйте слова из мира пользователей.
  3. Подумайте о том, какой запрос пользователь введёт, когда будет искать инструкцию.
  4. Перед публикацией инструкции ещё раз прочитайте название и подумайте, может быть вы указали какие-то лишние подробности.


Хочешь, чтобы никто не нашёл, забудь про навигацию


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


Содержание как карта


Главное требования к содержанию инструкции оно должно быть логичным.
Цель содержания, как и у любой карты ускорить процесс поиска. Помочь пользователю быстро найти нужный раздел. Да, кто-то скажет, что в инструкции всегда можно воспользоваться внутренним поиском, нажав Ctrl+F, но это не всегда удобно. Если страниц в инструкции много, то внутренний поиск может только запутать пользователя.


Содержание должно быть логичным




Здесь тоже не обойтись без примеров. Давайте посмотрим на навигацию в одной из моих инструкций.


Самый простой случай, когда описана программа, которая работает в одной операционной системе. В нашем случае это программа Рутокен Логон. Посмотрим на то, как устроена навигация в инструкции для неё.





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


Простая последовательность изложения может выглядеть так:



Установка -> Запуск -> Настройка -> Процесс работы -> Удаление

В таком содержании пользователь просто находит нужный раздел и выполняет описанную в нём процедуру.


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


Ранее мы рассматривали инструкцию про Рутокен Диск, она как раз была с таким содержанием. В ней пользователь находит раздел со своей операционной системой и подраздел с необходимой процедурой.


Такая последовательность изложения выглядит так:



Выбор операционной системы -> Запуск -> Настройка -> Процесс работы -> Удаление

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


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


У пользователя полминуты на то, чтобы найти нужный раздел

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


Вот пример такой инструкции. Она написана для пользователей Рутокен U2F.





Здесь, если пользователь пропустит содержание, то он увидит в заголовке раздела название необходимого сервиса и уже внутри этого раздела найдёт необходимый подраздел, при этом в содержании названия этих подразделов тоже остаются, для тех кто всё-таки его читает.


Содержание может всё испортить


Есть случай, когда содержание может действительно всё испортить. Его проще всего описать так: если пользователь пропустит любой шаг, то ничего работать не будет. Дорожная карта нужна в том случае, если дорог много. Но когда дорога одна и надо двигаться по ней не пропуская ни одного пункта, карта не нужна. Пользователь просто выполняет все шаги один за другим. Да, у меня таких инструкций немало, и они чаще всего про настройку чего-либо. Чтобы минимизировать стресс пользователя, в начале такой инструкции я объясняю ему, что необходимо последовательно выполнить все шаги этой инструкции, тогда у него сформируется определённый настрой.





Последний пример в этой статье как раз будет про это. Инструкция о том, как удалить сертификат. В самом её начале я объясняю пользователю, что прежде чем удалить сертификат, надо определить криптопровайдера или формат сертификата и записать имя контейнера. Это важно, так как можно удалить не тот сертификат, а вернуть его будет уже невозможно.





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



Давайте сделаем общие выводы:


  1. При составлении содержания учитывайте логику взаимодействия пользователя с тем, что вы описываете.
  2. Если пользователь пропустил содержание, то ему может помочь навигация в разделе.
  3. Если пропускать шаги в инструкции нельзя, то навигация не нужна.


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

Подробнее..

Внешний вид и скриншоты в пользовательской документации. Как надо и не надо делать

26.10.2020 10:06:40 | Автор: admin


Люди читают пользовательскую документацию, когда самостоятельно не могут с чем-то разобраться. Они не делают это для развлечения. И эмоции, которые преобладают в этот момент, далеко не всегда позитивные. Как разработчик пользовательской документации может помочь пользователю? Что ему необходимо учитывать при написании документа?


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


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

И это далеко не весь список проблем. Но моя задача не в том, чтобы рассказать вам, как всё плохо. Моя задача рассказать, что можно учитывать при создании документа, чтобы он был эффективным. В своих прошлых статьях я затрагивала не менее важные темы, а именно, рассказывала о том: как лучше всего организовать процесс документирования в компании, как корректно называть документы и какой должна быть навигация в них. Это статья про то, как создать у пользователя хорошее впечатление о документе, как не испортить ему настроение и помочь быстро разобраться в проблеме. Здесь будет информация про внешний вид документа и скриншоты.


Внешний вид документа


Для меня внешний вид документа это дизайн и верстка. И нельзя сказать, что это не важно. Да, ваш документ может быть написан очень хорошо, но его внешний вид сразу может испортить впечатление. Внешний вид это про удобство и заботу о пользователе.



Основные принципы дизайна документа


Дизайн это то на что в первую очередь обращает внимание пользователь, когда открывает документ. Он начинается уже с титульного листа. Не стоит забывать про корпоративные цвета, так как по документу сразу должно быть понятно какой компании он принадлежит или какой продукт в нем описан.


Уже сам дизайн может вызвать у пользователя какие-то эмоции. И лучше сделать его нейтральным, чтобы не усилить тот негатив, с которым пользователь пришел.


Есть четыре основных принципа дизайна документа:


  • контраст;
  • повторение;
  • выравнивание;
  • приближенность.

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


Контраст


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


Давайте рассмотрим три варианта дизайна документа:


Вариант 1. Без контрастных элементов:





Вариант 2. С большим количеством контрастных элементов:



Вариант 3. С корректным количеством контрастных элементов:





Вы видите насколько по-разному выглядят и воспринимаются эти три документа, а по факту, текст в них одинаковый.


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


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

В третьем документе все понятно: о чем документ, что важно и как найти нужную информацию.


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


Можно выделять:


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

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


Повторение


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


Выравнивание


Каждый элемент должен иметь визуальную связь с другим элементом на странице. Этот принцип про логичность расположения элементов и порядок на странице.


Приведу пример некорректного выравнивания элементов:





Выравнивание может повлиять на восприятие документа. Логика этого принципа такова: связанные элементы должны быть выровнены одинаково.


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


Приближенность


Основная идея принципа приближенности: близкое физическое расположение элементов на странице подразумевает взаимосвязь. Необходимо группировать связанные по смыслу элементы и тогда документ будет более организованным, и пользователю будет легче понять с чего начать чтение и когда его закончить.


Приведу пример инструкции, в которой не используется этот принцип:





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


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


Верстка и ее основные правила


Верстка это то на, что обращает внимание пользователь, когда начинает читать документ. Она может мешать пользователю правильно воспринимать смысл текста или наоборот помогать. Именно поэтому разработчику пользовательской документации важно понимать правила верстки и активно их использовать.


Правил верстки очень много, я напишу только те, которые я регулярно использую. Их две группы: первая относится к набору текста, а вторая к переносу слов и элементов.


Правила набора текста


  • в конце заголовка не ставьте точку;
  • между словами должен быть один пробел;
  • последняя страница документа должна быть заполнена хотя бы наполовину;
  • не оставляйте один пункт списка на странице;
  • не оставляйте одну строку таблицы на странице;
  • не разрывайте абзацы;
  • абзац должен состоять из 3-5 предложений;
  • не разрывайте смысловые блоки;
  • после точки, запятой, двоеточия, точки с запятой ставьте один пробел;
  • не путайте тире, длинное тире и минус. Всё это разные знаки;
  • с двух сторон от тире и длинного тире ставьте пробел.

Правила переноса


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

Это достаточно важные правила, которые следует соблюдать при верстке документа. Большинство из них были придуманы давно и актуальны по сей день.


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


Скриншоты в документе


Давайте для начала посмотрим на документ без скриншотов.





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


Первая строка в описании процедуры уже вызывает вопрос как выглядит Панель управления Рутокен? Здесь достаточно сразу после первого пункта разместить скриншот с изображением иконки программы. Тоже самое и с остальными пунктами.


Пользователю важно понимать о каких окнах, разделах, полях и кнопках идет речь в тексте. Важно понимать как они выглядят и где находятся, без скриншотов это сделать невозможно.


Дальше я опишу основные ошибки, которые делают на скриншотах. Названия буду придумывать для них сама, поэтому не судите строго.


Перегруженность


На скриншоте не должно быть много вспомогательных элементов. В идеале в одном пункте из описания процедуры должен быть один скриншот с одним вспомогательным элементом. Иначе пользователь может запутаться и забудет что-то сделать.


Как не надо делать:





Как надо делать:





Неоднозначная трактовка обозначений


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





И как надо делать:





Что здесь не так на первой картинке? Пользователь смотрит на эти две стрелочки и думает, почему одна сплошная, а другая нет. Одна из интерпретаций: потому-что второе действие не такое важное и его можно не выполнять. Но мы не можем угадать, как здесь будет рассуждать пользователь. Поэтому такого просто не надо допускать.


Я встречала еще вот такую ошибку, когда на одном скриншоте были дополнительные элементы нескольких цветов. Ну вот представьте, на скриншоте две стрелочки: одна красная, другая зеленая. Как здесь будет рассуждать пользователь тоже не понятно. Такого не должно быть, это может запутать пользователя.


Кричащий акцент


Во всем нужна мера. Если вы хотите обратить внимание пользователя на какую-то кнопку или поле на скриншоте, не обязательно для этого использовать много дополнительных элементов, одного вполне достаточно.


Покажу вам, как не надо делать:





И как надо делать:





Но самое нелепое, что я видела это когда на одно поле для заполнение было направлено около 10 стрелочек. Не стоит такого делать, да, вы обратите внимание пользователя, но уже после третьего такого скриншота ему захочется просто закрыть документ, он устанет от этого. Это как написать страницу текста ЗАГЛАВНМИ БУКВАМИ. Наш тон должен быть доброжелательным и ненавязчивым во всем, и скриншоты это должны только подкреплять.


Невидимые дополнительные элементы


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


Покажу вам, как не надо делать:





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


Одновременно много действий


Мне кажется, уже по примеру вы легко поймете о чем это.





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


Ну и последняя ошибка, которая очень сильно бросается в глаза.


Несерьезность


Я не могу вас всех заставить использовать стрелочку, прямоугольник и линию. Но я очень вас прошу не использовать какие-то странные элементы. Вы пишите серьезный документ для взрослых людей и при этом используйте, пожалуйста, серьезные дополнительные элементы. Не думайте, что какими-то мультяшными надписями вы кого-то развеселите.


Ну и снова антипример. Чтобы уже наверняка всё стало понятно





Вывод


Давайте не забывать о том, что мы разработчики пользовательской документации пишем для людей. Наша документация не просто так публикуется в интернете. Мы действительно хотим, чтобы ее легко находили, читали и с ее помощью решали свои проблемы. Никто не хочет писать в стол.


Мне очень хочется, чтобы вся пользовательская документация была эффективной, красивой и удобной, а главное востребованной. Для этого я и написала эти три статьи. Читайте, осознавайте и применяйте на практике.



В статье я использовала информацию из книг:


  1. Робин Уильямс. Дизайн. Книга для недизайнеров.
  2. Ян В. Уайт. Редактируем дизайном.
  3. Лукьянович И.Р. Основы верстки в INDESIGN.
Подробнее..

Момент, когда проектная документация нужна

28.12.2020 12:07:24 | Автор: admin
Время идет, планета крутится, системы растут и развиваются, а я продолжаю слышать в кругах аналитиков сожаление: Эх, пришел на проект, а тут никакой документации, смотрим в код.

Но это ерунда. Хуже, когда заказчик говорит: Создали два разработчика. Уволить не могу, хотя почти ничего не делают, только по мелочи донастраивают. А с этой системой у нас уже и бухгалтерия интегрирована, и Документация? Нет ее. А надо?.. Спасите-помогите!

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




Что это за зверь документация?


С чего начинается задача на разработку? С идеи. Чтобы что-то создать, нужно это представить в своей голове. Чтобы не потерять мысль, её лучше зафиксировать.

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

Для кого документировать?


Если нет понимания, кому нужна проектная документация, то она не нужна. Возможно, прочитав эту статью чуть дальше, мнение может резко поменяться, но это не точно.



В первую очередь документация нужна команде разработки и заказчику.

Разработчик быстрее осознает, над чем он вообще трудится, спокойнее принимает чужое наследство.

Тестировщик каждый раз не находит одни и те же ошибки, которые на самом деле уже стали особенностями реализации.

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

Иногда проектная документация нужна просто потому, что так сказали.

На мой взгляд, это самый омерзительный случай страдают все: и те, кто пишет документацию нудно, скучно, бессмысленно потраченные силы на соблюдение каких-нибудь ГОСТов, и те, кто потребляет ее обязанность заказать и оплатить документацию по ГОСТу, потому что так надо.

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

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

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

Причины, по которым компании приходят к внедрению документирования


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

Есть сервис МойСклад и 2007 год. Прекрасный пример стартапа от двух разработчиков. Фундамент сервиса был целиком заложен Аскаром (генеральный директор) и Олегом (технических директор). Если почитать историю создания МоегоСклада, то можно узнать интересный факт уже тогда было неосознанное документирование продукта в рабочей тетрадке в клеточку!

Любые знания, зафиксированные на материальном или цифровом носителе, представляют из себя ту самую проектную документацию, которая впоследствии помогает устанавливать причины: почему эта кнопка работает именно так, а не иначе.



На момент, когда у продукта было 0 пользователей, лэндинг и рабочая альфа-версия, документировать было бессмысленно. Да и сейчас любой самостоятельной команде разработчиков, запускающих стартап, уверена, документировать не надо вы сами творите свое сокровище и знаете его. Лучше докрутить еще парочку фич, чем заниматься печатью лишних символов с описанием системы для себя. Время бесценно. А вот тем, кто заказывает разработку стартапа, я советую задуматься, в какой момент они могут пожелать заменить подрядчика и начинать строить свою команду.

Пример с автомастерской


Есть среднестатистическая мастерская с механиком, которому регулярно привозят примерно одинаковые машины.

В зависимости от опыта он успешно будет чинить обычные автомобили: не глядя в инструкции, не советуясь со старшим мастером. Интуиция спасет его.

Так и с программными системами. Для опытного разработчика они все примерно одинаковые, только работают немного по-разному и названия отличаются.



Привезут в автомастерскую сломанную буханку. Опытный механик постучит молотком по нужным частям, и она поедет. А постучит возможно даже наугад! Это сопоставимо с тем, что опытный разработчик придет в разработку простой системы и будет решать задачи как получится, наугад. И все будет получаться, потому что никаких сложных связей и соединений внутри нет (например, какой-нибудь интернет-магазин с информационным сайтом или что угодно другое).

Привезут в автомастерскую сломанную буханку. Опытный механик постучит молотком по нужным частям, и она поедет. А постучит, возможно, даже наугад! Это сопоставимо с тем, что опытный разработчик придет в разработку простой системы и будет решать задачи как получится, наугад. И все будет получаться, потому что никаких сложных связей и соединений внутри нет например, какой-нибудь интернет-магазин с информационным сайтом или что угодно другое.

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

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

И все успешно получится, потому что система обычная, никаких наворотов нет.



Но вот привезли Aston Martin или Ferrari. А я обычный механик в среднестатистической автомастерской. Конечно, сначала я обрадуюсь такому. Но потом, когда дело дойдет до ремонта, я буду вдумчиво смотреть на это чудо света и искать все возможные инструкции, чтобы устранить неисправность.

Так и с программной системой! Приходящие разработчики видят нечто и пытаются понять, как с этим жить. Большая часть рабочего времени уходит на погружение в контекст: вдумчивый осмотр и изучение, а не на саму разработку.
Необходимость внедрения процесса документирования зависит от сложности системы.

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

В отсутствии проектной документации основная стоимость разработки будет потрачена на изучение того, как оно работает, что это и почему так.

За 13 лет МойСклад смог очень круто подрасти: веб-приложение для RU- и US-площадок, кассовое ПО для трех платформ, мобильные приложения, шесть протоколов API и много-много всего.

Продукт простой снаружи, для пользователя, но сложный внутри для разработки и развития. Я, как ведущий системный аналитик, шла в компанию с желанием описать все быстро и продолжать развивать документированный продукт.

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

Одна из основных причин начала накопления знаний в МоемСкладе продукт стал большим и сложным.

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

Причиной запуска такой деятельности стало то, что ведущий QA тратила много времени на обучение продукту новых сотрудников и рассказы про одно и то же. Да и некоторые знания забываются и теряются, потому что есть золотое правило не трогай то, что работает.
Собранные командой тестирования документы и сегодня помогают ориентироваться в том, как работают части МоегоСклада: что считать нормой, а что нет.



Программный код и есть документация


Так говорят разработчики. И нет, это не так.

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

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

Иногда код со встроенной документацией может спасать продукт, но все же это не полноценное решение проблемы. Не-разработчикам тяжело работать с таким видом описания: структура и формат неподходящие. Но немного проблему документирования это решает.

Как нас много


Как масштаб проекта по части количества людей влияет на необходимость появления документации.











Сервис МойСклад начинался с Аскара и Олега 13 лет назад. Целиком знают продукт всего три человека: Аскар, Олег и Максим присоединившийся к ним немногим позже продакт и бизнес-аналитик.

Сегодня компания насчитывает более 150 человек. Три хранителя знаний на тридцать сотрудников? Возможно. А на команду от ста человек? Да и помнить все детали, особенно когда реализовывал их не ты, просто невозможно. Поэтому нормой стал ответ смотри как на проде.

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

Может ответить только зафиксированное знание, которое либо есть, либо нет, либо оно в человеке (а значит его нет).

В МоемСкладе стали важными такие умения, как археология по коду у разработчиков, археология по возможностям системы у тестировщиков и аналитика.

Эти навыки стали ключевыми и их стоило вносить в описание вакансий. Ими обладают далеко не все на рынке труда, да и никто особо этим заниматься не хочет.

Не храните знания в людях это опасно


Рынок IT-специалистов очень бодр и динамичен. Отсутствие документации на продукт может быть опасным. Человек, уходя из компании, уносит с собой знания о тех частях, которые он делал. Это плохо тем, что развитие и сопровождение неизведанных частей становится очень дорогим удовольствием нужно исследовать, как работает сейчас и достраивать над текущим поведением нечто новое.

У бизнес-заказчика при смене подрядчика возникнет очень много вопросов с передачей кода новой компании: наследство не любят, особенно, недокументированное. Бизнес-заказчику без документации может быть сложно стать независимым.



Сегодня все более актуальна тема с удаленной работой, да и ранее команды разработки всегда обсуждали задачи в чатах (Slack, Telegram, Skype и т.д.).

В какой-то момент жизни продукта может настать перевес: переписки у разработчиков занимают больше рабочего времени, чем решение задач.

Слишком дорого начинают обходиться разговоры. Нужно своевременно отлавливать этот момент и начинать документировать, чтобы погружение в контекст новых сотрудников проходило легче, без лишних переписок и созвонов.

Моя позиция такова: стараюсь минимизировать развернутые ответы на вопросы в чатах и максимально ссылаться на существующую документацию:

Разработчик: [Вопрос]
Я: [ссылка на Confluence] п. [название]


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

И про контекст










Итого: где же тот самый момент?


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

Некоторые компании начинают с первых дней, а некоторые тянут до последнего. Но начинать никогда не поздно. Через 5 лет, через 10 или 13 главное не пытаться прятать голову в песок, когда становится заметно, что сотрудникам сложно работать и есть проблемы с пониманием системы.

Что может дать наличие документации на программный продукт?

  • Меньше обсуждений в чатах и поисков причин почему так.
  • Быстрее погружение в контекст.
  • Команде проще понимать и оценивать объем изменений для новых задач.


А такой результат влечет за собой как минимум экономическую выгоду.

Ссылки


analystdays.ru/ru/talk/83497 Analyst Days. Как мы процесс документирования внедряли
habr.com/ru/company/moysklad/blog/452016 Сервис МойСклад 12 лет в облаке (уже 13!)
Подробнее..

Документация в порядке

30.03.2021 16:11:46 | Автор: admin

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

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

Небольшое лирическое отступление про то, что меня вдохновило на написание этого текста:

Теория разбитых окон

В криминологии есть так называемая теория разбитых окон: Если в здании разбито одно стекло и никто его не заменяет, то через некоторое время в этом здании не останется ни одного целого окна. То есть, согласно теории, если порядок не поддерживается - люди охотнее его нарушают и не следуют правилам.

Теорию подтверждают эксперименты социологов из Нидерландов. В одном из них ученые приклеивали к рулям припаркованных велосипедов рекламные буклеты и убирали из окрестности все урны. При этом на стене рядом с велосипедами висело заметное объявление о запрете граффити. Для экспериментальной группы исследователи обеспечили сплошь разрисованную граффити стену, а для контрольной - чистую. В результате, у чистой стены выбросили на улицу или перевесили флаеры на чужой велосипед 25% группы из 77 человек, а у раскрашенной - 69%.

Считаю, что принцип теории можно распространить практически на все сферы жизни человека: чистота и порядок провоцируют на созидание и продуктивность, убирают элементы хаоса и отвлекающие факторы. Однако, конечно, лучше оставлять пространство для творчества и не сковывать себя абсолютной идеальностью.

При разработке ИТ-систем мне кажется очень важным поддерживать порядок в документации. Это и есть та самая стена, на фоне которой разворачивается проектная жизнь - на нее смотрят и делают выводы, что это за проект и как там все работает.

Зачем писать

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

Обоснованность наличия документации - отдельная тема, об этом писали, например, здесь.

Если коротко - то без бумажки ты букашка. Наша память обманчива и недолговечна. Завтрашний ты обманешь себя сегодняшнего или наоборот. Придет новый человек или уйдет старый - каждый такой финт будет стоить вам дорого. Без общей картины вы будете заниматься микроменеджментом и разработкой того, что уже кем-то сделано, но он забыл вам об этом сказать. Будете делать петли и вставлять друг другу палки в колеса. А через полгода мучительно вспоминать, зачем нужен этот огромный кусок кода, который все тормозит. И это даже не касаясь кейса, когда вы заказали разработку на стороне.

Что писать

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

Например, на старте проекта с гибкой методологией велика вероятность, что все еще раз 5 поменяется до момента внедрения. Поэтому подробное техническое описание может быть лишней тратой времени. А вот позитивный сценарий - на какие кнопки в каком порядке пользователь нажимает, какие данные вводит - нужен всем членам команды. И при частых его изменениях особенно важно, чтобы у всех было единое понимание текущей версии процесса.

Легче кому-то одному потратить пару часов на документирование, чем всей команде постоянно проверять свою память.

То есть даже когда обстоятельства не в пользу полноценного описания системы и вы работаете в Agile-режиме - важно понимать, что какая-то документация существенно облегчит процесс разработки и принесет много пользы.

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

Необходимый минимум

На мой взгляд документы, которые важны практически на любом проекте, это:

  1. Документ-маршрутизатор

    Место, откуда можно добраться до всех артефактов проекта. Это может быть страница в Confluence, пространство Notion или просто Google-документ. Важно создать единую точку входа - пусть там будут только ссылки на разные инструменты и источники, но вам не придется запоминать пути поиска нужного файла.

  2. Артефакты проектных процессов

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

  3. Глоссарий

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

  4. Артефакты бизнес-потребности и бизнес-процесса

    Agile-манифест гласит: Работающий продукт важнее исчерпывающей документации. Но нельзя разработать работающий как надо продукт без четкого понимания, что же мы все-таки делаем и зачем. Бизнес-требования, схема процесса или просто письмо с постановкой от заказчика - что-то должно быть.

  5. Концептуальная модель системы

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

    Используйте IDEF0, "дорожки" BPMN, просто схему или текстовый перечень - главное обозначить принцип работы вашей системы.

    Пример верхнеуровнего описания процессаПример верхнеуровнего описания процесса
  6. Классы пользователей и уровни доступа

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

  7. Cценарии использования

    Даже если вы не используете этот инструмент для разработки требований - какой-то сценарий работы системы у вас есть. Это может быть инструкция для пользователей или тех. поддержки. Или последовательность вызовов с параметрами, если речь идет о взаимодействии систем.

  8. Логика работы системы

    По коду или БД не всегда получается понять смысл функционала. Например, формула расчета стоимости скорее всего задается бизнес-правилами, о которых коду ничего не известно.

    Эти данные так или иначе передаются разработчикам при постановке задачи. Удобно сразу их записывать в виде читаемого документа, а в задачах вставлять только ссылки на место в этом документе. А если в тот же документ прикреплять тест-кейсы - будет совсем красиво.

  9. Описание АПИ

    Да пребудет с нами swagger и стандартный формат ответа методов. Если с вами интегрируются внешние компании - не обойтись и без подробного описания параметров.

  10. Тестовые данные

    Среды, учетные записи и все, что нужно, чтобы не сводить с ума тестировщика однообразными вопросами.

  11. Ограничения/нефункциональные требования

    Вы договорились, что рассчитываете максимум на 100 пользователей? Делаете импорт справочников раз в сутки в час ночи? Внешняя система не умеет принимать какие-то значения? Сделайте приятно себе в будущем - запишите все эти детали.

Другие типы документов

Потребность в некоторых документах возникает вариативно, в зависимости от особенностей проекта:

  1. Архитектура системы

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

  2. Требования к данным

    Логическая модель, требования к составу и формату данных, особенности работы с ними и пр. Всё это не всегда покрывается характеристиками БД - в таком случае полезно зафиксировать их в отдельном документе.

    Сюда же можно добавить соглашения о формате БД - принципы наименования таблиц и атрибутов, используемые типы данных и пр.

  3. UX/UI макеты и прототипы

    Их лучше сразу собирать в одном известном всем месте и держать в актуальном состоянии.

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

  4. Описание интеграций

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

  5. Безопасность

    В целом параметры безопасности могут быть описаны вместе с доступами или нефункциональными требованиями, либо же наследоваться от общего контура ИТ компании. Но бывают системы с приоритетом или особым подходом к этой характеристике.

  6. Внешняя документация

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

Не трудно заметить, что бОльшая часть перечисленной информации скорее всего на проекте уже есть. Но она может быть разбросана по сохраненным сообщениям, личным папкам, письмам и прочему открытому космосу. Собрать это в единую структуру и оформить - не так долго, но эта работа может заметно сократить издержки на лишние вопросы, забытые задачи, кривой функционал и прочие неприятные факторы.

Как писать

Несколько инсайтов о работе с документацией:

  • Не забывайте про актуальность

    Стоит писать только ту документацию, которую вы сможете поддерживать в актуальном состоянии.

    При отсутствии описания люди начнут общаться друг с другом и у них есть шанс добраться до истины. При неактуальной документации - все будут на нее смотреть и делать неправильно.

  • Неоформленные артефакты - тоже документация

    Удобно складывать в одно место те артефакты, которые нет возможности обработать и хорошо оформить.

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

  • Растите культуру документирования в команде

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

    Важно договориться, как такая документация будет поддерживаться.

  • Комментарии в коде не всегда спасают

    Структура кода не обязана повторять структуру процесса/функционала и, тем более, бизнес- и пользовательских требований. Поэтому из кода можно понять "как" работает система, но на вопросы "зачем?", "почему?" и "как должна?" отвечает именно проектная документация.

  • Планируйте и декомпозируйте работу с документацией

    Документирование - это задача, которую легко разбить на небольшие отрезки времени и размазать по спринту.

    Когда-то я бронировала в календаре последние 2 часа пятницы на составление/актуализацию документации. Принимать решения в это время опасно, к тому же эта деятельность помогает подвести итоги рабочей недели и запланировать следующую.

  • Закрывайте техдолг

    При введении функционала в эксплуатацию важно выделить время на дооформление хвостов. Иначе не видать спокойной поддержки и доработки системы.

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

  • Больше схем и диаграмм

    Визуальная информация воспринимается легче и быстрее, лучше запоминается. Чем больше данных вы представите графически - тем доступнее и короче будет документация.

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

  • Учитесь писать нехудожественные тексты

    Навык написания текстов сильно ускоряет процесс документирования и повышает его качество. Рекомендую использовать https://glvrd.ru. Плюс по возможности почитать "Пиши, сокращай" и "Бизнес-копирайтинг". Так и работа быстрее пойдет, и тексты станут понятнее и приятнее.

    Вот еще хороший доклад на тему "Как писать полезные технические тексты".

Как итог

Не обязательно подробно документировать всё, или хотя бы выполнять "необходимый минимум" из этой статьи. Всегда полезно сверять часы с реальностью и понимать - что действительно нужно и поможет достичь цели.

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

Даже если у вас нет ТЗ с тезаурусом и перечнем иллюстраций - структурированное и понятное хранение имеющейся документации облегчит жизнь всей команды. А также сподвигнет вас и коллег более собранно и ответственно относиться к проекту.

Подробнее..

Автоматическая документация для Flask с использованием OpenAPI

15.02.2021 18:22:10 | Автор: admin
image alt


Техническая документация, как известно, крайне важная часть любого проекта. До недавнего времени мы прекрасно жили с таким генератором документаций как Sphinx. Но наступил момент переходить на технологии с бОльшим набором возможностей, поэтому мы приняли решение переписать нашу документацию на более современный стандарт: OpenAPI Specification. Эта статья является скромным гайдом по такому переезду. Она будет интересна Python-разработчикам, особенно тем, которые используют Flask. После ее прочтения вы узнаете, как создать статическую OpenAPI документацию для Flask приложения и развернуть ее в GitLab Pages.




apispec + marshmallow


В качестве веб-фреймворка у нас используется Flask. Документацию для API, созданного с помощью него, мы и хотим создать. Спецификация по стандарту OpenAPI описывается форматом YAML(или JSON). Чтобы преобразовать докстринги нашего API в необходимый формат, будем использовать такой инструмент, как apispec, и его плагины. Например, MarshmallowPlugin, с помощью которого (и самой библиотеки marshmallow) можно удобно за счет возможности наследования и переиспользования описать входные и выходные данные эндпоинтов в виде python классов, а также провалидировать их.

Используя библиотеку marshmallow, создадим класс, описывающий параметры API:

from marshmallow import Schema, fieldsclass InputSchema(Schema):   number = fields.Int(description="Число", required=True, example=5)   power = fields.Int(description="Степень", required=True, example=2)

Аналогично сделаем для выходных параметров:

class OutputSchema(Schema):   result = fields.Int(description="Результат", required=True, example=25)

Для группировки запросов в OpenAPI используются теги. Создадим тег и добавим его в объект APISpec:

def create_tags(spec):   """ Создаем теги.   :param spec: объект APISpec для сохранения тегов   """   tags = [{'name': 'math', 'description': 'Математические функции'}]   for tag in tags:       print(f"Добавляем тег: {tag['name']}")       spec.tag(tag)

Далее нам нужно интегрировать параметры в докстринг так, чтобы это соответствовало OpenAPI спецификации.

Пример:

from flask import Blueprint, current_app, json, requestblueprint_power = Blueprint(name="power", import_name=__name__)@blueprint_power.route('/power')def power():   """   ---   get:     summary: Возводит число в степень     parameters:       - in: query         schema: InputSchema     responses:       '200':         description: Результат возведения в степень         content:           application/json:             schema: OutputSchema       '400':         description: Не передан обязательный параметр         content:           application/json:             schema: ErrorSchema     tags:       - math   """   args = request.args   number = args.get('number')   if number is None:       return current_app.response_class(           response=json.dumps(               {'error': 'Не передан параметр number'}           ),           status=400,           mimetype='application/json'       )   power = args.get('power')   if power is None:       return current_app.response_class(           response=json.dumps(               {'error': 'Не передан параметр power'}           ),           status=400,           mimetype='application/json'       )   return current_app.response_class(       response=json.dumps(           {'response': int(number)**int(power)}       ),       status=200,       mimetype='application/json'   )

Эта функция пример реализации метода GET в нашем API.

Блок summary. Краткое описание функции. Для более подробного описания можно добавить блок description.

Блок parameters. Описание параметров запроса. У параметра указывается, откуда он берется:

  • path, для /power/{number}
  • query, для /power?number=5
  • header, для X-MyHeader: Value
  • cookie, для параметров переданных в cookie файле

и schema, в которую передается python класс, описывающий данный параметр.

Блок responses. Описание вариантов ответа команды и их структура.

Блок tags. Описание тегов, которые используются для логической группировки эндпоинтов.

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

После того, как мы описали методы API, можем загрузить их описание в объект APISpec:

def load_docstrings(spec, app):   """ Загружаем описание API.   :param spec: объект APISpec, куда загружаем описание функций   :param app: экземпляр Flask приложения, откуда берем описание функций   """   for fn_name in app.view_functions:       if fn_name == 'static':           continue       print(f'Загружаем описание для функции: {fn_name}')       view_fn = app.view_functions[fn_name]       spec.path(view=view_fn)

Создаем метод get_apispec, который будет возвращать объект APISpec, в нем добавляем общую информацию о проекте и вызываем описанные ранее методы load_docstrings и create_tags:

from apispec import APISpecfrom apispec.ext.marshmallow import MarshmallowPluginfrom apispec_webframeworks.flask import FlaskPlugindef get_apispec(app):   """ Формируем объект APISpec.   :param app: объект Flask приложения   """   spec = APISpec(       title="My App",       version="1.0.0",       openapi_version="3.0.3",       plugins=[FlaskPlugin(), MarshmallowPlugin()],   )   spec.components.schema("Input", schema=InputSchema)   spec.components.schema("Output", schema=OutputSchema)   spec.components.schema("Error", schema=ErrorSchema)   create_tags(spec)   load_docstrings(spec, app)   return spec


image alt


Swagger UI


Swagger UI позволяет создать интерактивную страницу с документацией.

Создадим эндпоинт, который будет возвращать спецификацию в json формате, и вызываем в нем get_apispec:

@app.route('/swagger')def create_swagger_spec():   return json.dumps(get_apispec(app).to_dict())

Теперь, когда мы получили json спецификацию, нам нужно сформировать из неё html документ. Для этого воспользуемся пакетом flask_swagger_ui, с помощью которого можно встроить интерактивную страницу с документацией на базе Swagger UI в наше Flask приложение:

from flask_swagger_ui import get_swaggerui_blueprintSWAGGER_URL = '/docs'API_URL = '/swagger'swagger_ui_blueprint = get_swaggerui_blueprint(   SWAGGER_URL,   API_URL,   config={       'app_name': 'My App'   })


Таким образом, мы сделали эндпоинт /docs, при обращении по которому получаем документацию следующего вида:

image alt


image alt

GitLab Pages + ReDoc



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

Использование GitLab позволяет сгенерировать такую статическую страницу с документацией в CI/CD процессах.

Таким образом, мы один раз соберем документацию, и при обращении по заданному адресу она будет просто отображаться без какой-либо дополнительной обработки.

Для этого сохраним APISpec в YAML файл:

DOCS_FILENAME = 'docs.yaml'def write_yaml_file(spec: APISpec):   """ Экспортируем объект APISpec в YAML файл.   :param spec: объект APISpec   """   with open(DOCS_FILENAME, 'w') as file:       file.write(spec.to_yaml())   print(f'Сохранили документацию в {DOCS_FILENAME})

Теперь, когда мы получили YAML файл по спецификации OpenAPI, нужно сформировать HTML документ. Для этого будем использовать ReDoc, так как он позволяет сгенерировать документ в gitlab-ci с красивой и удобной структурой. Публиковать его будем с помощью GitLab Pages.

Добавим следующие строки в файл gitlab-ci.yml:

pages: stage: docs image: alpine:latest script:   - apk add --update nodejs npm   - npm install -g redoc-cli   - redoc-cli bundle -o public/index.html docs.yaml artifacts:   paths:     - public

Стоит отметить, что index.html нужно сохранять в папку public, так как она зарезервирована GitLabом.

Теперь, если мы запушим изменения в репозиторий, по адресу namespace.gitlab.com/project появится документация:

image alt


Также путь до документации можно посмотреть в Settings/Pages

Пример документации с использованием ReDoc: ivi-ru.github.io/hydra

Заключение


Таким образом, мы научились собирать OpenAPI документацию с использованием ReDoc и хостить ее на GitLab Pages. В эту статью не попало еще несколько возможностей этих инструментов, например, валидация параметров с помощью marshmallow. Но основной ее целью было показать непосредственно процесс создания документации.

Полезные ссылки


Подробнее..

Какая бывает документация

13.02.2021 22:06:51 | Автор: admin

Когда мы говорим о тестировании документации, то обычно подразумеваем тестирование требований, ТЗ. И это тестирование на полноту, однозначность и прочая. Смотрим, как новый функционал будет коррелировать со старым, не будет ли проблем. Заранее продумываем свои тесты, обсуждаем реализацию...

Однако помимо ТЗ есть еще куча другой документации, которую тоже стоит проверить. Как минимум вычитать, нет ли ошибок. Эта статья как чек-лист, что еще нужно найти и проверить.

Итак, давайте посмотрим, какая бывает документация:

  1. ТЗ требования

  2. Пользовательская документация

  3. Примеры

  4. Письма от системы

  5. Сообщения об ошибках

  6. Поп-ап сообщения

  7. Предупреждения что вводить

  8. Инструкция по установке

  9. Описание полей

  10. Маркетинговые материалы

  11. Обучение FAQ, презентации

  12. Поздравляшки

  13. Кнопки

  14. Остальное

  15. Итого

1. ТЗ требования

ТЗ техническое задание. Это основной тип документации для тестировщика. Если ТЗ есть, его всегда надо тестировать. Как само ТЗ, так и систему на соответствие этому ТЗ. Помните самые простейшие баги? Когда есть четкие требования, но система работает по другому.

Виды требований

В каком виде могут быть требования? Есть разные варианты:

Техническое задание

Сухое описание того, как система должна работать. Что уметь делать и как реагировать на ошибки.

Вариант использования

Описание через взаимодействия пользователя с системой:

Пользователь делает то

Система в ответ делает се

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

Пользовательский сценарий

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

В общем, градация от сухое ТЗ до интересная история широкая. Как ваш аналитик решил записать, так и будет.

Картинка

Да да, именно картинка! Вид ее может быть любой:

  • Блок-схема

  • Диаграмма состояний и переходов

  • Скриншот, раскрашенный красным тут должно быть вот так, а тут эдак

  • Схема движения транзакций

  • ...

То есть снова есть простор для творчества. Хотя обычно, конечно, используют от силы блок-схемы. Но и на том спасибо =)

Что-то другое

Я уверена, что могут быть и другие варианты. Но так как это статья от тестировщика тестировщику, ограничимся базовыми вариантами. За остальным к аналитику =)

У меня на одном из проектов, например, ТЗ было в виде презентации PowerPoint. Вот как генеральный продавал проект спонсорам, так мы и должны были сделать. Картинки + немного текста вот и всё ТЗ. Что непонятно, уточняйте устно.

Размер требований

Опять же, размер может быть любой. Все зависит от проекта, на который вы попадете.

Подробное описание

Обычно встречается на гос проектах. Ооооо, сколько там ТЗ!

Я участвовала на одном таком проекте, где описание функционала, который описывается одной строчкой (есть авторизация через email) занимало 10 листов А4 пошаговое описание интерфейса с картинкой через строку.

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

Но зато начинающему тестировщику очень легко работать с такой документацией. Там должно быть прописано ВСЕ. И позитивные сценарии, и негативные. Читай да выполняй, сверяясь с требованиями.

Плюсы:

  • Требования может проверить даже новичок (даже если там бухгалтерия или еще что-то сложное, в чем он ни в зуб ногой)

  • Если это ТЗ для интеграции у Заказчика будет возникать меньше вопросов А что будет, если...?. Ведь всё уже прописано в ТЗ.

Минусы:

  • Неактуальность документации (я бы написала сложно поддерживать актуальность, но она все равно в итоге будет неактуальна. Слишком много её)

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

Краткое описание

Буквально одна страничка на довольно большой объем работы. Там не расписываются подробно все ошибки или что может пойти не так, это скорее как напоминалка, какие функции должны быть.

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

Плюсы:

  • Легко поддерживать актуальность.

  • При грамотном описании все понятно, без воды.

Минусы:

  • Начинающий тестировщик может пропустить тесты он не догадается, что тут можно было бы проверить (иногда ведь в ТЗ расписываются и все сообщения об ошибках, даже думать не надо, читаешь и делаешь).

  • Если отдать ТЗ третьим лицам (например, заказчику или его тестировщикам), получите много вопросов А что будет, если...?, и придется дополнять требования.

Однако минусы не так уж страшны. Так что если есть возможность пишите кратко!

Нечто среднее

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

Требований нет!

Бывает и такое. Приходите на проект, на, держи, тестируй. А где документация? А нету ее, так проверяй. Что делать?

На самом деле не бывает такого, что требований нет. Они всегда есть. Просто иногда в голове. Заказчика, аналитика, архитектора...

Ваша задача в этом случае эти требования узнать. И сохранить:

  • Найти носителя информации.

  • Выяснить все подробности.

  • Кратенько записать.

  • Попросить его проверить.

Тут вы можете сказать:

Эй, але! Я тестировщик! Поставлю задачу аналитику и пусть он делает.

Ну-ну. Вы думаете, если до вас процветало разгильдяйство, то сейчас все резко изменится? Что нужно было просто задачку на аналитика поставить? Если документации до сих пор нет значит, всех всё устраивает.

Хотите изменить мир? Начните с себя. Заставить других так не работает. Если вам плохо без отсутствия документации, сделайте ее сами. В следующей главе я расскажу, как это можно сделать. Если же вас не парит отсутствие документов живите как живёте.

2. Пользовательская документация

Это вся документация, которую вы передаете пользователю. Описание системы и её функционала, скриншоты интерфейса, даже требования всё, что находится в открытом для пользователя доступе.

Чем отличается от ТЗ? Тем, что в ТЗ вы можете использовать сленг, сокращения, не писать какую-то очевидную для коллег информацию. А вот пользователь ваших сокращений не знает, ему пишите понятнее.

У нас, например, в вики-системе есть разделы по проекту:

  • Внутренний пользователи его не видят. Там все потроха, а еще описание реализации и тестов.

  • Внешний общий доступен всем пользователям. Тут лежат инструкции по разворачиванию системы (для администраторов) и по работе в ней (для пользователей), описание API-методов, примеры их вызовов Это всё пользовательская документация.

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

Таким образом, в пользовательскую документацию могут входить и примеры, и требования. Но... Зачем смешивать все в единую кучу? А как вы потом будете на своем проекте искать документацию? Я предлагаю все же разделить:

  • Требования требования для реализации.

  • Пользовательская документация информация о работе системы.

Ограничивается ли документация этими пунктами? Разумеется, нет! Поэтому я и написала эту статью, чтобы вы не забыли про остальные пункты ))

3. Примеры

Всегда проверяйте примеры. Просто ВСЕГДА!

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

Другой вопрос а что относится к примерам? Что проверять то нужно? Давайте разбираться!

Файл-образец

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

  1. Возьмете свой файлик и попробуете сразу на нем.

  2. Возьмете пример из системы.

Первый вариант возможен, да. Но часто ли у вас под рукой нужный файл? Это надо еще пойти в систему, сделать выгрузку... А зачем напрягаться, если вас Дадата не устраивает исходно? Конечно, сначала проще взять образец и посмотреть на нем, что умеет система.

Если ок, всё устраивает, то пробуем на своих данных. Но это обычно второй шаг, а начинают с готового примера. Поэтому очень важно проверять в регрессе, что файл-образец:

  • Скачивается (вдруг ссылка побилась??)

  • Обрабатывается без ошибок, выдаёт правильный результат.

Предзаполненные поля в форме ввода

Что, если у нас просто форма ввода? И туда можно добавить пример! Вот как в Дадате сделано:

Все поля заполнены по умолчанию. Можно просто ткнуть на кнопку Проверить и посмотреть результат. А потом уже обрабатывать свои данные. И поверьте, большинство просто ткнет в кнопку для начала, просто потому, что так проще.

Примеры вызова API-методов

Что может быть приятнее, чем скопировать пример и отлаживаться на нем? То есть сначала послали запрос, который 100% работает, а потом уже варьируем под свои данные.

Это очень важно для интеграции. Вы ведь пытаетесь соединить свою систему с чужой. Чужую вы почти не знаете, как она работает? Спасает только наличие ТЗ.

Но что, если требований тааааак много и они довольно сложные, а интегрировать уже пора начинать? Сначала стоит выполнить простейший сценарий. А где его взять? Конечно, из примера! Выполняем пример вручную. Работает? Тогда пишем вызов уже из кода. Написали? Теперь уже сидим и вчитываемся подробнее, разбирая всякие альтернативные сценарии.

Именно поэтому примеры очень важны. С них начинают работу с системой.

Другие примеры

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

Ну а я выше рассказала об основных. Не забудьте проверить, есть ли у вас в системе предзаполненная строка или файл-образец. И тестируйте их каждый релиз (желательно автоматически, но тут уж как пойдет)

Итого по примерам

Примеры очень важны. С них начинают работу с системой.

  • Если у вас их нет просите добавить.

  • Если они есть тестируйте их!

Если вы делаете внешнее API для заказчика или вообще публичное, опишите его и добавьте примеров. Именно с них пользователь начнет знакомство с методом.

Но и в простом интерфейсе есть место для примеров. Можно облегчить пользователям жизнь, подготовив файл-образец или предзаполнив форму ввода. И они обязательно этими примерами воспользуются. Поэтому примеры мы ОБЯЗАТЕЛЬНО тестируем. Всегда. Это лицо нашего приложения, оно должно работать.

4. Письма от системы

О, это тоже очень важный пункт! Сейчас многие системы присылают приветствия, напоминания, уведомления... Так вот эти письма это тоже документация, причем очень важная ее часть!

Типичные проблемы писем плейсхолдеры, которые:

  • не разименовались;

  • разименовались, но неправильно.

Что такое плейсхолдер? Это заглушка, которая меняется на нужное значение при отправке письма. Разработчик же не знает заранее, как вас зовут. Но допустим, что он хочет сделать именное письмо:

Привет, Ольга! Спасибо за регистрацию на нашем сайте...

Привет, Андрей! Спасибо за регистрацию на нашем сайте...

Привет, Сладкий пупсик! Спасибо за регистрацию на нашем сайте...

Разработчик пишет письмо, оставляя плейсхолдер вместо имени:

Привет, $username! Спасибо за регистрацию на нашем сайте...

И говорит в коде: Вместо $username подставь имя, которое пользователь ввел при регистрации. Возьми значение из такого-то поля. Теперь, когда Маша-Ваня-Петя регистрируются на сайте, они получают личное письмо со своим именем!

Обычно такие подмены делают на имена и даты. Например, дата, на которую куплен билет. Главное подставить нужное значение! А с эти бывает беда...

В апреле 2017 года я летела в Екатеринбург, на конференцию DUMP[1]. Купила билеты в S7 Airlines заранее в феврале. Перепроверила даты, вроде все правильно, вылетаю 13.04.

Упорный бот пытался впарить мне отель через их сайт и отказ не принял. А 02.02.2017 он прислал мне напоминалку, что у меня скоро полет... И поставил дату... Сегодня о_О

Когда-когда мой полет?? Эй, он же в апреле!Когда-когда мой полет?? Эй, он же в апреле!

Эй, але, я покупала билеты на апрель! Холодный мороз по коже а вдруг я ошиблась? Нашла письмо с билетами, нет, все хорошо:

Вот же, 13.04!

Значит, просто накосячили в письме. Благо понятно как, раз дата сегодняшняя то вместо моего реального времени полета вставили SYSDATE. Или там и должно быть sysdate, но письмо должно было быть отправлено в апреле...

Проблемы бывают самые разные:

Иногда письмо приходит с опозданием и получается оплатите счет до вчера.

Иногда тебе пишут Привет, username!. Забыли подставить значение =))

Иногда неправильно склоняют имя

Иногда неправильно определяют пол

...

То есть в первую очередь мы проверяем в письмах все переменные и плейсхолдеры правильно ли они подставились? Если это строка с именем, проверяем такие моменты:

  • А если я пустым оставлю поле?

  • А если на другом языке напишу?

  • А если спецсимволы введу?

  • А если очень длинное имя?

Аналогично с датой:

  • Когда придет письмо сразу после регистрации, за день до назначенного времени?

  • Правильная ли дата будет в письме?

Ну и, конечно, надо хотя бы разок вычитать все письма на орфографические ошибки!

5. Сообщения об ошибках

Да да, это тоже документация! Поэтому их надо все найти и проверить. Зачем? Давайте я расскажу вам про Pretty roses (взят из интернета, исходного автора давно утеряли):

PASSWORD EXPIRED

"Sorry, your password has been in use for 30 days and has expired You must register a new one."

roses

"Sorry, too few characters."

pretty roses

"Sorry, you must use at least one numerical character."

1 pretty rose

"Sorry, you cannot use blank spaces."

1prettyrose

"Sorry, you must use at least 10 different characters."

1fuckingprettyrose

"Sorry, you must use at least one upper case character."

1FUCKINGprettyrose

"Sorry, you cannot use more than one upper case character consecutively."

1FuckingPrettyRose

"Sorry, you must use no fewer than 20 total characters."

1FuckingPrettyRoseShovedUpYourAssIfYouDon'tGiveMeAccessRightFuckingNow!

"Sorry, you cannot use punctuation."

1FuckingPrettyRoseShovedUpYourAssIfYouDontGiveMeAccessRightFuckingNow

"Sorry, that password is already in use. "

Пользователи всегда ошибаются. Неумышленно делают что-то не так. Они могут вставить вместо имени копипасту огромного текста из буфера обмена, вместо картинки загрузить txt, промахнувшись при выборе файла... Они могут сломать что-то просто потому, что не знают, как система работает...

Именно поэтому так важно обрабатывать негативные сценарии. Вообще, в идеале нужно делать так, чтобы пользователь просто не мог ошибиться! Например, если в поле можно вводить только целые цифры (количество товара в корзине), что будет лучше?

  1. При вводе символа ругаться Ты что, дурак? Тут только цифры!

  2. При вводе символа ругаться В поле можно вводить только цифры

  3. Не давать возможность ввести символы обрезать их при копипасте и игнорировать при вводе с клавиатуры.

Разумеется, идеальным будет третий вариант. А второй мы оставим на случай, если пользователь обойдет наше ограничение.

Ведь не дать ввести символы это ограничение, установленное на клиенте. При знании нужных инструментов его легко обойти (начните с Web developer toolbar, вкладка Forms). Поэтому нужно оставить защиту на сервере если пользователь символы таки ввел, выведем ошибку.

См также:

Клиент-серверная архитектура в картинках подробнее о клиенте и сервере

Общая мысль:

Если негативный сценарий можно избежать, сделайте это.

Если избежать его нельзя, тогда уже делайте сообщение об ошибке.

Ну а подробнее про то, как будет лучше пользователю, смотрите в литературе по usability. Вот мой список книг, см раздел Usability-тестирование.

Как искать сообщения

В систему можно загружать файл? Тогда пробуем грузить пустой файл, неправильного формата, расширения, разрешения...

В форме редактирования есть обязательные поля? Пробуем их не заполнять или заполнять неправильно...

Система передает ответы через SOAP/JSON? А если отправить неправильный запрос, пустой, с неполными или некорректными данными?

И так далее, и тому подобное.

Если есть доступ к коду отлично! Смотрим, в какие сообщения разработчики оборачивают эксепшены, находим их в приложении и проверяем отображение.

Каким должно быть сообщение об ошибке

Каким должно быть сообщение об ошибке?

Коротким, иначе пользователь заснет, читая его.

Понятным, иначе как понять, что я сделала не так?

Из сообщения должно быть понятно:

В чем моя ошибка?

Что мне сделать, чтобы исправить ее?

При этом сообщение должно быть в мире пользователя. Мне будут одинаково непонятны тексты:

Извините, что-то сломалось.

Error 38759245, see line 333 in code

Неправильно введены данные.

Особенно на форме из 100 полей. Какие именно данные я ввела неверно? И даже если их подсветили красным, а что неверно то? Как верно будет? Вы мне скажите, что делать то надо.

А еще можно сделать сообщение интересным и смешным! Как? Вот, посмотрите, какая прелесть:

Примеры сообщений об ошибках

Dadata

В Дадату можно загружать файлы формата Excel или CSV. Система заранее предупреждает о том, какой должен быть файл:

Если попробовать грузануть туда JPEG, система понятно объясняет, что надо сделать:

Сообщение об ошибке в Дадате понятноСообщение об ошибке в Дадате понятно

Это пример как хорошо, а дальше разберем, как плохо =)

Wildberries, галерея стиля, загрузка фото

Один раз я попробовала загрузить фото в Галерее стиля (туда пользователи выкладывают фоточки в вещах из магазина) и невольно потестировала документацию сайта...

Итак, заходим в личный кабинет, оттуда в Мои образы. Читаем информацию, но увы, ни слова о том, какие файлы допустимы:

Читаем условия по загрузке фотоЧитаем условия по загрузке фото

Вроде никаких ограничений нет...

Итак, возрадовались возможности создать образ, грузим фоточку.

Выбираем фото для образа...Выбираем фото для образа...

Ага, вот и первое ограничение! Файлы должны быть размером поменьше...

Но ведь так айпад снимает... Ладно, берем стандартные виндовые ножницы, обрезаем фото и сохраняем как JPEG, чтобы уж наверняка мало весить стал. Грузим снова:

Не хочешь 2 Мб, на тебе 100 КбНе хочешь 2 Мб, на тебе 100 Кб

И что бы вы думали, мне говорят?

Что значит поддерживается только jpg? А я что гружу?

Я ведь jpg и гружу, але!Я ведь jpg и гружу, але!

Я гружу JPEG, а мне говорят, что формат неверный, грузи JPEG? о_О

Ладно-ладно! Снова открываю фоточку, снова вырезаю ножницами и сохраняю как PNG, на рисунке чуть выше мы его видим, он в 6 раз побольше весит, качество получше, все дела... Но ситуация повторяется...

Ох ох ох, у меня так было на первых попытках загрузки фоток, пошли старым дедовским методом вставить картинку в Paint, уменьшить масштаб и сохранить как jpg. И вуаля, блин! Загрузилось!

Я, как пользователь, посылаю разработчикам лучи ненав добра и нежности в такие минуты.

Знаете, в чем оказалась проблема? В регистрозависимости расширения файла:

  • jpg грузится;

  • JPG нет.

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

Как это исправлять? Можно, конечно, разжевать пользователю, что jpg могу, JPG не могу, но... Зачем? Лучше сделать функцию проверки формата регистронезаивисимой. Помните о том, что лучше предотвратить ошибку, чем красиво ее расписать?

Далее, если загрузить слишком маленькую картинку, то получим ошибку:

Файл должен быть не менее 500 пикселей в ширину и 700 в высоту.

Откуда пользователю узнать про этом ограничение? Нужно предупредить! Можно завести такое улучшение:

**********************************************************************

Подсказывать правильный формат и размер файлов для загрузки в ГС

Указать ограничения еще до того, как пользователь начнет грузить файлы. В раздел Мои образы https://lk.wildberries.ru/mylooks добавить надпись:

Принимаются фото:

jpg, jpeg, gif, png, bmp до 2Мб

не менее 500 пикселей в ширину и 700 в высоту

**********************************************************************

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

Какие пиксели? Что надо делать, чтобы сделать их больше или меньше?

Имхо, лучше грузить фото покрупнее, до 3-4 Мб и ужимать их на программном уровне, чтобы не хранить тяжесть в базе. В галерее все равно небольшая фоточка отображается, поэтому обидно врядли будет, если делать как радикал, который сам уменьшает фото до 800 px.

Если эту пикселяцию поставили для ограничения снизу, чтобы не прошли нечеткие фото, то тоже стоит обсудить. Если это было предотвращение чего-то, то лучше ее вообще снять и посмотреть, сильно ли ухудшится качество загружаемых фотографий. Потому что 100 Кб jpeg вполне себе нормально отображается. Если нагрузка на модераторов возрастет, подумать, что можно сделать. Но пока этот отсев создает проблемы пользователю, а не модератору.

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

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

Wildberries, форум, загрузка фото

Попробовала добавить аватарку на форуме. Иду в Мой кабинет на форуме, далее Изменить фотографию, выбираю фото и...

БЛИН, ДА В ЧТО, ИЗДЕВАЕТЕСЬ, ЧТОЛИ?!!!

Вот что я должна понять из этого сообщения? Почему неудачно? Я что-то сделала не так? Система сломалась? Совсем или мне попробовать через 5 минут?

Помните, что сообщение должно говорить, что сейчас плохо и как я могу это исправить (если могу).

Wildberries, галерея стиля, комментарии

Снова про галерею стиля. Все комментарии к образам отслеживаются модераторами, но это второй рубеж. Первый автоматический отсев ссылок и черт знает чего еще.

Почему черт знает? Потому что текст сообщения непонятный:

Поле содержит ссылку или некорректное выражение

Вроде все ясно, да? Ну нефиг ссылки лепить, всего и делов... Но под огонь попадают нормальные слова или фразы. Например, слово ребенок:

А теперь представьте, что вы написали большой комментарий в духе Ой, какой красивый ребенок! А как хорошо на нем курточка сидит, прямо вау, самой такую захотелось взять....

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

В общем, когда пишете сообщение об ошибке, думайте о пользователе. Что я из него пойму? Смогу ли исправить ошибку? Пойму вообще, что я сделала не так? Если да то всё круто! Если нет сделайте так, чтобы поняла.

6. Поп-ап сообщения

Pop-up это всплывающее окошко, как навязчивое а вы уже лайкнули нас в фейсбуке?.

В веб приложениях это обычно:

  • уведомление о регистрации;

  • акционное предложение;

  • мини-версия корзины с покупками;

  • ...

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

В мобильных игрушках:

  • реклама новой игрушки;

  • временная акция;

  • поздравляшка с успешным окончанием уровня;

  • не-поздравляшка ты провалил уровень;

  • ...

Что тут стоит проверить? Влезает ли текст в отведенное ему место =))

Пример бага в веб-приложении мы находили в рамках The FedEx Tour: если ввести слишком длинный емейл при регистрации, получим такую картину:

А вот и пример поп-апа в игрушке из серии три в ряд. Если не успел освободить ежа за N ходов, выпадает такое сообщение:

Это на mini ipad было дело. Так что учтите, не только акции во всплывашках! И тестировать такое надо на самых мелких экранах, а потом на средних. А то, может, для телефонов изображение уменьшили, а для айпадов оставили одно, что для макси, что для мини, большой же экран, влезет!

Или вот ещё пример из той же игрушки. Прочтете текст снизу: когда закончится акция?))

7. Предупреждения что вводить

Это когда около поля заранее пишут требования к нему:

Логин должен содержать латинские символы и цифры.

Пароль должен быть длиннее 8 символов и содержать как символы, так и цифры.

...

Чтобы не допустить сообщение об ошибке, предупреждаем о правилах заранее! А требования те же самые, что и у сообщений об ошибках, предупреждения должны быть:

понятные;

в мире пользователя;

выполнимые.

Не надо писать на языке разработки. Пишите для людей, они оценят это больше, нежели формальный стиль общения.

Про выполнимость расскажу такую историю:

Изменение пароля, банк

На одном проекте я работала с банком. Чтобы посмотреть логи сервера, нужен удаленный доступ к виртуальной машине.

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

Вроде все верно, тут говорят сразу, что пароль должен соответствовать политике безопасности. Я не против, но это вся страница. Никакой ссылки на политику безопасности... И где же мне ее взять?

Тут нужно продумать то, что на страницу заходят люди, которые НЕ работают в банке и НЕ знают, где взять внутреннюю документацию (да ее никто и не даст). Поэтому лучше просто заранее вынести информацию в это сообщение.

Я же подбирала пароль наугад, а что делать...

Думайте о своих пользователях кто они? Если вы делаете софт только для сотрудников компании, можно ссылаться на некую внутреннюю документацию. И то всегда лучше дать ссылку, чем заставлять пользователя искать ту же политику безопасности.

А если к вашему приложению будет доступ у третьих лиц, то ссылки на внутреннюю документацию стоит убрать. Напишите лучше около поля, каким должен быть пароль. Это не займет места больше, чем эта унылая цитата =))

8. Инструкция по установке

Пользовательское приложение

Если это простое или общедоступное ПО его будут устанавливать сами пользователи.

В идеале, конечно, инструкции нет, вместо нее просто .exe файл (если речь про Windows). Помните, как последний раз что-то устанавливали? Скачал, запустил, 10 раз кликнул далее-далее-далее, профит!

Но что, если вы решили установить то же приложение на Linux? Ну ладно, ладно, там тоже бывает просто, запустил команду скачивания, и вот у тебя уже всё есть.

Но что, если недостаточно просто запустить установочный файлик? Что, если нужно прописать какую-то переменную в Path, например? Тогда комбинируем файл быстрой установки + краткая инструкция.

Например, установка maven. Скачиваем, читаем инструкцию по установке. Она мега-простая, но она есть. Для винды:

1. Check environment variable value e.g.

echo %JAVA_HOME%

C:\Program Files\Java\jdk1.7.0_51

2. Adding to PATH: Add the unpacked distributions bin directory to your user PATH environment variable by opening up the system properties (WinKey + Pause), selecting the Advanced tab, and the Environment Variables button, then adding or selecting the PATH variable in the user variables with the value C:\Program Files\apache-maven-3.6.0\bin. The same dialog can be used to set JAVA_HOME to the location of your JDK, e.g. C:\Program Files\Java\jdk1.7.0_51

3. Open a new command prompt (Winkey + R then type cmd) and run mvn -v to verify the installation.

Переведем:

1. Проверьте текущую переменную окружения, есть ли у вас Java на компьютере?

echo %JAVA_HOME% команда проверки

C:\Program Files\Java\jdk1.7.0_51 результат команды, он говорит, что Java установлена, так как существует переменная %JAVA_HOME%

2. Добавьте maven в PATH: добавьте ссылку на директорию bin в пользовательскую переменную PATH. Для этого откройте системные настройки (WinKey + Pause), выберите вкладку Advanced, нажмите кнопку Environment Variables и добавьте переменную PATH, или выберите ее, если она уже существует. Добавить туда надо значение пути до директории bin, например: C:\Program Files\apache-maven-3.6.0\bin. Аналогично можно и JAVA_HOME добавить, прописав путь до JDK, например C:\Program Files\Java\jdk1.7.0_51

3. Откройте НОВУЮ командную строку (Winkey + R, а потом написать cmd) и выполните команду mvn -v, чтобы проверить установку.

Фактически для установки нужно выполнить ОДНО действие добавить ссылку на директорию bin в PATH. Еще два пункта для проверки того, что все установилось. Maven обращается к JAVA_HOME, поэтому такая переменная должна существовать, что мы и проверяем. И саму установку maven тоже проверяем командой mvn -v.

Это оптимальная инструкция, ничего лишнего. Или приложение устанавливается само, или к нему есть короткая инструкция на действия, которые надо сделать именно вам.

Серверное приложение

Это полноценное приложение, которое Заказчик сам устанавливает на свои сервера. Например, система работы с клиентами в банке. Она требует конкретных ресурсов и настроек системы, просто далее-далее-далее тут не обойтись.

В этом случае нужно обеспечить полноценную инструкцию по установке, считая, что:

  1. Сервер создан с нуля, там НИЧЕГО нет.

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

  3. Разворачивать сервера будут админы, которые с компьютером на вы.

Учитывая третий пункт, пишем максимально подробно, максимально понятно. Если просим выполнить команду даем саму команду, чтобы вставил в командную строку и все. Если сервер можно поднимать как на винде, так и на линуксе, дублируем инструкции одна для Windows, другая для Linux. И везде даем примеры команд.

Разумеется, если вам попадется прошаренный админ это будет счастье великое. Но крутой по простой инструкции пройдет, а джуниор по инструкции для крутых нет. Выводы?

В идеале, конечно, ставим на голом сервере докер и не паримся с операционными системами и настройками. Выдали готовый докер-файл, готово!

Но бывает и так, когда докер ставить нельзя. Служба безопасности не одобряет: Мало ли, что вы в этом докере на сервер установите? Нет-нет, давайте инструкцию по развертыванию с нуля, мы сами всё настроим.

Тогда инструкция будет сильно больше! Что может в нее входить:

Подготовка к развертыванию

  • Методика расчета требований к аппаратному обеспечению будьте уверены, вас обязательно спросят, откуда такие требования к железу. Проще один раз записать, чем каждый раз снова объяснять.

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

  • Требования к настройке программно-аппаратной платформы об этом чуть ниже

Требования к настройке какие программы установить, какие права доступа выдать. Соберите всю информацию в одном месте:

  • Настройка рабочей станция для ваших сотрудников

  • Настройка сервера приложений для ОС *nix

  • Настройка сервера приложений для ОС Windows

  • Настройка сервера СУБД Oracle

  • Настройка сервера СУБД MariaDB

  • Настройка Active Directory

  • ...

Видите? Windows отдельно, Linux отдельно. Если умеете работать с разными базами данных напишите под каждую отдельную статью.

Инсталляционный пакет

Описание файлов, которые подрядчик передает заказчику, с их описанием.

Установка системного и специального ПО

Например, продукт написан на Java, а сервер приложения Wildfly. Тогда здесь будут примерно такие разделы:

  • Установка параметров ОС Windows

  • Создание пользователей ОС Linux

  • Установка параметров ОС Linux

  • Установка Java

  • Установка Wildfly

Каждая статья подробно расписывает, как выполнить установку. И не забывайте о примерах!

Установка системы

Инструкция по установке системы.

Запуск системы

Короткая инструкция, в которой прописаны команды для запуска и остановки системы.

Что-то ещё

Может быть ещё целая куча документации:

о том, как настраивать систему ПОСЛЕ установки;

о дополнительных настройках типа шифрования паролей, горячего резерва, и прочего.

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

9. Описание полей

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

Вот, например, регистрация в Дадате:

Зачем указывать имя? Чтобы к вам обращались в письмах по нему.

Зачем указывать почту? Чтобы мы могли прислать состояние обработки и баланс.

Все эти подписи это тоже документация! Не надо думать, что документация это только документы про работу системы, вынесенные отдельно. Нет! Это и сообщения об ошибках, и текст на главной странице, на кнопках, в подписях к полям... Это все тоже документация.

10. Маркетинговые материалы

Рассылки, которые вы шлете пользователям.

Статьи на Хабре или другом ресурсе.

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

Еще один вариант рекламы какой-нибудь купон, который вылезает на сайте или в мобильном приложении.

  • Вычитываем текст, чтобы не было ошибок.

  • Если это поп-ап окно, проверяем, что его можно закрыть.

  • Если это всплывашка в мобилке, проверяем, не вылезает ли она за экран на небольшом смартфоне.

11. Обучение FAQ, презентации

Обучающие материалы это тоже документация. И снова они бывают самых разных видов, зависит от типа продукта и бюджета.

Tutorial

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

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

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

FAQ

Одна или несколько статей, где собраны ответы на типовые вопросы.

F1

Документация из серии Помощь.

Online help

Если у вас есть робот-помощник с зашитыми в него скриптами это тоже документация!

Обучающие статьи

Они могут быть в закрытом или открытом доступе. Это то, где вы рассказываете, как сделать ту или иную вещь с помощью вашей программы.

Если статья открытая, то туда может вести ссылка прямо с сайта.

Если статья закрытая, вы даете к ней доступ только своим клиентам. Она может быть в вашей вики-системе, ворд-файле или гуглодоке.

Видео

Если у вас есть видео в помощь их тоже надо тестировать на устаревание!

Это может быть полноценное видео или кликабельные слайды, такие можно сделать в Wink.

Презентация

Это может быть:

продающая презентация что умеет наш продукт;

обучающая презентация как им пользоваться.

И этотоже документация, которую надо тестировать:

  • Выдержан ли стиль компании в презентации?

  • Актуальны ли картинки? Не менялся ли интерфейс?

  • Насколько полно раскрыта тема? Может, стоит что-то добавить?

Я и сама проводила обучение сотрудников заказчика. Тестировщику вообще очень полезны такие поездки поговорить с теми людьми, которые будут использовать ваш продукт, послушать их вопросы... И понять, что для них важно!

Так вот, после каждой поездки я переделывала свою презентацию. Где-то вопросы задавали, где-то сама во время обучения подумала о, стоит еще рассказать вот о чем. Это процесс постоянных улучшений, не стоит думать, что презентацию сделаете один раз и все готов. Тестируйте ее, дорабатывайте и улучшайте!

12. Поздравляшки

И снова это касается в первую очередь игрушек. Такая ностальгия по тем временам, когда я именно игры для мобильников и тестировала.

Так вот, когда вы заканчиваете уровень или всю игру, вылезает поздравляшка. Обычно этот всплывающее окно с текстом Поздравляем!. Еще чаще текст будет английским Congratulations!.

Английская версия длиннее, отсюда могут возникнуть проблемы разряа сообщение вылезло за экран телефона. Конечно, сейчас уже нет тех экранчиков, на которых тестировала я (старый siemens, например, с диагональю 3 дюйма). Но и среди смартфонов встречаются малыши, их стоит проверить!

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

13. Кнопки

Текст на кнопках тоже документация! Вроде очевидно, но все же. Я, например, сталкивалась и с таким:

Как можно пропустить такой баг? Ведь регистрация в интернет-магазине основной кейс, потому что без нее пользователь не может продолжить покупки. Значит, ее тестируют. Видимо, у всех так замылился глаз уже, что подписи на кнопках просто не читают... А вы читайте! =)

Раз уж столкнулась с такой проблемой, то вот, решила вынести ее в отдельный пункт. Не забывайте всё читать, не по диагонали, а целиком.

14. Остальное

Документации очень много. Это все, что видит пользователь и что может показаться неочевидным:

Гарантийный талон это тоже документация (которую редко читают, но всё же). Он обычно встречается у бытовой техники или компьютера.

Пользовательское соглашение / оферта а это то, что заменяет нам договор или гарантийный талон в современном ИТ-мире. Пользуясь онлайн-сервисом, вы автоматически соглашаетесь с офертой, которая есть у него на сайте, даже если вы ее не читали ))

Упаковочный текст и графика помните, раньше игры покупали на DVD в специальных магазинах? Так вот обертка диска, текст и графика на нем это тоже документация, которую надо проверять!

А то вдруг у вас слишком завышенные требования к железу и никто не купит диск?

Или вдруг требования занижены и игра просто не запустится на слабом компьютере? Тогда рассерженный пользователь вернется в магазин и будет требовать назад свои деньги.

Итого

Видов документации очень много! Она не ограничивается только лишь требованиями )) Не забывайте про остальную документацию на проекте. И обращайтесь к этому чек-листу за поиском вдохновения что я ещё забыл проверить =)

Самые важные виды документации:

  • ТЗ требования

  • Пользовательская документация

  • Примеры

  • Сообщения об ошибках

Чуть менее, но все еще важно:

  • Предупреждения о том, как заполнять поле

  • Описание поля (зачем мне его заполнять?)

  • Предзаполненный текст в поле ввода

  • Инструкция по установке

  • Маркетинговые материалы

  • Статьи на Хабре или где-то еще

  • Обучение материалы

  • FAQ

  • Online help

  • Презентации

А еще есть:

  • Пользовательское соглашение / оферта

  • Гарантия

  • Упаковочный текст и графика

Это тоже нужно проверять, но уже не в приоритете!

PS больше полезных статей ищите в моем блоге по метке полезное. А полезные видео на моем youtube-канале

Подробнее..

Чек-лист тестирования требований

19.02.2021 22:06:58 | Автор: admin

Когда разрабатывается новая функциональность системы, аналитик пишет требования, а тестировщик их проверяет. До того, как начать реализацию. Потому что на этом этапе внести исправления дешевле всего.

Вот только на что обращать внимание при тестировании? Есть набор основных характеристик, которыми должна обладать хорошая документация:

  1. Полнота

  2. Однозначность

  3. Непротиворечивость

  4. Необходимость

  5. Осуществимость

  6. Тестируемость

Конечно, их может быть и больше. Кто-то использует мнемонику CIRCUS MATTA, кто-то расширяет список под себя и команду. Но эти шесть характеристик основные. О них и в книгах по тестированию пишут, и в самых разных статьях.

В этой статье я расскажу о каждой из них поподробнее, с картиночками и примерами из жизни.

1. Полнота

Все ли описано? Ничего не забыли? Вдруг у нас остался неописанный функционал или параметр API-метода?

Чтобы проверить этот пункт, просто напишите чек-лист проверок функционала. Вот как начали читать ТЗ, сразу записывайте тесты. Важно именно писать, а не просто прикидывать в уме. Иначе что-то обязательно забудете.

Как-то раз мне прислали на проверку ТЗ на новый функционал. Да, по хорошему надо сразу прикинуть тесты, которые буду писать. А это надо взять ручку, блокнот и начать тест-дизайнить... Но я занималась другой задачей, а ТЗ надо проверить сегодня, чтобы отправить оценку заказчику.

Поэтому решила проверить мысленно. Читаю пункт ТЗ, прикидываю, какие могут быть тесты. В итоге задала парочку уточняющих вопросов:

А что, если... ?

У Заказчика уточнили, документацию пополнили! В остальном меня всё устроило, вроде нормально описано, всё учтено.

Заказчик согласовал ТЗ, разработчик сделал. Пришло время тестировать. Начинаю писать автотесты и... Да, разумеется, сразу получаю еще 5-10 дополнительных вопросов. В ТЗ не были предусмотрены все сценарии, и я о них тоже не подумала, пока прикидывала тесты мысленно.

А как только стала расписывать план автотестов, сразу увидела белые пятна. При этом у меня 10 лет опыта в тестировании. Не полагайтесь на память и быстренько мысленно прикину, выделите полчаса и распишите чек-лист проверок подробно.

Чем плохо отложить вопросы на потом? Не слишком профессионально согласовать требования, которые написала твоя команда, а через пару недель задавать уточняющие вопросы. Заказчик подумает: а чего сразу не спросили?

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

Да, написать тесты это дольше, чем просто прочитать документацию. Но зато вы экономите время потом, ведь чек-лист уже готов, бери да проверяй!

2. Однозначность

Требования должны трактоваться всеми одинаково.

Отчет должен загружаться быстро что значит быстро?

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

  • разработчик прикинет, что в таких объемах 5 секунд нормальное время отклика, даже быстрое.

Налицо конфликт интересов. И ведь каждый будет тыкать в ТЗ для отстаивания своей позиции. Лучше конкретизировать:

  • Отчет за год должен загружаться не более секунды.

  • Отчет за весь период времени должен загружаться не более 5 секунд.

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

  • Аналитик будет думать, что там будет значение 0. Деньги же, цифра!

  • Разработчик сделает пустое поле, не указано ведь ничего! А это что-то сломает...

Если в требованиях не указано, как обработать ошибочный сценарий, разработчик может:

  • Не подумать о нем и никак не обработать пользователь может огрести страшную ошибку.

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

Все, что можно прочитать двояко, лучше исправить. Это не значит, что нужно описывать каждую мелочь, но всё зависит от читателей документа.

Если это внутренний документ, а у вас сильная команда можно не расписывать подробно.

Если этот документ отправят заказчику, надо расписать вообще всё потому что у заказчика свои тестировщики, и они обязательно зададут кучу а что, если...?. Если они хорошие тестировщики, разумеется. Это вы знаете свою программу и представляете, как она реагирует на ошибки или что-то такое. Тестировщик заказчика этого не знает, он будет уточнять.

3. Непротиворечивость

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

Например, есть страница нефункциональных требований, где написано, что любая страница должна грузится не более 3 секунд. Аналитик пишет ТЗ на новый модуль отчетности, который использует много данных и сложные формулы. И он пишет, что отчет может грузиться вплоть до минуты. Явное противоречие!

Если заказчик найдет первый раздел документации, он будет требовать именно такую скорость. И будет прав, кто же хочет ждать?)

4. Необходимость

Помните главный принцип: Кратко, но емко? Он действует и в документации тоже.

Круто, когда документация полная. Но это не значит, что простой функционал надо растечь на 10 листов А4. Когда документации много, сложно проверить полноту, сложно удержать в голове, о чем уже говорил, не повторяться и не противоречить самому себе.

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

Пишите только то, что необходимо:

  • В ТЗ функционал, основной сценарий и альтернативы, типы ошибок.

  • В пользовательской документации то, как пользоваться системой. Но не доходя до крайностей и обучения включению компьютера.

5. Осуществимость

А можно ли реализовать то, что тут написано? Насколько это будет сложно и дорого?

Этот пункт обычно проверяют разработчики. Они остужают буйные фантазии из серии загружать миллионы данных за 0,1 секунду или что-то архитектурно сложное. Бывает такое, что на бумаге всё звучит просто, а вот сделать это займет человеко-месяц в лучшем случае.

В одной из систем, с которыми я работала, был точечный поиск. Не просто найди мне все данные, где встречается Ленина, а именно найди мне адреса, у которых улица Ленина. Это отсеет фамилию Ленина, комментарий к телефону и другие нерелевантные данные.

Но вот беда нельзя поискать по двум параметрам ОДНОГО атрибута. Если сказать Найди мне домашний адрес с улицей Ленина, система вернет:

1. Васю: домашний адрес с улицей Ленина.

2. Петю: домашний адрес с переулком Турчанинов и рабочий с улицей Ленина.

Почему так?

Это баг в системе? Или просто нельзя сделать такой поиск, это неосуществимо? Нужно смотреть по коду.

В той системе для поиска использовали Lucene. Его можно настроить по-разному:

o поиск по любому полю;

o поиск по конкретному полю;

o множественный поиск по конкретному атрибуту (в одном адресе проверить и тип, и улицу);

o ...

Но! Чем сложнее сценарий поиска, тем медленнее он работает. Дольше сохраняет данные (потому что структура внутри усложняется), дольше ищет или потребляет больше ресурсов для той же скорости.

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

Осуществимо желание отсеять Петю? Да. Но это просто не нужно. Потому что вреда принесет больше, чем пользы. Ради того, чтобы в выборку из 1000 человек не попали 10 лишних, платить несколько миллионов за дополнительные мощности серверов смысла просто нет.

6. Тестируемость

Можно ли протестировать этот функционал?

Подумайте об этом заранее. А то бывает так, что разработчик уже всё сделал, и тут только тестировщик понимает, что задачу никак нельзя проверить. Или можно проверить вручную, но нельзя написать автотесты, фреймворк под новый функционал не заточен.

Если в компании принято все покрывать автотестами, то это станет проблемой. Может, разработчик прочитает ТЗ и сам поймет, что ещё фреймворк тестов дорабатывать надо. А может, он не вспомнит об этом. И тогда ваша задача вспомнить. Чтобы сразу заложить время на доработки.

У меня бывали ситуации, когда мы делали задачу в текущем релизе, а потом ставили новую Доработать фреймворк автоматизации, чтобы поддержать изменения в следующий. Иногда забывали про фреймворк, а потом времени в релизе уже не оставалось. А иногда сразу понимали, что всё сразу сделать не успеем.

Иногда про тесты не думаешь, так как уже есть похожие. Например, у нас давно были автотесты на обратный поток в JMS-очередь. А потом для одного из заказчиков мы сделали обратный поток в две JMS-очереди.

Сначала я не подумала о доработке автотестов ведь возможность проверить что ушло есть! А когда добралась до тестирования, пошла к разработчику:

А как мне указать вторую очередь? Или папка jms это то, что в обе уйдет?

Хм, нет, погоди, это только в старую. Надо доделывать фреймворк, поддержать разные очереди.

Ну и ничего, доделали, написала тестов!

Хотя лучше об этом помнить сразу, иначе велик шанс, что тестировать за вас придется разработчику. Или половину проверок переносить на следующую итерацию, что тоже не очень хорошо.

При этом бывает и так, что тестировать все равно придется разработчику. Скажем, когда делают рефакторинг, что может проверить тестировщик? Только регресс провести, посмотреть, что ничего не отломалось. А если есть автотесты, то это проверят они =)

Однако если тесты (авто или ручные) прошли успешно, это ещё не значит, что рефакторинг прошел хорошо. Сама суть рефакторинга переписать код, чтобы он был более оптимален и читабелен. Чтобы его было легче поддерживать в дальнейшем и интегрировать с другими частями системы.

И именно это и надо проверить! А проверить это может только разработчик. Он и выполняет тестирование в данном случае.

Бонус: мнемоника CIRCUS MATTA и другие доп материалы

CIRCUS MATTA мнемоника для ревью пользовательских историй. Это как раз про тестирование требований! Истории должны обладать качествами:

  • Completeness полнота

  • Independent независимость

  • Realisable реализуемость

  • Consistency консистентность

  • Unambiguity однозначность

  • Specific специфика заказчика

  • Measurable измеримая

  • Acceptable приемлемая

  • Testable тестируемая

  • Traceable трассируемая (можно проставить взаимосвязи)

  • Achievable достижимая

Вон сколько пунктов получилось! Мне особенно импонируют пункты специфика заказчика и трассируемость. Это и правда важно. Если у вас коробочный продукт, который кастомизируется под заказчика, обязательно смотрите на пункт Specific. А трассируемость очень хороший бонус, облегчающий поддержку документации в актуальном состоянии!

См также:

Тестирование документации к программным продуктам тут целых 18 критериев хорошей документации!

Тестирование требований. Особенности статья от Лаборатории Качества.

Подробнее..

Как сделать текст легче

27.11.2020 10:16:55 | Автор: admin

В прошлой статье я обещала, что расскажу, как сделать документы легче для восприятия. Есть два основных направления: текстовка и структура документа. Сегодня поработаем с текстами. Технические документы на русском читаются особенно тяжело, и добиться легкости в них сложнее, чем в английском. Как можно исправить многословные, громоздкие документы? Давайте попробуем сделать их конкретнее, проще, короче, и последовательнее.



Конкретнее


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


Целевая аудитория кажется каким-то внешним фактором, не влияющим на документы, но это не так. Очень много проблем в доках решается именно отсылкой к ЦА. Например, насколько понятен этот текст? За всех мы сказать не можем: мне, например, понятен, а вот ему не очень. Так мы далеко не уедем, нужно какое-то решение. А именно: понятно ли это для целевой аудитории? Рассмотрим пример.


Я писала документы для Acronis Cyber Infrastructure, это когда из серверов делают кластер, а его используют для storage и virtual machines. Упрощенно, этот продукт рассчитан на enterprises, в частности, на сервис-провайдеров. ЦА документов системные администраторы, и не самые простые. Обыкновенному человеку они будут непонятны. Но это не bug, это by design. Если бы мы писали эти доки для обычных пользователей, то:


  1. Нужно было бы объяснять все концепты storage и HCI очень подробно и понятно. Такой dummy guide, для чайников.
  2. Нельзя было бы использовать общепринятые термины сферы, нужно было бы упрощать и описывать. Например, вместо node, возможно, был бы server, потому что это слово более употребимо и понятнее всем, хотя оно не передает роли сервера в кластере.

Короче говоря, это были бы совсем другие документы.


Плохо, когда для доков не определена ЦА. Начинаются метания: а это достаточно понятно? А это не слишком элементарно? К вопросу о ГОСТах и ЕСПД. Там как раз часто целевая аудитория люди, которые почти не умеют пользоваться компьютером. Сейчас таких мало. Поэтому документ на обычного современного юзера, написанный по ЕСПД, может получиться очень тяжелым, перегруженным ненужными деталями. Зато, вероятно, в момент написания ГОСТов он четко попадал бы в ЦА.


Заметки на полях


  • В начале документа неплохо иметь раздел Target audience, чтобы было сразу понятно, для кого написан документ. К сожалению, часто там написано: Для всех, кто читает этот документ или использует наш продукт. Если вам попадется нормальный раздел, где четко описана целевая аудитория, скиньте, пожалуйста, в комменты, с удовольствием почитаю.
  • Иногда документ рассчитан на более-менее общую аудиторию, но есть пара сложных моментов для знатоков, например, какие-то хитрые настройки. Такие вещи можно убирать в knowledge base.
  • Даже если вы пишите доку для админов и сразу это обозначаете в разделе Target audience, все равно придут люди, которые вообще не шарят. И они станут писать вам: А что это? А это? А почему так сложно? Будьте готовы.


Проще


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


Было


Для установки программы необходимо запустить исполняемый файл wizard.exe и следовать указаниям мастера установки.


Стало


Чтобы запустить мастер установки, дважды нажмите на файл wizard.exe.


Было


В этом окне можно установить флаг для создания значка (ярлыка) на рабочем столе, который может быть использован для запуска ПО на выполнение. После задания значения флага следует нажать кнопку Далее.


Стало


При необходимости, установите флажок Создать значок на рабочем столе. Нажмите Далее.


Заметки на полях


  • Совершенно спокойно можно убирать из доков описание общих свойств элементов GUI. То есть если вы описываете таблицу, а в ней (ничего себе!) можно поменять ширину столбцов перетаскиванием границы, это писать необязательно. Реальный пример: Размеры частей окна и ширина колонок могут быть изменены путем перемещения разделительных полос левой кнопкой мыши. Положение окна можно изменить перемещением строки заголовка с помощью левой кнопки мыши (ЛКМ).
  • Иногда исходный текст настолько запутанный, что даже не знаешь, с какой стороны подступиться. Самое сложное здесь понять, что же имеется в виду, а уже с пониманием будет легче подобрать простые слова. Обычно такие тексты просто нужно переписать начисто. Вот, поломайте голову над таким примером: Пользователь имеет возможность изменить положение объекта вручную, перетащив его с помощью ЛКМ в удобное положение. Существует два способа изменения положения объекта. 1-ый способ заключается в свободном перемещении, когда можно выбрать любую позицию для установки объекта. 2-й способ, когда позиция имеет фиксированное место с дискретным углом 45 и фиксированным удалением от точки пересечения графика с визиром.


Короче


Недавно на одном из вебинаров услышала очень точную фразу: Каждое слово, которое вы пишите, пользователь читать не хочет. Согласна на 100%. Но при этом, признаюсь, мне знакомо чувство, когда хочется еще дописать, и еще немного объяснить, и повторить то же другими словами, ну, чтобы точно дошло! Борюсь с этим чувством, и вам советую.


Сделать текст короче это не совсем то же самое, что сделать его проще. Когда мы упрощаем текст, мы убираем лишние технические детали. А когда мы сокращаем его, мы убираем фигуры речи и лишние обычные слова. Например, если пункт 2 идет после пункта 1, не нужно писать После выполнения пункта 1. Или вместо следует нажать лучше писать нажмите.


Было


После выполнения указанных действий в режиме Р для печати билета с одним из запрограммированных тарифов от 1 до 9 достаточно нажать соответствующую цифровую клавишу. Билет будет автоматически отпечатан.


Стало


Чтобы напечатать билет с запрограммированным тарифом от 1 до 9, нажмите на соответствующую цифру.


Часто в русских инструкциях попадаются длинные абзацы сплошного текста, которые нужно разбить на несколько абзацев и сократить. Посмотрим на большой абзац, в котором спрятана инструкция. Процедура на несколько шагов сплошным текстом, еще и с нарушением логического порядка это боль. Но все поправимо. Разбиваем на шаги, упорядочиваем по логике и вуаля!


Было


Для обновления, нужно временно скопировать файл Ф на компьютер с ПО, обновить программой П (указать путь к файлу Ф), затем скопировать файл обратно на сетевой ресурс. Перед началом обновления, необходимо убедиться в достаточном количестве свободного места на диске, где расположен файл Ф, это необходимо для создания резервной копии. Объём свободного места должен быть не менее размера обновляемого файла. Если свободного места недостаточно, программа выведет соответствующее сообщение.


Стало


Обновление


  1. Убедитесь, что на диске, где расположен файл Ф, достаточно места для создания резервной копии.
  2. Скопируйте файл Ф из сетевого хранилища на компьютер с программой П
  3. В программе П укажите путь к файлу Ф и обновите его.
  4. Скопируйте обновленный файл Ф обратно в сетевое хранилище.


Заметки на полях


  • Когда мы работаем с большими абзацами сплошного текста, нужно помнить про visual effectiveness. Слишком много букв подряд и читать уже сложно. Иногда достаточно разбить на шаги или абзацы, а иногда можно подумать про схему. Толковая схема решает. Но чтобы сделать толковую схему, нужно понимать суть процедуры от и до. Здесь может пригодиться помощь разработчика или program manager.


Последовательнее


Технический писатель человек творческий, поэтому названий для одной и той же операции может быть много: нажать, щелкнуть, кликнуть, и все в одном документе. И помножим это на количество творческих людей, работающих над одним документом. Я за консистентность. Одна и та же операция должна называться одинаково. Если вам нравится Щелкнуть, то так и пишите везде. Если Нажать аналогично. Выберите подходящий термин и последовательно применяйте его везде. А еще лучше, заведите корпоративный глоссарий, хотя бы на русском, и там пропишите нужные фразы. +500 к консистентности, и еще помогает новичкам быстрее освоиться.


Заметки на полях


  • Иногда непонятно правильное название чего-то на русском, но известно его английское название. Например, у нас есть нода, от английского node. Как найти верное русское слово? Можно зайти на глоссарий Microsoft. Там выбираем английский исходный язык и русский язык перевода, вводим слово на английском, и смотрим предложенные варианты на русском. Получаем узел.
  • Если уж решились сделать документы последовательнее, эти правки должны быть применены повсеместно. Иначе какой смысл? Обычно такие изменения затрагивают больше всего текстов. Поэтому здесь нужно правильно рассчитать сроки и затраты. И особенно важно не забыть про локализацию, ведь для них это означает очень масштабное изменение в нескольких языках сразу.
  • Когда в документах то disk, то drive, это не очень хорошо. Но когда то же самое в GUI, это совсем плохо. Поэтому на GUI смотрим особенно внимательно и запоминаем все варианты, которые потом нужно будет править.


Ресурсы


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


  • Слово живое и мертвое Норы Галь. Классика.
  • Живой как жизнь Корнея Чуковского, глава Канцелярит. Классика.
  • Пиши, сокращай Максима Ильяхова. Свежий взгляд на старые проблемы +очень практичный подход. Здесь подробно описано, как именно можно сократить тексты.
  • Developing Quality Technical Information: A Handbook for Writers and Editors от Gretchen Hargis и др. Здесь много про цели, задачи, ЦА документов. А еще хорошие примеры и практичные советы.

PS. Отдельная тема почему английский такой краткий, четкий, и понятный по сравнению с русским. Хотя, например, испанский тоже так себе в легкости, не лучше нашего. Но это уже языковедение. Пока ходить туда не будем, если нужно, напишите в комментах.
Подробнее..

Как мы в Активе пишем пользовательскую документацию. Почему это важно

14.07.2020 06:19:36 | Автор: admin

Что пользователь хочет видеть в пользовательской документации? Что его в ней раздражает? Эти вопросы задаёт себе каждый, кто пишет такую документацию, но далеко не каждый правильно отвечает на них. Совсем небольшой процент пользователей читает документацию. Давайте разберёмся, почему так и как сделать пользовательскую документацию эффективной и изменить отношение пользователей к ней.



Нам мешает негативный опыт


С такой ситуацией сталкивался почти каждый: вам надо быстро освоить какую-то ИТ-систему, она очень сложная, и в ней хранятся важные данные. Метод проб и ошибок здесь не подойдёт. Наверняка в такой момент вы вспомнили про руководство пользователя, открыли его и начали внимательно изучать. После 10 минут чтения вы ещё больше запутались, закрыли руководство и начали осваивать систему, используя при этом метод будь что будет. И хорошо, если при этом вы не удалили что-то очень важное и не получили результат, о котором будете жалеть, а ведь всякое бывает.


Да, через какое-то время вы всё-таки освоили систему и ловко жонглируете её процедурами, но чего это вам стоило? Вы потратили время, нервы и может даже не только свои. Что решило бы вашу проблему ещё на раннем этапе?


Ответ один хорошая пользовательская документация.


Документация может всё


Пользовательская документация не только помогает быстро разобраться в ИТ-системе, она формирует позитивный пользовательский опыт и тем самым укрепляет репутацию продукта и компании в целом. Но не стоит забывать и о противоположной ситуации: плохая пользовательская документация помешает пользователю разобраться в ИТ-системе, сформирует негативный опыт и разрушит репутацию продукта и компании. Верю, что эта мысль понятна всем и здесь ничего не надо объяснять.


Давайте представим, что у вас уже есть документация. Вы видите, что пользователи её просматривают. Наряду с этим, количество звонков в техподдержку не уменьшается, и пользователи чаще всего спрашивают о том, что уже давно описано в документации. Почему так? Причин может быть много, я разберу только те, которые связаны именно с пользовательской документацией.


Это будет цикл статей, в которых я расскажу вам про основные ошибки в технической документации, мы посчитаем, сколько они стоят компании. Я объясню поведение пользователя, обозначу, с какими трудностями и эмоциями он сталкивается, когда читает плохой документ. Покажу, как можно исправить ошибки с минимальными затратами. Мои статьи для всех, кто пишет документацию и хочет делать это более осознанно, с заботой о пользователе. Если вы хоть в чем-то будете со мной не согласны, то пишите свои мысли в комментариях. Мы вместе можем сделать эту статью максимально полезной.


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


В этой статье я расскажу вам о том, сколько в нашей компании стоит пользовательская документация, и из каких этапов у нас состоит процесс документирования. Lets go!


Сколько стоит пользовательская документация


Документация стоит денег, давайте разберёмся каких. Если в компании есть технический писатель, то стоимость документации не измеряется только его заработной платой. Расскажу, почему это так.


Рассмотрим на примере инструкции, которую можно написать за 20 часов. Технический писатель за это время напишет 25-страничный документ, в котором будет около 40 скриншотов.


Весь процесс производства инструкции в нашей компании состоит из следующих этапов:


1. Поставка задачи. Её создаёт и описывает менеджер проекта, руководитель проекта или руководитель отдела. На это нужно время, недостаточно просто написать Опиши процедуру. Здесь обязательно нужны детали. Например, здесь посчитаем 1 час рабочего времени менеджера проекта. На этапе постановки задачи менеджер проекта назначает консультанта и обозначает круг сотрудников компании, которые могут помочь и объяснят какие-то важные особенности системы. Получается, что цель этого этапа сформулировать задачу и назначить консультанта



2. Показ системы. Чаще всего здесь задействован системный аналитик, он демонстрирует систему техническому писателю и рассказывает, что и как работает. Прибавим 2 часа работы аналитика + 2 часа технического писателя. Здесь аналитик рассказывает, а технический писатель слушает и задаёт вопросы. Если система сложная, таких встреч может быть несколько. Цель этого этапа объяснить техническому писателю, как работает система.



3. Написание документа. Здесь главную роль играет технический писатель, но нельзя забывать про вопросы, которые у него могут возникать в процессе написания. Отвечать на них может аналитик, разработчик, менеджер проекта, тот, кто разбирается в продукте и умеет понятно объяснять. Таких вопросов может быть много и хорошо, если технический писатель оперативно получает на них ответы. Прибавим 20 часов работы технического писателя + 1 час работы аналитика + 1 час работы разработчика. Цель этого этапа создать первую версию инструкции.



4. Рецензирование. Чаще всего читает документ заказчик, в нашем случае менеджер проекта. На это тоже нужно время, оно зависит от количества страниц в документе и качества описаний. Прибавим 2 часа работы менеджера проекта. На этом этапе он пишет комментарии к документу. Цель этого этапа проверить документ.



5. Внесение правок. Реализует технический писатель, на этом этапе он тоже может задавать уточняющие вопросы коллегам. Техническому писателю здесь очень важно правильно понять комментарии к инструкции. Прибавим 2 часа работы технического писателя + 1 час работы аналитика. Цель этого этапа создать вторую версию документа.



6. Тестирование. На этом этапе подключается сотрудник отдела тестирования. Он реализует все описания процедур и оценивает насколько корректно они описаны. Прибавим здесь 2 часа работы тестировщика. Цель этого этапа проверить корректность описания процедур.



7. Повторное внесение правок. Технический писатель получает от тестировщика комментарии и вносит изменения в инструкцию. Прибавим 1 час работы технического писателя. Цель этого этапа создание третьей версии документа.



8. Вёрстка документа. Здесь может подключаться дизайнер. Если вёрстка не очень сложная, то технический писатель делает её сам. Прибавим 4 часа работы дизайнера. Цель этого этапа сверстать документ так, чтобы его было удобно использовать.



9. Публикация документа. Мы публикуем документ на своём сайте на специальной странице. Прибавим 20 минут работы администратора сайта.



Итого:


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


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


100 тысяч рублей или долларов


Вы видите, что технический писатель не один участвует в создании инструкции. Здесь не обязательно называть какие-то точные цифры. Документация стоит денег и ошибки в ней тоже. Именно поэтому её нужно сразу писать так, чтобы она решала задачи пользователя, приносила ему пользу, а не была чем-то бесполезным и просто пылилась на полке.


Сейчас, если в любом поисковике ввести слова руководство пользователя, то за 5 минут просмотра результатов вы найдёте как минимум 5 плохих документов и один хороший, а это совсем мало. Получается, что только каждый шестой документ является эффективным, а представьте сколько времени, денег потрачено впустую и надо здесь что-то менять. Давайте делать это вместе, так будет проще обратить внимание всех на эту проблему.


В следующей статье я расскажу про ошибки в документации. Отвечу на вопросы:


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

See you soon!

Подробнее..

Как мы снимаем видеоинструкции для решений Рутокен

20.01.2021 10:13:24 | Автор: admin

Мы решили продолжить наш цикл статей про разработку пользовательской документации, но на этот раз нам захотелось рассказать еще об одном способе создания инструкций для пользователей это съемка видеороликов. Мы расскажем о процессе их производства: от возникновения идеи до загрузки ролика на YouTube-канал. У нас нет студии и профессиональных актеров, мы все делаем сами и хотим показать вам, что это не так сложно. Здесь вы найдете: идеи, готовые алгоритмы и, быть может, вдохновитесь на съемку своей видеоинструкции.

Когда обычной инструкции не достаточно

Иногда уже в процессе написания обычной инструкции понимаешь, хорошо бы показать какие-то процессы в видео. Например, если лампочка на устройстве, котором мы описываем, мигает несколько раз или меняет цвет. Да, можно написать если лампочка устройства мигает три раза, а потом гаснет, то устройство не работает. Вроде как всё понятно, а если лампочка не просто мигает, а несколько раз меняет цвет, то такое уже будет сложнее объяснить при помощи текста.

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

Мы расскажем, как снимать ролик на конкретном примере. У нас недавно вышло новое устройство и возникла необходимость показать нашим пользователям его уникальные возможности: работу через контактный и бесконтактный интерфейс. Лучше всего, нам кажется, это можно сделать в видео.

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

Что делает пользователь с обычной инструкцией? Он не читает ее полностью, а находит необходимый раздел и выполняет описанную в нем процедуру. А это значит, что он будет искать обычную инструкцию в том случае, когда смарт-карта у него уже есть, и наша обычная инструкция будет полезной только для существующих пользователей и вряд ли поможет нам привлечь новых. А смарт-карта новая она еще мало у кого есть. Вряд ли пользователь, который еще не купил эту смарт-карту, будет читать инструкцию на 20 страниц, ему проще посмотреть небольшой ролик и понять, что это за устройство.

Все начинается с идеи и оценки ее реализации

Идея пришла уже после написания инструкции, но далеко не все подобные идеи заканчиваются реализацией. Ведь производство ролика стоит дороже написания инструкции и необходимо было осознать, действительно ли рационально сейчас тратить на это ресурсы компании. И мы задали себе вопрос: кому кроме наших пользователей может пригодиться такая видеоинструкция? Ее глобальная цель привлечь внимание к новой смарт-карте, поэтому она точно пригодится нашим менеджерам, они смогут отправлять ролик потенциальным заказчикам. Ещё такой ролик или его фрагмент можно показывать на презентации устройства, вставить в пресс-релиз и добавить в новостную ленту в социальных сетях. А этого уже достаточно для того, чтобы запустить процесс его производства. Ну и не стоит забывать про очевидную цель загрузить новый ролик на YouTube-канал, чтобы наши подписчики про нас лишний раз вспомнили. У вас цели могут быть другие.

Кто нужен для производства видеоинструкции

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

  • Руководитель проекта или продукта. Как вы уже догадались, того продукта, для которого мы будем снимать ролик.

Зачем он нам: сформулировать цель ролика, ответить на вопросы в процессе написания сценария, вычитать сценарий и оценить ролик.

  • Технический писатель. Тот, который писал инструкцию для нашей смарт-карты. Он уже многое знает и напишет сценарий быстрее, чем любой другой, кому придется разбираться в этой теме. Зачем он нам: написать сценарий и снять видео с экрана своего компьютера. Также, если в видео есть реальные кадры, то нарисовать раскадровку для видеооператора. Это идеальная картина, бывает так, что технический писатель и режиссер, и оператор, и монтажер.

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

  • Монтажер. У нас это тот, кто писал сценарий, он собирает весь ролик. Видеооператор может помочь ему выполнить какие-то сложные моменты. В этот раз они были: нам надо было показать одновременную работу смарт-карты в двух мобильных операционных системах.

  • Человек, записывающий закадровый голос. У нас это реальный сотрудник технической поддержки, его голос знаком нашим пользователям. Он записывает закадровый голос для ролика.

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

Маркетолог. Он смотрит финальную версию и загружает ее на YouTube-канал.

Вроде никого не забыли. Да, многое может делать один человек и для каких-то роликов достаточно только заказчика и исполнителя.

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

Сколько времени нужно на производство ролика

Со сроками тоже все интересно. Если рассказывать про обычную инструкцию, то мы понимаем примерно сколько это займет времени, с видео сложнее. Оно может совсем не понравиться и какие-то моменты придется переснимать, а потом и заново монтировать. По опыту, на ролик продолжительностью 5 минут в среднем нужно 6-8 рабочих дней, это время на весь цикл производства. И надо понимать, что иногда этот срок растягивается в два и в три раза. А бывает, когда все сразу удачно складывается и требуется меньше времени.

Что нужно из оборудования

  • Компьютер. На нем производится запись необходимого материала с экрана, хранятся все файлы для видео и монтируется ролик.

  • Штатив. На него можно закрепить мобильный телефон для съемки живых кадров.

  • Мобильный телефон. На него, как вы уже догадались, можно снимать живые кадры. Когда есть возможность позвать в этот проект видеооператора, штатив и мобильный телефон не нужны, так как процесс съемки обеспечивает видеооператор.

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

  • Монтажная программа. В ней мы монтируем и собираем видео. У нас их две: для простого линейного монтажа мы используем программу Movavi, а для более сложного Adobe Premiere Pro. Первая очень простая и быстрая в освоении. Конечно необходимо, чтобы все используемое ПО было лицензированным.

  • Много памяти на компьютере и мощный процессор. Чтобы сохранять все файлы для ролика и быстро его собирать. Файлы для ролика занимают в разы больше места, чем обычная документация.

  • Программа для обработки звука. В ней мы обрабатываем звук. Можно установить специальную, а можно использовать возможности программы Adobe Premiere Pro.

  • Текстовый редактор. В нем мы пишем сценарий. Использовать можно любой, но лучше всего тот, в котором организована возможность совместной работы с документом. Например, можно использовать Microsoft Word 2016 или Google Docs.

  • Программа для записи видео с экрана. С ее помощью мы снимаем видео с экрана, если это необходимо. Мы используем ту же программу, в которой мы делаем скриншоты для обычной документации, это программа Snagit.

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

Вроде все, сами понимаете, что если нет штатива, то это не критично. А вот, например, без монтажной программы точно не обойтись. Все оборудование собрано, начинаем снимать? Нет, сначала пишем сценарий.

Обязательно ли писать сценарий

Ответ ДА. Сценарий нужен даже, если ваш ролик длится 20 секунд. Ролики без сценариев очень отличаются, в них нет нужных акцентов и логики. А если в таком ролике еще есть закадровый голос, то это вообще веселье. Что делает человек, который записывает закадровый голос: он просто комментирует все, что видит, а так быть не должно. Здесь мы можем услышать неоправданные паузы, слова-паразиты и т.п.

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

Как уже говорили, мы пишем сценарий в текстовом редакторе, в котором есть функция, которая позволяет работать с одним документом нескольким людям одновременно. Сценарий в нашем случае пишет технический писатель, на это ему нужен хотя бы один рабочий день. У нас в ролике есть закадровый голос, поэтому сценарий мы пишем сразу в том виде, в котором сможем его передать тому, кто будет записывать закадровый голос. Не стоит делать сценарий очень большим. Подумайте, что действительно важно рассказать пользователям, на что обратить их внимание.

Например, если пользователю необходимо указать какие-то конкретные значения параметров, то надо это сказать, а сами значения продублировать в субтитрах в кадре.

А вот, если мы показываем, как мигает индикатор на устройстве, то это словами комментировать не нужно, в ролике все и так будет видно.

Когда первая версия сценария написана, она отправляется на проверку заказчику. Это обязательно надо сделать перед началом съемки, так как у исполнителя и заказчика могут быть очень разные представления о содержании ролика, и важно это выяснить. Здесь не нужно торопиться, важно подождать, пока заказчик посмотрим и выдаст свои комментарии, иногда ждать приходится долго.

Комментарии получены, все ошибки исправлены, сценарий готов. Что делать дальше? С чего начать съемку? Начнем с самого сложного со съемки реальных кадров. В нашем ролике это кадры со смарт-картой, компьютером и мобильными телефонами.

Как снимать реальные кадры или записывать закадровый голос

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

Совет 1. Записывайте звук отдельно. Если вы снимаете живые кадры и хотите, чтобы они сопровождались закадровым голосом, то пишите звук отдельно. Качество звука это очень важный параметр.

Мы записываем закадровый голос специальный диктофон или на диктофон мобильного телефона.

Для записи звука вам нужно найти тихое помещение, так как не все шумы можно убрать в процессе обработки. Располагайте диктофон в 20 сантиметрах от губ говорящего.

Мы обещали рассказать вам про наш форс-мажор, он как раз возник в процессе производства этого ролика. Что произошло? Мы получили файлы с закадровым голосом в пятницу вечером и не успели их проверить. В субботу наш технический писатель смонтировал видео с этими файлами и когда пересматривал финальную версию, обнаружил брак по звуку. Это был звук от прикосновения говорящего к микрофону, а его убрать нереально, так как он шел параллельно голосу. Что пришлось сделать? Перезаписать закадровый голос. А сами понимаете, на это нужно время. Не повторяйте наших ошибок, всегда проверяйте файла с закадровым голосом перед монтажом.

Совет 2. Обрабатывайте звук. Убирайте шумы и выравнивайте звук по громкости.

Совет 3. Думайте про свет. Плохо когда света мало, но также плохо когда его много. Не снимайте против источника света. Он должен быть либо перед объектом съемки, либо сбоку.

Естественный свет лучше искусственного, но у него есть один большой минус его нельзя контролировать. Например, сейчас может светить солнце, а через 5 минут оно спрячется за тучу или облако, и свет в кадре будет выглядеть иначе. Для того, чтобы выравнивать кадры по свету, необходимо на самом последнем этапе монтажа сделать цветокоррекцию, это можно сделать практически в любой монтажной программе.

Совет 4. Выстраивайте картинку. Даже, если в кадре нет человека, желательно думать о картинке. Думать о том, как это будет выглядеть, пробуйте разные варианты. Ведь порой даже от того, как расположен компьютер в кадре зависит восприятие всего ролика. Если для вас важно, чтобы было видно происходящее на экране компьютера, то старайтесь избегать лишних бликов. Здесь тоже нужен осознанный подход.

Мы снимали для ролика кадры:

  • Общий план: компьютер, считыватель, смарт-карта и руки человека. Так мы показали, что нужно для подготовки смарт-карты к работе.

  • Крупный план: смарт-карта в ладони. Так мы показали, как выглядит смарт-карта.

  • Крупный план: смарт-карта, мобильное устройство и руки человека. Так мы показали, как работать со смарт-картой на мобильном устройстве.

После того, как мы отсняли реальные кадры, начинаем снимать видео с экрана.

Как снимать видео с экрана компьютера или мобильного устройства

Можно просто нажать кнопку Запись и начать выполнять процедуру на компьютере или мобильном телефоне, пусть все без разбора записывается. Но лучше разделить съемку большой процедуры на съемку нескольких подпроцедур. Это тоже надо сделать правильно, с соблюдением логики выполнения большой процедуры, чтобы у пользователя не возникло ощущения разорванности процесса.

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

Есть моменты, которые можно ускорить. Например, вы показываете как заполняете стандартные поля (фамилия, имя, отчество), такое пользователь сможет сделать сам.

А есть моменты, которые можно замедлить. Например, если показываете, что пользователю необходимо проверить значения полей. Здесь вам надо дать пользователю время на это.

Не забывайте про то, что в вашем ролике не должно быть каких-то личных данных (номеров телефонов, IP-адресов, адресов электронных почт и т.п.), их надо замылить.

Также мы замыливаем системную дату и время. Вы спросите зачем? У пользователя не должно быть информации о том, что вы долго снимали свой ролик, что-то записывали в два часа ночи, а что-то потом вставили из другого дня. А по системному времени он может это легко отследить, поэтому лучше его замылить.

Мы снимали для нашего ролика процедуру создания тестового сертификата через сервис ra.rutoken.ru. Это нужно, чтобы подготовить смарт-карту для работы с мобильным устройством. Ну и показали пользователю продуктовую страницу смарт-карты.

Все данные в ролике были вымышленными, поэтому мы их не замыливали. Системное время попало в кадр один раз в общем плане, поэтому его тоже не замыливали.

Теперь у вас есть реальные кадры, есть кадры, снятые с экрана, что делать дальше? Монтировать ролик?

Нужна ли музыка

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

Мы используем одну и туже музыку во всех роликах, купили ее несколько лет назад на всем известном сайте.

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

Музыку выбрали, теперь можно монтировать.

Как монтировать ролик

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

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

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

Редактирование голоса. При редактирование голоса необходимо вырезать: паузы, ошибки, слова-паразиты.

Текстовые слайды и субтитры. В начале видео, на заставке надпись может быть крупной.

Во всех остальных видеофрагментах их лучше делать поменьше и размещать в нижней трети кадра.

Также стоит придерживаться единой палитры. Яркие цвета можно использовать для расстановки акцентов, для всего остального нейтральные. Для лучшего сочетания оттенков можно воспользоваться цветовым кругом.

Картинки. Иногда нужно иллюстрировать какие-то процессы, в этом могут помочь картинки. Как уже писали, для создания иллюстраций мы используем онлайн-редактор Readymag. Там есть готовые изображения, из которых можно составить смысловой слайд.

Мы в ролике иллюстрировали процесс использования смарт-карты в рабочей ситуации на предприятии.

На монтаж тоже нужно время. У нас на это ушел один рабочий день. Потом мы собрали первую версию ролика и отправили на проверку заказчику. Он прислал нам комментарии, мы обсудили их и смонтировали финальную версию ролика. Ее отправили нашему маркетологу, на этом этапе может возникнуть необходимость что-то исправить. Нас попросили исправить заставку, мы это сделали, и потом ролик был опубликован на нашем YouTube-канале.

Жизнь ролика на YouTube

Имейте ввиду, что для ролика еще надо написать описание и создать значок. Давайте сначала расскажем про значок. Это картинка, которая будет отображаться, пока ваш ролик не будет запущен для просмотра. К ней есть некоторые требования. Вставим сюда скриншот со страницы помощи YouTube.

Из описания ролика должно быть понятно, о чем он и должны быть указаны ссылки на ресурсы, о которых было упомянуто в ролике. Также пользователи могут писать комментарии к вашему ролику, периодически надо это проверять. В этих комментариях может быть ценная информация. Например, пользователь мог что-то не так понять.

Дальше ролик живет своей жизнью. Его можно отправлять потенциальным клиентам, пользователям, показывать на презентациях. Он может вызвать эмоции и повлиять на отношение к продукту. Не стоит бояться снимать, в интернете вы можете найти много информации про это и все необходимые программы. Надеюсь, наша статья помогла вам хоть немного разобраться в этом процессе.

Также мы открыты к диалогу, если есть вопросы пишите в комментарии.

Подробнее..

Asciidoc для ЕСКД

24.05.2021 16:18:49 | Автор: admin

image


Введение


В этой статье хочу рассмотреть возможности Asciidoc в части обеспечения требований соответствия документов требованиям единой системы конструкторской документации (ЕСКД), конкретно ГОСТ Р 2.1059 (далее ГОСТ ЕСКД). Почему именно Asciidoc, я писал здесь.


Сразу уточню. Вопрос форматирования документа здесь не рассматривается. Создающий документацию не должен задумываться о форматировании. Как системный аналитик я создаю содержание и контролирую его структуру. Для получения документа, соответствующего ГОСТ ЕСКД или другому аналогичному стандарту, я должен нажать кнопку и получить корректно отформатированный документ в любых требуемых вариантах: pdf, Open Document (Libre
Office/Open Office), Open XML (Microsoft Word) и прочих.


После работы над https://github.com/CourseOrchestra/asciidoctor-open-document уверен,
что все проблемы форматирования решаются адекватными усилиями.


Рассмотрим структуру документа Asciidoc, соответствующего требованиям
ГОСТ ЕСКД.


Построение документа


В пункте 6.1.1 ГОСТ ЕСКД приведена рекомендуемая структура, которую в Asciidoc можно отобразить следующим образом.


= Наименование документа[preface]== Предисловие== Обозначения и сокращения== Термины и определения== Основное тематическое содержание документа (например, Особенности приготовления рататуя)[appendix]== Приложения (например, Перечень ингредиентов)== Ссылочные нормативные документы== Ссылочные документы[bibliography]== Библиография== Лист регистрации изменений

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


:mesto-vyhpuska: Москва

Здесь и далее для обозначения идентификаторов используется транслитерация, ГОСТ 7.79-2000 (система Б). Разработчики данного ГОСТ совершили лёгкое вредительство, не позволяющее использовать его для идентификаторов, поэтому мы используем доработанную версию, подробности здесь.


Для некоторых атрибутов предусмотрен упрощенный синтаксис, в данном случае наименование документа вводится первой строкой после одного знака =.


Раздел с содержанием (подраздел 6.2 ГОСТ ЕСКД) заполняется автоматически при генерации документации.


Разделы Приложение (подраздел 6.3 ГОСТ ЕСКД), Библиография (подраздел 6.4. ГОСТ ЕСКД) и Предисловие определены специальными ключевыми словами:


  • preface даст возможность процессору Asciidoctor понять, что не
    нужно включать этот раздел в содержание;


  • appendix позволит автоматически нумеровать приложения буквами;


  • bibliography объявляет раздел с библиографическими ссылками
    документа.



Встроенная поддержка библиографии реализована совсем просто, для соответствия ГОСТ ЕСКД необходимо использовать расширение [asciidoctor-bibtex] https://github.com/asciidoctor/asciidoctor-bibtex).


Список литературы задаём в файле формата BibTeX.


@Book{viz, author    = {Волков, А. М.}, title     = {Волшебник изумрудного города}, publisher = {Эксмордество}, year      = 1921, address   = Москва, lang=ru}

В самом документе необходимо использовать следующий синтаксис.


:bibtex-file: путь к файлу в формате BibTeXВ изумрудный город ведёт дорога, вымощенная желтым кирпичом cite:[viz(24)].[bibliography]== Список использованной литературыbibliography::[]

Деление документа на части


Требования к делению документов на части определены в подразделе 6.5 ГОСТ ЕСКД. Для деления документа на разделы/подразделы/пункты используется синтаксис:


== Раздел=== Подраздел==== Пункт

Атрибут secnums задаёт нумерацию разделов полностью по ГОСТ ЕСКД.


Чтобы Asciidoc отличал пункт от заголовка раздела (особенно, если пункт не имеет заголовка) можно использовать специальную роль, например [.punkt]. Роль задаём над заголовком.


[.punkt]==== Пункт

Перечисления


Требования к перечислениям определены в подразделе 6.7 ГОСТ ЕСКД. В Asciidoc перечисления задаются так:


.Наименование списка. Первый пункт. Второй пункт.. Подпункт второго пункта+Дополнительный абзац подпункта второго пункта. Третий пункт

Обратите внимание: у перечисления может быть наименование. В ГОСТ ЕСКД такого понятия нет, но Asciidoc позволяет в печатном документе не отрывать наименование от перечисления. В некоторых случаях это можно использовать.


Можно включать в список дополнительные абзацы, графику и иное содержание. Для этого используют символ +.


В ГОСТ ЕСКД возможно маркировать первый уровень перечислений дефисом. Для этого приведённый пример переоформим следующим образом.


.Наименование списка* Первый пункт* Второй пункт. Подпункт второго пункта+Дополнительный абзац подпункта второго пункта* Третий пункт

Asciidoc допускает вложенность пунктов до пятого уровня.


Таблицы


В качестве примера рассмотрим таблицу, приведённую на рисунке 1 ГОСТ ЕСКД (пункт 6.8.1).


.Наименование таблицы[cols="2,1,1,1,1", hrows=2]|====.2+|Головка2+|Заголовок графы 12+|Заголовок графы 2|Подзаголовок графы 1.1|Подзаголовок графы 1.2|Подзаголовок графы 2.1|Подзаголовок графы 2.2|Заголовок боковика 1|||||Заголовок боковика 2|||||Заголовок боковика 3|||||====

Результат зависит от настроек форматирования. Заданная выше таблица будет выглядеть приблизительно следующим образом.


image


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


В атрибуте cols (cols = "2,1,1,1,1") указано, что в таблице будет 5 колонок, причём первая будет в два раза больше остальных.


В атрибуте hrows указано количество строк в шапке таблицы. Шапка в соответствии с требованиями ГОСТ ЕСКД отображается на каждой странице, если таблица занимает более одной страницы.


Атрибут hrows не поддерживается исходным процессором Asciidoctor и требует специального расширения, в данном случае https://github.com/CourseOrchestra/asciidoctor-plugins. По умолчанию поддерживается только параметр options="header", предполагающий, что
строка заголовка может быть только одна.


В ГОСТ ЕСКД есть требование помещать слова Продолжение таблицы с указанием номера (обозначения) таблицы в начале каждой странице, на которую переносится таблица. Однако пункт 6.8.7 ГОСТ ЕСКД разрешает не указывать эту надпись при подготовке документа с использованием программных средств.


В самой таблице каждая ячейка начинается с вертикальной черты (|). Обычно между строками таблицы делают дополнительный перенос строки, так с таблицей легче работать.


Первая ячейка таблицы занимает по вертикали место двух ячеек, поэтому использован синтаксис .2+\|. Заголовки граф занимают две ячейки по горизонтали, использован аналогичный синтаксис, но без точки: 2+\|.


Графический материал


Для размещения графического материала (подраздел 6.9 ГОСТ ЕСКД) используем следующий синтаксис:


.Наименование рисункаimage::путь к изображению[атрибуты изображения]

Нумерация рисунков, как и в случае с таблицами делается автоматически.


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


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


Например, одной из основных проблем при расположении картинок в печатных документах является автоматический подбор их размера. Скажем, ваша диаграмма вытянута по вертикали. Вы добавили вниз еще один элемент, и картинка вылетела за пределы страницы. Или вы добавили элемент справа, который прекрасно влезает по ширине, но неумолимый алгоритм уверен, что главное не менять ширину и уменьшает пропорции картинки, что ведёт к мелким шрифтам и плохой читаемости.


Когда я писал конвертер в Open Document, то решил это добавлением специальных свойств, контролирующих оптимальное расположение. В общем случае проблему придётся решать для каждого выходного формата. Правда, всего один раз. В отличие от использования MS Word, где подгонка каждой картинки лежит на плечах пользователя.


Для процессора Asciidoctor реализовано расширение Asciidoctor Diagram для внедрения непосредственно в текст диаграмм, графиков и других элементов.


Для таких диаграмм используют следующий синтаксис.


[plantuml, png]....@startumlrectangle "Компонент 1" as c1rectangle "Компонент 2" as c2rectangle "Компонент 3" as c3c1 <-> c2c1 .. c3c2 == c3@enduml....

Результат должен выглядеть следующим образом:



Оформляют такие диаграммы также, как обычные изображения.


Формулы


Работа с формулами (подраздел 6.10 ГОСТ ЕСКД) аналогична работе с диаграммами: формулы можно задать прямо в тексте. В следующем примере формула задана на языке LaTeX/Mathematics:


[latexmath]++++\begin{bmatrix}a & b \\c & d\end{bmatrix}\binom{n}{k}++++

Часто формулы имеют пояснения. Чтобы указать Asciidoc, что абзац является именно пояснением к формуле, необходимо присвоить ему какую-то роль, например.


[formula-poyasnenie]где stem:[a] -- левый верхний элемент матрицы; +stem:[b] -- правый верхний элемент матрицы; +и т.д.

Ключевое слово stem означает, что формула помещена внутри текстовой строки.


Обратите внимание на символ + в конце строки. Он означает перенос текста на другую строку без завершения абзаца.


Аналогично реализуются другие элементы с фиксированным форматированием: примечания, примеры и т.п. Роль можно присваивать как отдельному абзацу, так и более крупному фрагменту текста.


Ссылки


Ссылки (подраздел 6.11 ГОСТ ЕСКД) в Asciidoc реализованы так: каждому объекту, на который необходима ссылка, присваивают идентификатор. Например, идентификатор для картинки может быть задан в удвоенных парных квадратных скобках:


[[moya-diagramma]].Моя диаграммаimage::moya-diagramma.jpg[]

Для ссылки на данную диаграмму используем следующий синтаксис.


Моя диаграмма изображена на рисунке (<<moya-diagramma>>).

В этом случае текст в документе будет выглядеть так:


Моя диаграмма изображена на рисунке (рисунок 1).

Для html-варианта (например, в интерактивной справке) можно вместо текста \"рисунок 1\" отображать его название.


Не очень красивым выглядит то, что в тексте документа слово \"рисунок\" повторяется дважды. Но это самый простой вариант, который позволяет с одной стороны соответствовать ГОСТ ЕСКД, а с другойсохранять падежи при использовании автоматизированной генерации документов.


Сноски


Для сносок (подраздел 6.13 ГОСТ ЕСКД) в Asciidoc существует специальный синтаксис.


Здесь расположена сноскаfootnote:f1[Текст сноски]

f1 в данном случаеидентификатор сноски, если необходимо поместить её более, чем в одном месте.


Выводы


  1. Asciidoc позволяет создавать документацию в соответствии с требованиями ЕСКД.


  2. Синтаксис Asciidoc не сложнее самого ГОСТ Р 2.1059.


  3. Можно забыть о стилях MS Word и сконцентрироваться на содержании
    создаваемых документов.


Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru