October 20, 2025

Автоматическая проверка заданий на языке R в  GitHub Classroom

1. Готовим репозиторий с тестами

1.1. Тесты не должны быть видны студентам, поэтому создаем в организации GitHub приватный репозиторий с тестами, например r-grading-tests. Структура директории:

├── README.md
├── run_tests.R
└── tests
    ├── test_assignment1.R
    └── test_helpers.R

1.2. Создаем run_tests.R и тесты для отдельных заданий.

file.create("tests/test_assignment1.R")
file.create("tests/test_helpers.R")
file.create(run_tests.R)

1.3. Редактируем run_tests.R.

library(testthat)

# Загружаем код студента
if (file.exists("assignment.R")) {
  source("assignment.R")
} else {
  stop("File assignment.R not found")
}

# Запускаем тесты
test_results <- test_dir("private-tests/tests/", reporter = "progress")

# Выводим результаты
cat("Tests completed! Check results.\n")
print(test_results)

2. Готовим репозиторий с заданиями

2.1 Создаем репозиторий homeworks-autograde. Репозиторий создается в организации, далее в настройках надо поставить галочку, что это шаблон.

Структура директории:

├── .github
│   └── workflows
│       └── autograde.yml
├── README.md
└── assignment.R

2.2. Создаем нужные файлы.

dir.create(".github/workflows", recursive = TRUE)
file.create(".github/workflows/autograde.yml")

2.3. Редактируем autograde.yml.

name: Autograde R Assignment

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout student code
        uses: actions/checkout@v3
        
      - name: Checkout private tests
        uses: actions/checkout@v3
        with:
          repository: ВАША-ОРГАНИЗАЦИЯ/r-grading-tests
          token: ${{ secrets.TEST_REPO_TOKEN }}  
          path: private-tests
          
      - name: Setup R
        uses: r-lib/actions/setup-r@v2
        
      - name: Install dependencies
        run: |
          R -e "install.packages('testthat')"
          
      - name: Run tests
        run: Rscript private-tests/run_tests.R

3. Создаем Personal Access Token (PAT)

3.1. Заходим в свои настройки GitHub (не организации). Developer settings → Personal access tokens → Tokens (classic). Generate new token → Generate new token (classic). Дайте токену имя, например, classroom-tests-access. Установите период его действия (в моем случае — учебный год). Дайте ему доступ к repo (полный контроль репозиториев).

После этого скопируйте токен (он покажется только один раз).

3.2. В организации, к которой относится репозиторий-шаблон с заданиями для студентов, идем Settings → Secrets → Actions, добавляем секрет TEST_REPO_TOKEN.

4. Публикация и проверка задания

4.1. Придумайте задание и опубликуйте его в GitHub Classroom, в качестве репозитория-шаблона укажите homeworks-autograde. Если у вас бесплатный план, сделайте студенческие репозитории публичными: работа Actions с приватными репозиториями на бесплатном плане сильно ограничены.

Пример задания: необходимо создать переменную hello и присвоить ей значение "hellow world!"

На этапе Set up autograding and feedback ничего не добавляйте! Автоматическая проверка уже настроена через файл в шаблоне.

4.2. Пишем тест для задания (файл test_assignment1.R в репозитории с тестами, не забудьте запушить). В нашем случае он выглядит так:

test_that("Variable 'hello' exists and has correct value", {
  
  # Проверяем, что переменная hello существует в глобальном окружении
  expect_true(exists("hello"), 
              info = "Variable 'hello' should be defined")
  
  # Если переменная существует, проверяем ее значение
  if (exists("hello")) {
    expect_equal(hello, "hello world!", 
                 info = "Variable 'hello' should equal 'hello world!'")
    
    expect_type(hello, "character")
    expect_length(hello, 1)
  }
})

test_that("Variable 'hello' is assigned with correct syntax", {
  if (exists("hello")) {
    expect_match(hello, "hello world!")
  }
})

В этом примере test_helpers.R не задействован; в противном случае не забудьте прописать source("tests/test_helpers.R").

4.2. Рассылаем ссылку на GitHub Classroom студентам. Когда студент выполнит и запушит задание, запустятся тесты. Если студент работает в браузере, то нажатие кнопки "Commit" автоматически отправит коммит на сервер, поэтому в этом случае push не требуется.

Надо несколько минут подождать, результат будет виден в Actions. Тесты запускаются для каждого коммита, который делает студент. (Чуть позже допишу, как это можно ускорить: сейчас основное время уходит на Setup R & Install dependencies).

5. Результат проверки

5.1. Чтобы увидеть результат проверки, студент может заглянуть в Actions.

5.2. Можно выбрать конкретную проверку и посмотреть ее результаты подробнее. Для студента это выглядит вот так (и я все еще думаю, как сделать это информативнее).

5.3. Преподаватель увидит, что тесты пройдены, в Classroom. ❗️ Но: GitHub Classroom на данный момент не умеет парсить и визуализировать числовые метрики из workflow. Он не умеет ни импортировать результаты тестов напрямую, ни показывать количество тестов (только passed/failed статус job).

Напишу, когда/если придумаю, как это докрутить.

6. Возможные проблемы

6.1. Если тесты не запустились, проверьте, что в студенческом репозитории есть файл autograde.yml. Он лежит в скрытой папке, и если вы пушили изменения через графический интерфейс Git в RStudio, они могли не попасть в репозиторий-шаблон. Чтобы исправить, выполните в терминале:

git add .github/workflows/autograde.yml
git commit -m "Add autograding workflow"
git push