문제

Java 코드 외에 Bash 스크립트가 실행되는 시스템이 있습니다. 우리는 파손될 수있는 모든 것을 테스트하려고 노력하고 있으며, 그 배쉬 스크립트가 깨질 수 있기 때문에 테스트하고 싶습니다.

문제는 Bash 스크립트를 테스트하기가 어렵다는 것입니다.

Bash 스크립트를 테스트하는 방법이나 모범 사례가 있습니까? 아니면 Bash 스크립트를 사용하여 종료하고 테스트 가능한 대체 솔루션을 찾아야합니까?

도움이 되었습니까?

해결책 2

토론 그룹으로부터 다음 답변을 얻었습니다.

외부 파일에서 프로 시저 (기능, 이름이 무엇이든)를 가져올 수 있습니다. 이것이 테스트 스크립트를 작성하는 열쇠입니다. 스크립트를 독립적 인 절차로 나누어 실행중인 스크립트와 테스트 스크립트로 가져올 수있는 다음 실행 스크립트를 최대한 간단하게해야합니다.

이 방법은 스크립트의 종속성 주입과 같으며 합리적으로 들립니다. 배쉬 스크립트를 피하고보다 테스트 가능하고 모호한 언어를 사용하는 것이 좋습니다.

다른 팁

실제로 A가 있습니다 Shunit2, Bourne 기반 쉘 스크립트를위한 Xunit 기반 단위 테스트 프레임 워크. 나는 그것을 직접 사용하지 않았지만 체크 아웃 할 가치가있을 수 있습니다.

이전에 비슷한 질문을했습니다.

수도꼭지-Compliant Bash 테스트 : 배쉬 자동 테스트 시스템

TAP, TEST TEST ATHOR PROTOCOL은 테스트 하네스에서 테스트 모듈 간의 간단한 텍스트 기반 인터페이스입니다. TAP는 PERL의 테스트 하네스의 일부로 시작되었지만 이제 C, C ++, Python, PHP, Perl, Java, JavaScript 등으로 구현되었습니다.

에폭시 주로 다른 소프트웨어를 테스트하기 위해 설계된 Bash 테스트 프레임 워크이지만,이를 사용하여 Bash 모듈을 테스트하는 데 사용합니다. 그 자체 그리고 판지 상자.

주요 장점은 상대적으로 낮은 코딩 오버 헤드, 무제한 주장 중첩 및 유연한 주장을 확인할 수 있습니다.

나는 만들었다 프레젠테이션 비교 Beakerlib - 레드 모자에서 사용하는 프레임 워크.

Nikita Sobolev는 몇 가지 다른 Bash 테스트 프레임 워크를 비교하는 훌륭한 블로그 게시물을 썼습니다. 배쉬 응용 프로그램 테스트

참을성이없는 경우 : Nikita의 결론은 사용하는 것이 었습니다. 박쥐 그러나 Nikita는 그것을 놓친 것 같습니다 박쥐 코어 2013 년부터 원래 BATS 프로젝트가 적극적으로 유지되지 않았기 때문에 앞으로 나아갈 수있는 프로젝트는 나에게 나타납니다.

배쉬 스크립트를 테스트하는 것이 "어려운"이유는 무엇입니까?

테스트 포장지의 문제점은 다음과 같습니다.

 #!/bin/bash
 set -e
 errors=0
 results=$($script_under_test $args<<ENDTSTDATA
 # inputs
 # go
 # here
 #
 ENDTSTDATA
 )
 [ "$?" -ne 0 ] || {
     echo "Test returned error code $?" 2>&1
     let errors+=1
     }

 echo "$results" | grep -q $expected1 || {
      echo "Test Failed.  Expected $expected1"
      let errors+=1
 }
 # and so on, et cetera, ad infinitum, ad nauseum
 [ "$errors" -gt 0 ] && {
      echo "There were $errors errors found"
      exit 1
 }

나는 꽤 좋아한다 Shell2Junit, Bash 스크립트 테스트에서 Junit와 같은 출력을 생성하는 유틸리티. 이것은 Jenkins 및 Bamboo 용 Junit 플러그인과 같은 지속적인 통합 시스템에 의해 생성 된 보고서를 읽을 수 있기 때문에 유용합니다.

Shell2Junit은 다음과 같은 포괄적 인 bash 스크립팅 프레임 워크를 제공하지 않습니다. Shunit2, 테스트 결과를 잘보고 할 수 있습니다.

