Как мы использовали Git, CI и code review в учебном процессе

В Академическом университете постоянно внедряются новые подходы к обучению. Программы, задания и сам процесс меняются таким образом, чтобы предоставить студенту наиболее полные и актуальные знания, а преподавателю — возможность попробовать более эффективные методы. Так и в прошлом семестре вместо того, чтобы принимать ДЗ по Java «на А4 и по ГОСТу», мы с bintree решили сделать все «как у больших дядей»: использовать Git, CI и code review. В этой заметке я поделюсь с вами возникшими проблемами, их решениями, плюсами-минусами такого подхода, а также некоторыми соображениями на будущее.

Проблемы стандартных подходов


Вопрос подготовки и проверки домашних и контрольных заданий встал перед нами сразу как только мы узнали, что будем вести Java. К тому моменту мы успели побывать в качестве студентов в разных университетах и попробовать на себе множество подходов к проверке ДЗ, например, «принеси на флешке» или «распечатай на листочке» (даже не буду утруждаться перечислением минусов этих двух). Наиболее удобным к тому времени для нас казался подход, который практиковался в АУ: студент присылает решение по электропочте и вступает с преподавателем в переписку. Однако и в этом подходе нам не все нравилось:

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


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

Немного подумав, мы решили, что связка «VCS + общедоступный CI-сервер + инструмент для ревью кода» избавит нас от всех вышеперчисленных проблем, а использование сторонних сервисов избавит еще и от необходимости все это настраивать.

Организация работы


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

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

Подбор сервисов


С VCS-сервисом все было просто и понятно: Github. Исторически так сложилось, что и у нас, и у большинства студентов были аккаунты именно там; это стало ключевым доводом «за». Кроме того, там же было решено делать ревью кода и оставлять замечания.

С сервисом CI все обстояло немного сложнее. Изначально мы решили использовать Travis CI и до некоторых пор он нас всем устраивал. Однако со временем наши требования изменились: кроме открытых тестов, доступных прямо из репозитория с заданием, нам захотелось сделать еще и несколько закрытых — для того, чтобы студенты самостоятельно подумали над различными тонкостями и граничными случаями. Мы создали закрытый репозиторий, изменили билд так, чтобы этот репозиторий добавлялся как submodule в основной, и добавили зашифрованных переменных с именем пользователя и паролем, чтобы Travis мог склонировать закрытый репозиторий. Все было хорошо ровно до того момента, пока один из студентов не попробовал сделать pull request. Оказалось, что зашифрованные переменные недоступны из билдов для PR и мы это не проверили. Беглый поиск по оставшимся CI-сервисам вывел нас на Semaphore CI. В отличие от Travis, он поддерживает загрузку секретных SSH ключей, которые можно использовать в билде для доступа к закрытым репозиториям, а это именно то, что нам было нужно.

Подводные камни и минусы


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

Второй проблемой стало отсутствие правил именования коммитов и PR. В итоге уже после первой домашки мы получили ворох PR с названиями вида «fix»,»1st hw», «моя домашка» и т.п. Все это дополнительно осложнялось тем, что определить студента по имени пользователя было почти невозможно, потому что профиль был заполнен далеко не у всех. Для последующих заданий мы, конечно, ввели строгие правила, но в первый раз пришлось попотеть.

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

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

Выводы и планы на будущее


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

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

© Habrahabr.ru