Testar no percurso de Bash

Aprende a testar os teus exercícios de Bash no Exercism


Podes usar o editor online no site do Exercism para resolveres os exercícios. Ou podes descarregar os exercícios para o teu computador, resolvê-los localmente e depois submetê-los ao Exercism. O resto deste documento fala sobre trabalhar localmente.

CLI do Exercism

Vais precisar da ferramenta de linha de comandos exercism para descarregares e submeteres exercícios. Consulta a documentação do CLI do exercism.

Função wrapper para a ferramenta exercism

Um dos aspetos irritantes da ferramenta exercism predefinida é que, depois de descarregares um exercício, tens de mudar de diretório manualmente. Esta função wrapper trata disso por ti; guarda isto no teu ~/.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
}

Repara que isto não pode ser um script de shell, tem de ser uma função de shell. Os scripts de shell são executados num processo filho e não conseguem afetar o ambiente (como o diretório de trabalho atual) da tua shell atual.

Testar localmente

Para testar no percurso de bash, usamos o bats.

Corre os testes para o exercício hipotético "whatever" assim:

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

Se quiseres imprimir a saída de depuração enquanto corres os testes localmente, vê Depuração local.

Instalar o bats-core

Deves conseguir instalá-lo a partir do teu gestor de pacotes preferido:

Para Mac (brew)

No macOS com o Homebrew, isto seria mais ou menos assim:

$ 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
  • O pacote bats legado também existe no ecossistema do Homebrew. Não instales esse por engano: instala o bats-core.

Para Linux

Fedora 30 e versões mais recentes

O bats está empacotado para o Fedora 30 e versões mais recentes; podes instalá-lo com

sudo dnf install bats

Outras distribuições de Linux

Para outras distribuições de Linux, a implementação do bats que usamos pode não estar disponível num pacote conveniente. A melhor forma de o instalar é a partir do código-fonte. Se quiseres instalá-lo em /usr/local, então

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

Depois disso, partindo do princípio de que /usr/local/bin está no teu $PATH, podes agora fazer:

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

Para Windows (MINGW64/Cygwin)

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

Nota: se estiveres a usar o já desatualizado https://github.com/sstephenson/bats.git e encontrares um erro como cp: cannot create symbolic link '${HOME}/bin/bats': No such file or directory, tens de copiar manualmente o conteúdo da pasta bin/bats/libexec/ para ${HOME}/bin/.

Há relatos de que as versões mais recentes do bats não se dão bem com o bash do MinGW. Antes de correres o script de instalação, podes querer:

$ git checkout v1.1.0

bats-assert

Para saberes o significado dos vários comandos assert* nos testes, consulta a documentação da biblioteca bats-assert.

Testes ignorados

Resolver um exercício significa fazer passar todos os seus testes. Por predefinição, só um teste (o primeiro) é executado quando corres os testes. Isto é intencional, pois permite-te focar-te apenas em fazer passar esse teste. Assim que passar, podes ativar o teste seguinte comentando ou removendo as

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

anotações que precedem os outros testes.

Anular os testes ignorados

Para correres todos os testes, incluindo os que têm anotações skip, podes definir a variável de ambiente BATS_RUN_SKIPPED com o valor true. Uma forma de a definir apenas enquanto corres o bats é:

BATS_RUN_SKIPPED=true bats exercise_name.bats

Pode ser conveniente usar uma função wrapper para escrever menos:

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

Depois, corre os testes apenas com:

bats

bats legado

O bats-core resultou de um fork da implementação original do bats. O projeto sstephenson/bats tinha bastantes bugs e estava abandonado. A propriedade foi transferida em 2017: sstephenson/bats#150 (comentário).

Se tiveres o sstephenson/bats original instalado (verifica com bats -v; se reportar um número de versão inferior a 1.0), deves mudar para o bats-core; caso contrário, podes ver-te a ter falhas de teste inexplicáveis.