노력하다 bashtest. 스크립트를 테스트하는 간단한 방법입니다. 예를 들어, 당신은 가지고 있습니다 do-some-work.sh 일부 구성 파일을 변경합니다. 예를 들어 새 줄을 추가하십시오 PASSWORD = 'XXXXX' 파일을 구성합니다 /etc/my.cfg.

Bash 명령을 라인별로 작성한 다음 출력을 확인합니다.

설치:

pip3 install bashtest

테스트 작성은 단지 쓰기 Bash 명령입니다.

파일 test-do-some-work.bashtest:

# run the script  
$ ./do-some-work.sh > /dev/null

# testing that the line "PASSWORD = 'XXXXX'" is in the file /etc/my.cfg   
$ grep -Fxq "PASSWORD = 'XXXXX'" /etc/my.cfg && echo "YES"
YES

실행 테스트 :

bashtest *.bashtest

당신은 찾을 수 있습니다 여기에 몇 가지 예가 있습니다 그리고 여기

어쩌면 이것은 사용하거나 기여할 수 있습니다

https://thorsteinssonh.github.io/bash_test_tools/

CI에 적합하고 쉘 환경을 원하는 사람들에게는 탭 프로토콜에 결과를 작성하려고합니다. 일부는 쉘 환경에서 실행되므로 일부는 쉘 환경에서 테스트해야한다고 주장 할 수도 있습니다.

시도해보십시오 assert.sh

source "./assert.sh"

local expected actual
expected="Hello"
actual="World!"
assert_eq "$expected" "$actual" "not equivalent!"
# => x Hello == World :: not equivalent!

도움이되기를 바랍니다!

나는 아무도 이야기하지 않았다는 것을 믿을 수 없다 OSHT! 호환됩니다 둘 다 Tap 및 Junit, 그것은 순수한 쉘 (즉, 다른 언어가 포함되지 않음)이며 독립형으로 작동하며 간단하고 직접적입니다.

테스트는 다음과 같습니다 (프로젝트 페이지에서 가져온 스 니펫) :

#!/bin/bash
. osht.sh

# Optionally, indicate number of tests to safeguard against abnormal exits
PLAN 13

# Comparing stuff
IS $(whoami) != root
var="foobar"
IS "$var" =~ foo
ISNT "$var" == foo

# test(1)-based tests
OK -f /etc/passwd
NOK -w /etc/passwd

# Running stuff
# Check exit code
RUNS true
NRUNS false

# Check stdio/stdout/stderr
RUNS echo -e 'foo\nbar\nbaz'
GREP bar
OGREP bar
NEGREP . # verify empty

# diff output
DIFF <<EOF
foo
bar
baz
EOF

# TODO and SKIP
TODO RUNS false
SKIP test $(uname -s) == Darwin

간단한 달리기 :

$ bash test.sh
1..13
ok 1 - IS $(whoami) != root
ok 2 - IS "$var" =~ foo
ok 3 - ISNT "$var" == foo
ok 4 - OK -f /etc/passwd
ok 5 - NOK -w /etc/passwd
ok 6 - RUNS true
ok 7 - NRUNS false
ok 8 - RUNS echo -e 'foo\nbar\nbaz'
ok 9 - GREP bar
ok 10 - OGREP bar
ok 11 - NEGREP . # verify empty
ok 12 - DIFF <<EOF
not ok 13 - TODO RUNS false # TODO Test Know to fail

마지막 테스트는 "Not Ok"으로 표시되지만 종료 코드는 0이기 때문에 0입니다. TODO. 장황을 설정할 수도 있습니다.

$ OSHT_VERBOSE=1 bash test.sh # Or -v
1..13
# dcsobral \!= root
ok 1 - IS $(whoami) != root
# foobar =\~ foo
ok 2 - IS "$var" =~ foo
# \! foobar == foo
ok 3 - ISNT "$var" == foo
# test -f /etc/passwd
ok 4 - OK -f /etc/passwd
# test \! -w /etc/passwd
ok 5 - NOK -w /etc/passwd
# RUNNING: true
# STATUS: 0
# STDIO <<EOM
# EOM
ok 6 - RUNS true
# RUNNING: false
# STATUS: 1
# STDIO <<EOM
# EOM
ok 7 - NRUNS false
# RUNNING: echo -e foo\\nbar\\nbaz
# STATUS: 0
# STDIO <<EOM
# foo
# bar
# baz
# EOM
ok 8 - RUNS echo -e 'foo\nbar\nbaz'
# grep -q bar
ok 9 - GREP bar
# grep -q bar
ok 10 - OGREP bar
# \! grep -q .
ok 11 - NEGREP . # verify empty
ok 12 - DIFF <<EOF
# RUNNING: false
# STATUS: 1
# STDIO <<EOM
# EOM
not ok 13 - TODO RUNS false # TODO Test Know to fail

