Тестування на треку Bash

Як тестувати свої вправи з Bash на Exercism


Можна скористатися онлайн-редактором на сайті Exercism, щоб розвʼязувати вправи. Або завантажити вправи на свій компʼютер, розвʼязати їх локально, а потім надіслати до Exercism. Далі в цьому документі йдеться про локальну роботу.

Exercism CLI

Щоб завантажувати вправи й надсилати їх, знадобиться інструмент командного рядка exercism. Дивіться документацію до exercism cli.

Функція-обгортка для інструмента exercism

Одна з неприємних особливостей стандартного інструмента exercism полягає в тому, що після завантаження вправи доводиться вручну змінювати каталог. Ця функція-обгортка робить це за нас; збережіть її у своєму ~/.bashrc.

exercism () {
    local out
    readarray -t out < <(command exercism "$@")
    printf '%s\n' "${out[@]}"
    if [[ $1 == "download" && -d "${out[-1]}" ]]; then
        cd "${out[-1]}" || return 1
    fi
}

Зауважмо, що це не може бути скриптом оболонки, це має бути функцією оболонки. Скрипти оболонки виконуються в дочірньому процесі й не можуть впливати на середовище (як-от поточний робочий каталог) поточної оболонки.

Локальне тестування

Для тестування на треку bash ми використовуємо bats.

Запустити тести для гіпотетичної вправи «whatever» можна так:

cd /path/to/your/exercise_workspace/bash/whatever
bats whatever.bats

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

Встановлення bats-core

Зазвичай його вдається встановити з улюбленого менеджера пакунків:

Для Mac (brew)

На macOS із Homebrew це матиме приблизно такий вигляд:

$ brew install bats-core
==> Downloading https://github.com/bats-core/bats-core/archive/v1.1.0.tar.gz
==> Downloading from https://codeload.github.com/bats-core/bats-core/tar.gz/v1.1.0
######################################################################## 100.0%
==> ./install.sh /usr/local/Cellar/bats-core/1.1.0
🍺  /usr/local/Cellar/bats-core/1.1.0: 13 files, 55KB, built in 4 seconds
  • У світі homebrew існує також застарілий пакунок bats. Не встановлюйте його помилково: встановіть bats-core.

Для Linux

Fedora 30 і новіші

bats є в пакунках для Fedora 30 і новіших, його можна встановити так:

sudo dnf install bats

Інші Linux

Для інших дистрибутивів Linux реалізація bats, яку ми використовуємо, може не мати зручного пакунка. Найкраще встановлювати її з джерельного коду. Якщо потрібно встановити її в /usr/local, тоді зробіть так:

git clone https://github.com/bats-core/bats-core
cd bats-core/
sudo ./install.sh /usr/local

Після цього, за умови, що /usr/local/bin є у $PATH, тепер можна виконати:

$ bats
Error: Must specify at least one <test>
Usage: bats [-cr] [-f <regex>] [-j <jobs>] [-p | -t] <test>...
       bats [-h | -v]
...

Для Windows (MINGW64/Cygwin)

$ git clone https://github.com/bats-core/bats-core.git
$ cd bats-core
$ ./install.sh $HOME

Примітка: коли використовується застарілий https://github.com/sstephenson/bats.git і виникає помилка на кшталт cp: cannot create symbolic link '${HOME}/bin/bats': No such file or directory, потрібно вручну скопіювати вміст теки bin/bats/libexec/ до ${HOME}/bin/.

Є повідомлення, що новіші версії bats погано працюють у MinGW bash, тож перш ніж запускати скрипт встановлення, можливо, варто:

$ git checkout v1.1.0

bats-assert

Щоб розібратися зі значенням різних команд assert* у тестах, зверніться до документації бібліотеки bats-assert.

Пропущені тести

Розвʼязати вправу означає зробити так, щоб усі її тести проходили. За замовчуванням під час запуску тестів виконується лише один тест (перший). Це зроблено навмисно, щоб можна було зосередитися на проходженні саме цього одного тесту. Коли він пройде, можна увімкнути наступний тест, закоментувавши або видаливши

[[ $BATS_RUN_SKIPPED == true ]] || skip

ці анотації, що стоять перед іншими тестами.

Як обійти пропуски

Щоб запустити всі тести, зокрема ті, що мають анотації skip, можна встановити змінну середовища BATS_RUN_SKIPPED у значення true. Один зі способів зробити це лише на час запуску bats такий:

BATS_RUN_SKIPPED=true bats exercise_name.bats

Буває зручно скористатися функцією-обгорткою, щоб менше друкувати:

bats() {
    BATS_RUN_SKIPPED=true command bats *.bats
}

Тоді запустити тести можна просто так:

bats

Застарілий bats

bats-core походить від оригінальної реалізації bats. Проєкт sstephenson/bats мав багато помилок і був занедбаний. У 2017 році право власності передали: sstephenson/bats#150 (коментар).

Якщо встановлено оригінальний sstephenson/bats (перевірити можна командою bats -v: якщо вона показує номер версії, менший за 1.0), тоді варто перейти на bats-core; інакше можна натрапити на незрозумілі збої тестів.