programing

유닛 테스트 Bash 스크립트

codeshow 2023. 4. 17. 22:12
반응형

유닛 테스트 Bash 스크립트

Java 코드 외에 일부 Bash 스크립트를 실행하는 시스템이 있습니다.파손될 가능성이 있는 모든 것을 테스트하려고 합니다.또, 이러한 Bash 스크립트가 파손될 가능성이 있기 때문에, 그것들을 테스트하고 싶다고 생각하고 있습니다.

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

Bash 스크립트를 테스트하는 방법 또는 베스트 프랙티스가 있습니까?아니면 Bash 스크립트 사용을 중지하고 테스트 가능한 대체 솔루션을 찾아야 합니까?

실제로 Shunit2는 Bourne 기반 셸 스크립트의 xUnit 기반 유닛 테스트 프레임워크입니다.직접 써본 적은 없지만 확인해 볼 만할 것 같아요.

이전에도 비슷한 질문을 한 적이 있습니다.

TAP 준거 Bash 테스트: Bash 자동 테스트 시스템

TAP(Test Anything Protocol)은 테스트 하니스에 있는 테스트 모듈 간의 단순한 텍스트 기반 인터페이스입니다.TAP은 Perl의 테스트 하네스의 일부로 시작되었지만, 현재는 C, C++, Python, PHP, Perl, Java, JavaScript 및 기타로 구현되어 있습니다.

토론 그룹으로부터 다음과 같은 답변을 받았습니다.

외부 파일에서 프로시저(함수, 이름 등)를 Import(임포트)할 수 있습니다.이것이 테스트 스크립트를 작성하기 위한 열쇠입니다.스크립트를 독립된 프로시저로 분할하여 실행 중인 스크립트와 테스트 스크립트로 Import할 수 있습니다.그 후 실행 중인 스크립트를 가능한 한 심플하게 만듭니다.

이 방법은 스크립트에 대한 종속성 주입과 비슷하며 합리적인 것으로 보입니다.Bash 스크립트를 피하고 테스트 가능한 언어를 사용하는 것이 좋습니다.

사용하기 쉽고 편리한 툴을 원했기 때문에 셸 스펙을 작성했습니다.

순수한 POSIX 쉘 스크립트로 작성되었습니다.shunit2보다 더 많은 셸을 사용하여 테스트되었습니다.배트코어보다 파워풀한 기능을 갖추고 있습니다.

예를 들어, 중첩된 블록, 모킹/스탭, 건너뛰기/보류하기 쉬운, 파라미터화된 테스트, 어설션 라인 번호, 행 번호별 실행, 병렬 실행, 랜덤 실행, TAP/JUnit 포맷터, 커버리지 CI 통합, 프로파일러 등을 지원합니다.

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

Nikita Sobolev는 몇 가지 다른 Bash 테스트 프레임워크를 비교한 훌륭한 블로그 투고를 작성했습니다.Bash 응용 프로그램 테스트 중

참을성이 없는 분들을 위해:니키타의 결론은 Bats를 사용하는 것이었지만, 2013년 이후 Bats의 원래 프로젝트가 활발하게 유지되지 않았기 때문에 앞으로 사용할 수 있을 것 같은 Bats-core 프로젝트를 Nikita가 놓친 것 같습니다.

아무도 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

에서는 " ok"로 ok"이므로입니다.이는 이 코드가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[(Extension)]에합니다.t하면 "subdirectory"를 사용할 수 .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쥬니트은 JUnit와 도 있습니다.prove(1).

는 두 가지 을 모두 .이러한 기능을 로 하고 , 「」을 실행하고 있습니다.IS/OK네거티브와 는 「네거티브」를 사용하고 있습니다.RUN/NRUN이 프레임워크는 최소한의 오버헤드로 최대의 이익을 가져옵니다.

왜 Bash 스크립트를 테스트하는 것이 어렵다고 합니까?

이런 시험용 포장지가 뭐가 문제죠?

 #!/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
 }

Epoxy는 주로 다른 소프트웨어를 테스트하기 위해 설계된 Bash 테스트 프레임워크이지만, 그 자체와 카톤을 포함한 Bash 모듈 테스트에도 사용합니다.

주요 장점은 상대적으로 낮은 코딩 오버헤드, 무제한 어설션 중첩 및 검증할 어설션의 유연한 선택이다.

Red Hat에서 일부 사람들이 사용하는 프레임워크인 Beaker Lib과 비교해서 프레젠테이션을 했습니다.

assert.sh에 접속해 보세요.

source "./assert.sh"

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

저는 Bash 스크립트 테스트에서 JUnit과 같은 출력을 생성하는 유틸리티인 shell2junit을 매우 좋아합니다.생성된 보고서는 Jenkins Bampoo용 JUnit 플러그인과 같은 연속 통합 시스템에서 읽을 수 있으므로 유용합니다.

shell2junit은 shunit2와 같은 포괄적인 Bash 스크립트 프레임워크를 제공하지 않지만 테스트 결과를 적절하게 보고할 수 있습니다.

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에 적합하고 쉘 환경을 원하는 사용자에게 적합한 TAP 프로토콜에 결과를 쓰는 것을 목적으로 합니다.셸 환경에서 실행되는 것도 있기 때문에 셸 환경에서 테스트해야 한다는 주장도 있을 수 있습니다.

저는 여기에 제시된 많은 솔루션을 시도해 보았습니다만, 그 대부분이 너무 크고 사용하기 어렵다는 것을 깨달았습니다.그래서 저는 저만의 작은 테스트 프레임워크를 구축했습니다.https://github.com/SnacOverflow/t-bash

JUnit 스타일의 기본 세트를 사용하여 간단하게 직접 실행할 수 있는 저장소의 파일 1개뿐입니다.

여러 사내 프로젝트에서 프로페셔널하게 사용해 왔으며, Bash 스크립트를 매우 안정적이고 회귀에 강한 상태로 만들 수 있었습니다.

테스트 작성mytest.sh특정 입력을 사용하여 스크립트를 호출합니다.

텍스트 파일 생성expected/mytest.stdout테스트에 대한 예상 출력이 포함되어 있습니다.

버전 관리(있는 경우)에 커밋합니다.

테스트를 실행하여 출력을 다른 파일로 리디렉션합니다.

mytest.sh > actual/mytest.stdout

그러면 결과가 어떻게 달라지는지 텍스트 차이 도구만 있으면 됩니다.그냥 하면 될 것 같아요.

diff expected/mytest.stdout actual/mytest.stdout

bash_unit을 살펴보는 것이 좋습니다.

https://github.com/pgrange/bash_unit

아웃텐틱을 보세요.여러 언어(Perl, Python, Ruby 및 Bash 선택) 및 크로스 플랫폼(Linux 및 Windows) 프레임워크에서 모든 명령줄 애플리케이션을 테스트하기 위해 간단하고 확장 가능합니다.

언급URL : https://stackoverflow.com/questions/1339416/unit-testing-bash-scripts

반응형