사용하도록 이름을 바꿉니다 .t 확장 및 그것을 a t 하위 디렉토리 및 사용할 수 있습니다 prove(1) (Perl의 일부) 실행 :

$ prove
t/test.t .. ok
All tests successful.
Files=1, Tests=13,  0 wallclock secs ( 0.03 usr  0.01 sys +  0.11 cusr  0.16 csys =  0.31 CPU)
Result: PASS

세트 OSHT_JUNIT 또는 패스 -j 주니트 출력을 생성합니다. 주니는 또한 결합 할 수 있습니다 prove(1).

파일을 소싱 한 다음 어설 션을 실행 하여이 라이브러리 테스트 기능을 사용했습니다. IS/OK 그리고 그들의 부정적인 것과 사용하여 스크립트 RUN/NRUN. 저에게 있어이 프레임 워크는 가장 적은 오버 헤드에서 가장 많은 이익을 제공합니다.

내가 만들었다 쉘 스펙 사용하기 쉽고 유용한 도구를 원했기 때문입니다.

Pure Posix Shell Script에 의해 작성되었습니다. 그것은 Shunit2보다 많은 껍질로 테스트되었습니다. 박쥐/박쥐 코어보다 강력한 기능이 있습니다.

예를 들어, 중첩 블록, 조롱하기 쉬운 블록, 쉽게 건너 뛰기 쉬운/보류, 매개 변수화 된 테스트, 어시스트 라인 번호, 라인 번호별로 실행, 병렬 실행, 랜덤 실행, 탭/주니트 포맷터, 커버리지 및 CI 통합, 프로파일 러 등 .

프로젝트 페이지의 데모를 참조하십시오.

나는 여기에 제시된 많은 솔루션을 시도했지만 대부분의 솔루션을 부피가 크고 사용하기 어렵다는 것을 알았으므로 나만의 작은 테스트 프레임 워크를 만들었습니다. https://github.com/meonlol/t-bash

junit 스타일의 기본 세트와 함께 직접 실행할 수있는 것은 저장소의 파일 하나 일뿐입니다.

나는 여러 내부 프로젝트에서 전문적으로 사용했으며 Bash 스크립트를 매우 안정적이고 회귀 방지에 저항 할 수있었습니다.

bash_unit을 살펴보고 싶을 수도 있습니다.

https://github.com/pgrange/bash_unit

보세요 외곽, 그것은 간단하고 많은 언어 (Perl, Python, Ruby, Bash On Choice) 및 크로스 플랫폼 (Linux, Windows) 프레임 워크로 확장 가능합니다.

더 큰 스크립트에 Bash를 사용하는 것이 정당화하기가 어렵다는 것을 알았습니다. 파이썬 큰 장점이 있습니다.

  • 시도/제외하면 오류가 발생한 경우 변경 사항을 취소 할 수있는보다 강력한 스크립트를 작성할 수 있습니다.
  • '와 같은 모호한 구문을 사용할 필요가 없습니다.if [ x"$foo" = x"$bar"]; then ...'오류가 발생하기 쉬운.
  • 옵션과 인수를 쉽게 구문 분석합니다 getopt 모듈 (그리고 파싱 용 인수를위한 훨씬 쉬운 모듈이 있지만 그 이름은 저를 탈출합니다).
  • Python을 사용하면 기본 문자열 및 배열 대신 목록/딕트 및 객체로 작업 할 수 있습니다.
  • Regex, 데이터베이스와 같은 적절한 언어 도구에 대한 액세스 (물론 모든 것을 mysql Bash에서 명령하지만 코드를 작성하는 가장 좋은 방법은 아닙니다).
  • 올바른 형태의 사용에 대해 걱정할 필요가 없습니다. $* 또는 "$*" 또는 "$@" 또는 $1 또는 "$1", 파일 이름의 공간은 문제가 아닙니다. 등 등.

이제 가장 간단한 스크립트에만 Bash 만 사용합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top