IBM Senior DevOps Engineer & Integration Architect. Официальный DevOps ментор и коуч в IBM   Привет Хабр! Иногда мне приходится расширять функционал наших платформ по запросам разработчиков и в для этого мне отлично подошел Go. Однако нужно не только уметь писать на языке, но и уметь его тестировать. Как вы поняли, сегодня я хотел бы рассказать про основы тестирования в Go.Тестирование — это первостепенная задача в Go. Пакет тестирования предоставляет API для написания тестового кода. Опишу упражнение, в котором мы реализуем и выполним базовые тестовые случаи с помощью стандартного пакета тестирования. Выполним их с помощью набора инструментов Go. Шаг первый: Внедрим тесты с помощью стандартного пакета тестирования. Выполним тесты из командной строки с помощью команды go test. Для многих языков программирования тестирование является дополнительной функцией. Это не относится к Go. Пакет тестирования встроен в среду выполнения Go и предлагает все необходимое для написания сложного тестового кода. API прост для понимания и в то же время позволяет избежать синтаксического сахара. Тестовый код находится в файле исходного кода, отличном от рабочего исходного кода. По конвенции эти исходные файлы имеют файл, заканчивающийся на _test.go. Например, для файла Go http.go вы должны создать тестовый файл с именем http_test.go. Нет специальной директории для тестового кода. Файл просто живет вместе с производственным исходным кодом. При написании тестового кода необходимо учитывать всего несколько шагов: В список импорта необходимо добавить пакет тестирования. Каждый тестовый пример представлен функцией. Функция должна быть экспортирована, а ее имя должно начинаться с префикса Test. Функция имеет единственный параметр, который ссылается на тип testing.T. Параметры предоставляют вам доступ к соответствующему API для реализации утверждений. Приступим. Сперва создадим файл hello.go со следующим содержимым Экспортируемая функция Hello принимает два параметра. Параметра “name”  представляет имя человека, а параметр “language” определяет языковой префикс, используемый для приветствия человека. Например, для параметров «Ben» и «English» в возвращаемой строке будет «Hello, Ben». Логика может вернуть ошибку, если язык не поддерживается.Давайте напишем тестовый пример для этого самого варианта использования в файле с именем hello_test.go. Как вы можете видеть в приведенном ниже примере кода, мы вызываем исходный код (в данном случае функцию Hello) и затем проверяем его результат. Если результат не соответствует вашим ожиданиям, вы можете отметить это с помощью вызова функции t.Error*. Вызов t.Error* сообщает об ошибке теста, но продолжает выполнение набора тестов до тех пор, пока не будут выполнены все тестовые кейсы: Вероятно, вы можете представить еще много тестовых случаев для функции Hello. Не стесняйтесь добавлять их, чтобы получить больше опытаНо теперь прогоним наши тестыВозможность выполнять тесты связана с тулчейном Go. Чтобы выполнить тесты, просто запустим исполняемый файл go с помощью команды test. В качестве последнего параметра команды нам нужно будет указать пакеты, которые вы хотите протестировать. Вместо предоставления конкретного пакета я часто просто рекурсивно выполняю все тесты из корневой директории. Полная команда для такого поведения — go test ./…. Мы имеем дело только с основным пакетом, который содержит один тест. Выполним тесты с помощью следующей команды. Также мы используем параметр -v для отображения подробного вывода. Все тесты должны пройти:go test -v Отлично, идем дальше, задействуем Testify.Стандартный пакет тестирования предоставляет API для написания тестового кода. Однако API не хватает, когда дело доходит до предоставления удобных методов и синтаксического сахара. Testify — это пакет с открытым исходным кодом, упрощающий написание логики утверждений. Сейчас мы реализуем и выполним базовые тестовые примеры с помощью testify.Сперва добавим testify с помощью команды go get:go get github.com/stretchr/testifyСледующий код (также hello_test.go) импортирует пакет assert из файла testify. Его API предлагает множество удобных методов, которые упрощают написание утверждений. Здесь мы проверяем нулевое значение ошибки с помощью assert.Nil и равенство фактического с ожидаемым возвращаемым значением через assert.Equal: И запустим тест: go test -vНу и перейдем к созданию метрик покрытия кода и репортов.Метрики покрытия кода помогают определить части рабочего исходного кода, которые были покрыты тестами. Наличие хорошего охвата правильными утверждениями означает, что вы можете уверенно проводить рефакторинг кода или внедрять новые функции и исправления ошибок, не нарушая существующие функции. Сейчас мы создадим метрики покрытия кода и отобразим их в браузере. Показатели покрытия кода отвечают на вопрос: «Какая часть нашего кода была проверена тестами?» В большинстве случаев нереально стремиться к 100% охвату, поскольку вы потратите много усилий на написание тестов. Более практичный подход — стремиться к 70–75% охвата. Этот процент дает вам достаточную уверенность, чтобы вносить изменения в рабочий исходный код, не ломая его немедленно. Наиболее часто используемые критерии покрытия кода следующие: Покрытие операторов (также известное как покрытие строк): какой оператор/строка в блоке кода был покрыт? Покрытие ветвей: какой путь выполнения был охвачен? Покрытие условий: оценивается ли каждое булево подвыражение как истинное, так и ложное? Не ведитесь на голые цифры. Не менее важно писать хорошие утверждения. Утверждения проверяют результат теста. Например, при записи файла вы захотите убедиться, что файл существует в нужном месте и содержит ожидаемые данные. Помня об этой теории, давайте рассмотрим поддержку покрытия кода в Go.Тулчеин Go имеет встроенные возможности для создания показателей покрытия кода. Мы уже использовали команду go test раньше. Все, что вам нужно сделать, чтобы зафиксировать показатели покрытия кода, — указать параметр командной строки -cover. Метрики будут отображаться прямо на терминале:go test ./... -cover Вы также можете записать метрики в файл для дальнейшей обработки. Следующая команда записывает файлы в cover.txt: go test ./... -coverprofile=coverage.txtПосле выполнения команды вы должны найти файл метрик. Обычно не нужно смотреть непосредственно на текстовый файл, но вы можете заглянуть в его структуру: Итак, каким критериям покрытия кода следует Go? Критерии команды Go называются режимами покрытия и могут быть установлены с помощью параметра командной строки -covermode. Вот общий обзор: set: Выполнялся ли каждый оператор? count: сколько раз выполнялся каждый оператор? atomic: работает как count, но считает точно в параллельных программах Режим покрытия по умолчанию — это покрытие операторов, фактически установленное значение. Это критерии, которые мы применяли с предыдущей командой go test. Не стесняйтесь исследовать другие режимы покрытия и определить, как меняются числа. На следующем шаге вы узнаете, как превратить метрики в визуальное представление.Обычно удобнее видеть метрики в визуальном представлении. Тулчеин Go предлагает способ превратить метрики из текстового файла в отчет в формате HTML. Отчет в формате HTML отображает представление метрик с цветовой кодировкой в статическом файле HTML. Давайте попробуем. Следующая команда создает файл HTML с именем index.html. Существуют и другие варианты визуализации метрик покрытия кода. IDE может отображать метрики непосредственно в коде. Хорошими вариантами являются JetBrains GoLand и Microsoft Visual Studio Code с установленным плагином Go. Кроме того, вы также можете отправить метрики на стороннюю платформу, которая предоставляет расширенные функции визуализации. Coveralls и Codecov — лишь некоторые из них. Напоследок хочу порекомендовать бесплатный вебинар от моих коллег из OTUS, на котором вы познакомитесь с профессией Тестировщика ПО, узнаете, где работают тестировщики и увидите какие задачи стоят перед тестировщиком в течение рабочего дня. Зарегистрироваться на бесплатный вебинар  Редактор