понедельник, 27 июня 2016 г.

CI для Go на базе Github

Сегодня поговорим о тестировании. На изучение темы применительно к Go меня сподвигла задача минимизации HTML (подробнее в "Веб поиск на Go. Краулер. Как не хранить лишнее"). Реализация имела так много особых случаев, что без тестов удержать их в голове стало невозможно. А чуть позже природная лень сподвигла меня настроить автоматическую прогонку тестов.




GoConvey

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

Относительно хорошим я бы назвал GoConvey, который от ему подобных отличается:
  • Возможностью автоматически прогонять тесты при изменении файла.
  • Наличием web интерфейса, который достаточно красочно показывает текущее состояние тестов.
  • Иногда полезна возможность desktop нотификаций о результатах.
Развесистая система assert'ов в плюс не засчитываю, это основа фреймворка тестирования.

Для начала работы ставим пакет:
go get github.com/smartystreets/goconvey
И в корне проекта запускаем:
goconvey
Он сам отыщет модули с тестами, прогонит и откроет в браузере результат:

Синтаксис вопросов не вызывает:
package package_name

import(
    "testing"
    . "github.com/smartystreets/goconvey/convey"
)

func TestNum(t *testing.T) {
    Convey("1 should equal 1", t, func() {
        So(1, ShouldEqual, 1)
    })
}
Но лучше пролистать документацию, хотя бы для того, что бы узнать о вложенных тестах и о поддерживаемых видах assert'ов.
Так же фреймворк совместим со стандартными интерфейсами, поэтому "go test" отработает как нужно. В целом достаточно удобный и простой инструмент.

 

Travis CI

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

А раз человек существо непостоянное и ленивое, переложим повторяющиеся действия на машину. Желательно на машину чужую. Тут поможет Travis, я о нём уже рассказывал, но тогда это был Rust, для Go - ещё проще. Настройка заключается в добавлении репозитория в отслеживаемые на travis-ci.org, плюс закомитить в корень проекта ".travis.yml":
language: go
sudo: false
go:
  - tip
os:
  - linux
install:
  - go get -u -t -v ./...
script:
  - go build -v -o bin/go-web-search
  - ./go.test.sh
after_success:
  - bash <(curl -s https://codecov.io/bash)
notifications:
  email:
    recipients:
      - name@server.io
    on_success: never
    on_failure: always
Расшифровка:
  • "language: go" - указываем какое окружение нам нужно, для Go будут добавлены cmake, scons и прочее.
  • "go: - tip" - прогонять тесты будем только на последней версии Go, при желании можно явно указать другие.
  • "sudo: false" - добровольно отказываемся от использования sudo, в ответ нам делают docker контейнер, который быстрее, выше, сильнее.
  • секция "install" - ставим все зависимости проекта (и тестов - флаг "-t").
  • в секции "script" - собственно собираем проект и потом запускаем тесты. Тесты можно было запустить командой "go test ./…", но мне нужно считать покрытие, ниже объясню зачем. Скрипт "go.test.sh" выглядит вот так.
  • команда в after_success - триггер для codecov, о котором ниже.
  • в "notifications" - рассылаем уведомление на почту, если сборка завершилась с ошибкой.
Подробности в документации. Ну и самое главное - добавьте бейдж в readme проекта.

 

CodeCov

 Твои тесты в Travis CI могут быть бесконечно зелёными, но какой в этом толк, если покрытие менее 100%? Самостоятельно постоянно мерить покрытие лень, забываешь. Это дело машин, они железные - стерпят. Хоть в Go и есть CLI утилиты для расчёта покрытия, но смотреть сухие цифры в консоли это одно, а красочно оформленные результаты совсем другое.

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

Поддерживает 24 ЯП, бесплатен для Open Source и прост в настройке. Есть аналог coveralls.io, но визуально он мне нравится меньше. Для настройки, логинимся на codecov.io через аккаунт GitHub и добавляем репозиторий, он сам спросит нужные права и т.п. Потом добавляем в корень файл ".codecov.yml":
coverage:
  precision: 2
  round: nearest
  range: "40...90"
  status:
    project:
      default:
        target: "90%"
        threshold: "10%"
    patch:
      default:
        target: auto
        threshold: null
    changes:
      default:
        target: auto
Это почти умолчательные настройки, где указываем кол-во знаков после запятой для покрытия, метод округления, цель к которой мы стремимся и т.п. Вот тут почитайте подробнее.

Далее ему необходим сформированный файл "coverage.txt" с указанием покрытия для каждого файла. Для этого тесты выше, я запускал через go.test.sh, который генерит всё необходимое. По завершению генерации файла, посылаем сигнал о том, что файл можно анализировать:
bash <(curl -s https://codecov.io/bash)
Выше я эту команду вызывал в Travis CI в секции "after_success". Всё! Осталось только добавить иконку в README с указанием покрытия. Документация тут.

Комментариев нет:

Отправить комментарий