140

Javaコードの他にいくつかのBashスクリプトが実行されているシステムがあります。壊れてしまう可能性のあるすべてのものをテストしようとしているので、それらのBashスクリプトが壊れている可能性があるので、それらをテストしたいと思います。

問題は、Bashスクリプトをテストするのが難しいことです。

Bashスクリプトをテストする方法またはベストプラクティスはありますか?または、Bashスクリプトの使用をやめて、テスト可能な代替ソリューションを探す必要がありますか?

4

16 に答える 16

52

実際には、Bourneベースのシェルスクリプト用のxUnitベースのユニットテストフレームワークであるshunit2があります。自分で使ったことはありませんが、チェックする価値があるかもしれません。

同様の質問が以前に尋ねられました:

于 2009-08-27T07:43:18.627 に答える
34

TAP準拠のBashテスト:Bash自動テストシステム

Test Anything ProtocolであるTAPは、テストハーネス内のテストモジュール間の単純なテキストベースのインターフェイスです。TAPは、Perlのテストハーネスの一部として誕生しましたが、現在はC、C ++、Python、PHP、Perl、Java、JavaScriptなどで実装されています。

于 2012-11-02T16:16:08.367 に答える
31

ディスカッショングループから次の回答を得ました。

外部ファイルからプロシージャ(関数、名前が何であれ)をインポート(インクルードなど)することができます。これがテストスクリプトを作成するための鍵です。スクリプトを独立したプロシージャに分割し、実行中のスクリプトとテストスクリプトの両方にインポートして、実行中のスクリプトを可能な限りシンプルにします。

この方法は、スクリプトの依存性注入のようなものであり、合理的に聞こえます。Bashスクリプトを避け、よりテスト可能でわかりにくい言語を使用することをお勧めします。

于 2009-09-01T07:43:40.387 に答える
11

Nikita Sobolevは、いくつかの異なるBashテストフレームワークを比較する優れたブログ投稿を作成しました。Bashアプリケーションのテスト

せっかちな人のために:ニキータの結論はバットを使用することでしたが、元のバットプロジェクトは2013年以来積極的に維持されていないため、ニキータは私が今後使用するものであると思われるバットコアプロジェクトを見逃したようです。

于 2018-03-14T08:04:38.840 に答える
7

Epoxyは、主に他のソフトウェアをテストするために設計したBashテストフレームワークですが、それ自体Cartonを含むBashモジュールのテストにも使用しています。

主な利点は、コーディングオーバーヘッドが比較的低く、アサーションのネストが無制限で、検証するアサーションを柔軟に選択できることです。

私はそれをBeakerLib(Red Hatの一部で使用されているフレームワーク)と比較してプレゼンテーションを行いました。

于 2013-09-28T08:59:43.490 に答える
7

誰もOSHTについて話していないなんて信じられません!TAPJUnitの両方 と互換性があり、純粋なシェル(つまり、他の言語は含まれていません)であり、スタンドアロンでも機能し、シンプルで直接的なものです。

テストは次のようになります(プロジェクトページから取得したスニペット):

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

最後のテストは「問題あり」と表示されますが、終了コードは。であるため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名前を変更して拡張子を使用し、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

JUnit出力を生成するために設定OSHT_JUNITまたはパスします。-jJUnitは。と組み合わせることもできますprove(1)

私はこのライブラリを使用して、ファイルをソーシングしてからIS/OKとそのネガティブを使用してアサーションを実行することで関数をテストし、/を使用してスクリプトをRUN実行しましたNRUN。私にとって、このフレームワークは最小のオーバーヘッドで最大の利益を提供します。

于 2019-06-12T17:50:35.983 に答える
7

使いやすく便利なツールが欲しかったので、shellspecを作成しました。

純粋なPOSIXシェルスクリプトで記述されています。shunit2よりも多くのシェルでテストされています。bats/bats-coreよりも強力な機能があります。

たとえば、ネストされたブロック、モック/スタブが簡単、スキップ/保留が簡単、パラメーター化されたテスト、アサーション行番号、行番号による実行、並列実行、ランダム実行、TAP / JUnitフォーマッター、カバレッジとCI統合、プロファイラー、等

プロジェクトページのデモを参照してください。

于 2019-07-09T06:52:17.087 に答える
6

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
 }
于 2009-08-27T07:56:42.283 に答える
4

assert.shを試してみてください:

source "./assert.sh"

local expected actual
expected="Hello"
actual="World!"
assert_eq "$expected" "$actual" "not equivalent!"
# => x Hello == World :: not equivalent!
于 2017-05-06T20:47:58.710 に答える
3

私はshell2junitがとても好きです。これは、BashスクリプトテストからJUnitのような出力を生成するユーティリティです。生成されたレポートは、 JenkinsBamboo用のJUnitプラグインなどの継続的インテグレーションシステムで読み取ることができるため、これは便利です。

shell2junitはshunit2のような包括的なBashスクリプトフレームワークを提供していませんが、テスト結果の優れたレポートを作成できます。

于 2014-01-17T22:33:59.923 に答える
3

bashtestを試してください。スクリプトをテストする簡単な方法です。たとえば、do-some-work.shいくつかの構成ファイルを変更するものがあります。たとえば、PASSWORD = 'XXXXX'構成ファイルに新しい行、を追加します/etc/my.cfg

Bashコマンドを1行ずつ記述してから、出力を確認します。

インストール:

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

こことここにいくつかの例があります。

于 2016-07-26T05:27:48.370 に答える
3

たぶん、これは使用することができます、または貢献することができます:

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

これは、 CIに適し、シェル環境が必要なユーザーに適していると私が想像するTAPプロトコルで結果を書き込むことを目的としています。シェル環境で実行されるものもあると思います。そのため、シェル環境でテストする必要があると主張する人もいるかもしれません。

于 2016-08-05T17:52:36.787 に答える
2

ここに示す多くのソリューションを試しましたが、それらのほとんどがかさばりすぎて使いにくいことがわかったので、独自の小さなテストフレームワークを構築しました:https ://github.com/meonlol/t-bash

これは、 JUnitスタイルの基本セットを使用して、直接実行できるリポジトリ内の1つのファイルです。

私はこれをいくつかの内部プロジェクトで専門的に使用し、Bashスクリプトを非常に安定して回帰耐性を持たせることができました。

于 2019-07-06T15:56:24.567 に答える
0

bash_unitを確認することをお勧めします。

https://github.com/pgrange/bash_unit

于 2016-04-04T09:30:00.060 に答える
0

Outthenticを見てください。シンプルで、多くの言語(PerlPythonRuby、Bashを選択)およびクロスプラットフォーム(LinuxおよびWindows)フレームワークで拡張可能であり、任意のコマンドラインアプリケーションをテストできます。

于 2018-09-28T19:27:46.130 に答える
0

テストを作成しますmytest.sh。特定の入力を使用してスクリプトを呼び出します。

テキストファイルを作成しますexpected/mytest.stdout。これには、テストで期待される出力が含まれています。

それらをバージョン管理(存在する場合)にコミットします。

テストを実行し、出力を別のファイルにリダイレクトします。

mytest.sh > actual/mytest.stdout

次に、テキスト差分ツールを使用して、結果がどこから逸脱しているかを確認します。私はあなたがただできると思います

diff expected/mytest.stdout actual/mytest.stdout
于 2021-02-18T01:38:03.040 に答える