Temos um sistema que possui alguns scripts bash rodando além do código Java. Como estamos tentando testar tudo que pode possivelmente quebrar, e esses scripts bash podem falhar, queremos testá-los.
O problema é que é difícil testar scripts bash.
Existe uma maneira ou uma prática recomendada para testar scripts bash? Ou devemos parar de usar scripts bash e procurar soluções alternativas testáveis?
Respostas:
Na verdade, existe um shunit2 , uma estrutura de teste de unidade baseada em xUnit para scripts de shell baseados em Bourne. Eu não usei sozinho, mas pode valer a pena conferir.
Perguntas semelhantes já foram feitas antes:
fonte
Recebi a seguinte resposta de um grupo de discussão:
Este método é como injeção de dependência para scripts e parece razoável. É preferível evitar scripts bash e usar uma linguagem mais testável e menos obscura.
fonte
Teste Bash compatível com TAP : Sistema de teste automatizado Bash
núcleo de morcego
fonte
Nikita Sobolev escreveu uma excelente postagem no blog comparando algumas estruturas de teste bash diferentes: Testando aplicativos Bash
Para os impacientes: a conclusão de Nikita foi usar Bats, mas parece que Nikita perdeu o projeto Bats-core , que me parece ser aquele a usar daqui para frente, já que o projeto Bats original não foi mantido ativamente desde 2013.
fonte
Epoxy é uma estrutura de teste Bash que projetei principalmente para testar outro software, mas também o uso para testar módulos bash, incluindo ele próprio e o Carton .
As principais vantagens são a sobrecarga de codificação relativamente baixa, aninhamento de asserções ilimitado e seleção flexível de asserções a serem verificadas.
Fiz uma apresentação comparando-o ao BeakerLib - um framework usado por alguns na Red Hat.
fonte
Por que você diz que é "difícil" testar scripts bash?
O que há de errado com wrappers de teste como:
fonte
Eu criei shellspec porque queria uma ferramenta útil e fácil de usar.
Escrito por puro script de shell POSIX. Ele foi testado com muitos shells mais do que shunit2. Possui recursos poderosos do que morcegos / núcleo de morcegos.
Por exemplo, suporte a bloco aninhado, fácil de simular / stub, fácil de pular / pendente, testes parametrizados, número de linha de asserção, execução por número de linha, execução paralela, execução aleatória, formatador TAP / JUnit, cobertura e integração de CI, criador de perfil e etc .
Veja a demonstração na página do projeto.
fonte
Eu gosto bastante do shell2junit , um utilitário para gerar saída do tipo JUnit de testes de script Bash. Isso é útil porque o relatório gerado pode ser lido por sistemas de integração contínua, como os plug-ins JUnit para Jenkins e Bamboo.
Embora o shell2junit não forneça a estrutura de script Bash abrangente como o shunit2 , ele permite que você tenha bons relatórios dos resultados do teste.
fonte
Tente bashtest . É uma maneira simples de testar seus scripts. Por exemplo, você tem
do-some-work.sh
que alterar alguns arquivos de configuração. Por exemplo, adicione uma nova linhaPASSWORD = 'XXXXX'
ao arquivo de configuração/etc/my.cfg
.Você escreve os comandos do bash linha por linha e verifica a saída.
Instalar:
Criar testes é apenas escrever comandos bash.
Arquivo
test-do-some-work.bashtest
:Execute testes:
Você pode encontrar alguns exemplos aqui e aqui
fonte
Talvez isso possa ser usado ou contribuído para
https://thorsteinssonh.github.io/bash_test_tools/
Destina-se a escrever resultados em protocolo TAP que imagino ser bom para CI e bom para aqueles que desejam ambientes shell. Imagino que algumas coisas sejam executadas em ambientes de shell, portanto, alguns podem argumentar que devem ser testados em seu ambiente de shell.
fonte
Experimente assert.sh
Espero que ajude!
fonte
Não acredito que ninguém falou sobre OSHT ! É compatível com ambos TAP e JUnit, é pura shell (isto é, há outros idiomas envolvidos), ele funciona autônomo também, e é simples e direta.
O teste se parece com isto (fragmentos retirados da página do projeto):
Uma corrida simples:
O último teste mostra "não está ok", mas o código de saída é 0 porque é um
TODO
. Pode-se definir verbose também:Renomeie-o para usar uma
.t
extensão e coloque-o em umt
subdiretório, e você pode usarprove(1)
(parte do Perl) para executá-lo:Defina
OSHT_JUNIT
ou passe-j
para produzir saída JUnit. JUnit também pode ser combinado comprove(1)
.Eu usei essa biblioteca tanto funções de teste, fornecendo seus arquivos e, em seguida, executando assertions com
IS
/OK
e seus negativos, quanto scripts usandoRUN
/NRUN
. Para mim, essa estrutura fornece mais ganho com o mínimo de sobrecarga.fonte
Tentei muitas das soluções apresentadas aqui, mas achei a maioria delas muito volumosas e difíceis de usar, então criei minha própria pequena estrutura de teste: https://github.com/meonlol/t-bash
É apenas um arquivo no repo que você pode simplesmente executar diretamente, com um conjunto básico de declarações de estilo JUnit.
Usei-o profissionalmente em vários projetos internos e fui capaz de tornar nossos scripts bash superestáveis e resistentes a regressões.
fonte
Você pode querer dar uma olhada em bash_unit:
https://github.com/pgrange/bash_unit
fonte
Dê uma olhada no Outthentic , é simples, extensível por várias linguagens (Perl, Python, Ruby, Bash na escolha) e plataforma cruzada (Linux, Windows) para testar qualquer aplicação de linha de comando.
fonte
Achei difícil justificar o uso do bash para scripts maiores quando o Python tem grandes vantagens:
if [ x"$foo" = x"$bar"]; then ...
', que está sujeita a erros.getopt
módulo (e há um módulo ainda mais fácil para análise de argumentos, mas o nome me escapa).mysql
comando no bash, mas não é a maneira mais agradável de escrever código).$*
ou"$*"
ou"$@"
ou$1
ou"$1"
, os espaços nos nomes dos arquivos não são um problema, etc, etc, etc.Agora eu uso o bash apenas para os scripts mais simples.
fonte
if [[ $foo = $bar ]]; then ...
. Isso ainda não é melhor do que o que o python tem a oferecer, mas é melhor do que o que você apresentou.trap
(para limpar / desfazer em caso de erro), bem como regex (ou seja[[ $1 =~ ^[1-3]{3}$ ]]
). Tenho certeza de que a sintaxe obscura que você usou é uma referência a implementações antigas dotest
, não ao bash. Bash é ótimo para fazer interface com ferramentas de linha de comando existentes ... Freqüentemente, um único pipe paraawk
ougrep
é muito mais fácil do que a alternativa Python.optparse
ou seu sucessorargparse
. Nunca vi ninguém usar ogetopt
módulo, nem o usei pessoalmente. Agetopt
utilidade é ótima. A análise de argumentos a partir do shell não é um problema, uma vez que você tenha um bom padrão. A menos que você esteja tentando implementar subcomandos no estilo git ou algo assim, não é muito problema.