셸 스크립트에 대한 단위 테스트
내가 수년 동안 작업해온 거의 모든 제품에는 일정 수준의 셸 스크립트 (또는 Windows의 배치 파일, PowerShell 등)가 포함되어 있습니다. 대부분의 코드를 Java 또는 C ++로 작성했지만 항상 쉘 스크립트로 더 잘 수행되는 통합 또는 설치 작업이있는 것처럼 보였습니다.
따라서 쉘 스크립트는 제공된 코드의 일부가되므로 컴파일 된 코드처럼 테스트해야합니다. 누구든지 shunit2 와 같은 쉘 스크립트 단위 테스트 프레임 워크에 대한 경험이 있습니까? 지금은 주로 Linux 쉘 스크립트에 관심이 있습니다. 테스트 하네스가 다른 xUnit 프레임 워크의 기능과 사용 편의성을 얼마나 잘 복제하는지, 그리고 CruiseControl 또는 Hudson과 같은 연속 빌드 시스템과의 통합이 얼마나 쉬운 지 알고 싶습니다.
업데이트 2019-03-01 : 내 선호는 지금 박쥐 입니다. 나는 작은 프로젝트에서 몇 년 동안 그것을 사용했습니다. 나는 깨끗하고 간결한 구문을 좋아합니다. CI / CD 프레임 워크와 통합하지는 않았지만 종료 상태는 제품군의 전체적인 성공 / 실패를 반영합니다. 이는 아래에 설명 된 shunit2보다 낫습니다.
이전 답변 :
Linux 환경에서 Java / Ruby 웹 애플리케이션과 관련된 쉘 스크립트에 shunit2 를 사용 하고 있습니다. 사용하기 쉬웠으며 다른 xUnit 프레임 워크에서 크게 벗어나지 않았습니다.
CruiseControl 또는 Hudson / Jenkins와의 통합을 시도하지 않았지만 다른 수단을 통해 지속적 통합을 구현할 때 다음과 같은 문제가 발생했습니다.
- 종료 상태 : 테스트 스위트가 실패하면 shunit2는 0이 아닌 종료 상태를 사용하여 실패를 전달하지 않습니다. 따라서 shunit2 출력을 구문 분석하여 제품군의 통과 / 실패를 결정하거나 shunit2를 일부 연속 통합 프레임 워크가 예상 한대로 작동하도록 변경하여 종료 상태를 통해 통과 / 실패를 전달해야합니다.
- XML 로그 : shunit2는 결과의 JUnit 스타일 XML 로그를 생성하지 않습니다.
왜 아무도 BATS를 언급하지 않았는지 궁금합니다 . 최신이며 TAP를 준수합니다.
설명 :
#!/usr/bin/env bats
@test "addition using bc" {
result="$(echo 2+2 | bc)"
[ "$result" -eq 4 ]
}
운영:
$ bats addition.bats
✓ addition using bc
1 tests, 0 failures
@ blake-mizerany의 Roundup은 훌륭하게 들리며 앞으로도 활용해야하지만 여기에 단위 테스트를 만드는 "가난한"접근 방식이 있습니다.
- 테스트 가능한 모든 것을 함수로 분리하십시오.
- 외부 파일로 기능을 이동 말
functions.sh
과source
는 스크립트로.source `dirname $0`/functions.sh
이 목적으로 사용할 수 있습니다 . 끝
functions.sh
에서 아래 if 조건에 테스트 케이스를 삽입합니다.if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then fi
테스트는 종료 코드 및 변수 값에 대한 간단한 검사가 뒤 따르는 함수에 대한 문자 호출입니다. 쉽게 작성할 수 있도록 아래와 같은 간단한 유틸리티 함수를 추가하고 싶습니다.
function assertEquals() { msg=$1; shift expected=$1; shift actual=$1; shift if [ "$expected" != "$actual" ]; then echo "$msg EXPECTED=$expected ACTUAL=$actual" exit 2 fi }
마지막으로
functions.sh
직접 실행하여 테스트를 실행합니다.
다음은 접근 방식을 보여주는 샘플입니다.
#!/bin/bash
function adder()
{
return $(($1+$2))
}
(
[[ "${BASH_SOURCE[0]}" == "${0}" ]] || exit 0
function assertEquals()
{
msg=$1; shift
expected=$1; shift
actual=$1; shift
/bin/echo -n "$msg: "
if [ "$expected" != "$actual" ]; then
echo "FAILED: EXPECTED=$expected ACTUAL=$actual"
else
echo PASSED
fi
}
adder 2 3
assertEquals "adding two numbers" 5 $?
)
모집 : http://bmizerany.github.com/roundup/
자세히 설명하는 README의 기사에 대한 링크가 있습니다.
roundup 및 shunit2 외에도 shell 단위 테스트 도구에 대한 개요에는 assert.sh 및 shelltestrunner가 포함 되었습니다 .
I mostly agree with roundup author's critique of shunit2 (some of it subjective), so I excluded shunit2 after looking at the documentation and examples. Although, it did look familiar having some experience with jUnit.
In my opinion shelltestrunner is the most original of the tools I've looked at since it uses simple declarative syntax for test case definition. As usual, any level of abstraction gives some convenience at the cost of some flexibility. Even though, the simplicity is attractive I found the tool too limiting for the case I had, mainly because of the lack of a way to define setup/tearDown actions (for example, manipulate input files before a test, remove state files after a test, etc.).
I was at first a little confused that assert.sh only allows asserting either output or exit status, while I needed both. Long enough to write a couple of test cases using roundup. But I soon found the roundup's set -e
mode inconvenient as non-zero exit status is expected in some cases as a means of communicating the result in addition to stdout, which makes the test case fail in said mode. One of the samples shows the solution:
status=$(set +e ; rup roundup-5 >/dev/null ; echo $?)
But what if I need both the non-zero exit status and the output? I could, of course, set +e
before invocation and set -e
after or set +e
for the whole test case. But that's against the roundup's principle "Everything is an Assertion". So it felt like I'm starting to work against the tool.
By then I've realized the assert.sh's "drawback" of allowing to only assert either exit status or output is actually a non-issue as I can just pass in test
with a compound expression like this
output=$($tested_script_with_args)
status=$?
expected_output="the expectation"
assert_raises "test \"$output\" = \"$expected_output\" -a $status -eq 2"
As my needs were really basic (run a suite of tests, display that all went fine or what failed), I liked the simplicity of assert.sh, so that's what I chose.
After looking for a simple unit test framework for shell that could generate xml results for Jenkins and not really finding anything, I wrote one.
It's on sourceforge - the project's name is jshu.
http://sourceforge.net/projects/jshu
You should try out the assert.sh lib, very handy, easy to use
local expected actual
expected="Hello"
actual="World!"
assert_eq "$expected" "$actual" "not equivalent!"
# => x Hello == World :: not equivalent!
I recently released new testing framework called shellspec.
shellspec is BDD style testing framework. It's works on POSIX compatible shell script including bash, dash, ksh, busybox etc.
Of course, the exit status reflects the result of running of the specs and it's has TAP-compliant formatter.
The specfile is close to natural language and easy to read, and also it's shell script compatible syntax.
#shellcheck shell=sh
Describe 'sample'
Describe 'calc()'
calc() { echo "$(($*))"; }
It 'calculates the formula'
When call calc 1 + 2
The output should equal 3
End
End
End
참고URL : https://stackoverflow.com/questions/971945/unit-testing-for-shell-scripts
'Program Tip' 카테고리의 다른 글
치명적 : 'https://github.com'의 사용자 이름을 읽을 수 없음 : 해당 파일 또는 디렉터리가 없습니다. (0) | 2020.11.15 |
---|---|
Webpack의 규칙 대 로더-차이점은 무엇입니까? (0) | 2020.11.15 |
LRU 캐시 설계 (0) | 2020.11.14 |
GL 라이브러리 / 헤더를 얻는 방법은 무엇입니까? (0) | 2020.11.14 |
부동 소수점 나누기 대 부동 소수점 곱하기 (0) | 2020.11.14 |