سؤال

لدينا نظام يحتوي على بعض نصوص bash التي تعمل إلى جانب كود Java.نظرًا لأننا نحاول اختبار كل شيء يمكن أن يتعطل، وقد تتعطل نصوص bash هذه، فإننا نريد اختبارها.

تكمن المشكلة في صعوبة اختبار نصوص bash.

هل هناك طريقة أو أفضل الممارسات لاختبار نصوص bash؟أم يجب علينا التوقف عن استخدام نصوص bash والبحث عن حلول بديلة قابلة للاختبار؟

هل كانت مفيدة؟

المحلول 2

وحصلت على الجواب التالي من مجموعة نقاش:

<اقتباس فقرة>   

وكان من الممكن لاستيراد (بما في ذلك،   أيا كان) إجراء (وظيفة،   كل ما هو اسمه) من خارجي   ملف. هذا هو المفتاح لكتابة   اختبار السيناريو: أنت تفريق الخاص بك   النصي في إجراءات مستقلة   التي يمكن بعد ذلك يمكن استيرادها إلى كل من   تشغيل البرنامج النصي والاختبار الخاص بك   النصي، ثم لديك الجري   النصي تكون بسيطة بقدر الإمكان.

وهذا الأسلوب هو مثل حقن التبعية للمخطوطات، والأصوات معقول. تجنب البرامج النصية باش واستخدام لغة أكثر قابلة للاختبار وأقل غموضا هو الأفضل.

نصائح أخرى

يوجد في الواقع أ شونيت2, ، إطار اختبار الوحدة القائم على xUnit لنصوص Shell المستندة إلى Bourne.لم أستخدمه بنفسي، لكن قد يكون من المفيد التحقق منه.

لقد تم طرح أسئلة مماثلة من قبل:

مقبض-اختبار باش المتوافق: نظام باش للاختبار الآلي

TAP، بروتوكول اختبار أي شيء، عبارة عن واجهة نصية بسيطة بين وحدات الاختبار في أداة الاختبار.بدأ TAP حياته كجزء من أداة الاختبار لـ Perl ولكن لديه الآن تطبيقات في C وC++ وPython وPHP وPerl وJava وJavaScript وغيرها.

الايبوكسي هو إطار اختبار باش أنا مصمم أساسا لاختبار البرامج الأخرى، ولكن أنا استخدامها لاختبار وحدات سحق كذلك، بما في ذلك نفسها و <لأ href = "HTTPS: // github.com/spbnick/carton/tree/master/tests "يختلط =" noreferrer "> الكرتون .

والمزايا الرئيسية هي نسبيا الترميز انخفاض النفقات العامة، غير محدود التعشيش تأكيد واختيار مرنة من التأكيدات للتحقق.

ولقد ارتكبت عرض مقارنتها <لأ href = "https://fedorahosted.org/ beakerlib / "يختلط =" noreferrer "> BeakerLib - إطار المستخدمة من قبل بعض في ريد هات

ونيكيتا سوبوليف كتب وظيفة ممتازة بلوق مقارنة عدد قليل من الأطر اختبار باش مختلفة: <لأ href = "https://medium.com/wemake-services/testing-bash-applications-85512e7fe2de" يختلط = "noreferrer" = عنوان "تطبيقات اختبار باش"> تطبيقات اختبار باش

لالصبر: كان الاستنتاج نيكيتا لاستخدام الخفافيش ولكن يبدو أن نيكيتا غاب عن مشروع الخفافيش النواة التي يبدو لي أن أكون واحدة للاستخدام في المستقبل، إذ المشروع الخفافيش الأصلية لم يتم الحفاظ بنشاط منذ عام 2013.

وماذا أقول أنه في "من الصعب" لاختبار البرامج النصية باش؟

ما هو الخطأ مع مغلفة اختبار مثل:

 #!/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 أو أداة لتوليد أداة JUnit مثل الإخراج من الاختبارات النصي باش. هذا مفيد لأن التقرير الذي تم إنشاؤه ثم يمكن قراءتها من قبل أنظمة التكامل المستمر، مثل أداة JUnit المكونات الإضافية لجنكينز والخيزران.

وعلى الرغم shell2junit لا يوفر إطار البرمجة باش شامل مثل shunit2 ، فإنه لا يسمح لديك التقارير لطيفة من نتائج الاختبار.

bashtest . سيصدره طريقة بسيطة لاختبار البرامج النصية. على سبيل المثال، لديك do-some-work.sh مما يؤدي إلى تغيير بعض ملفات التكوين. على سبيل المثال، إضافة PASSWORD = 'XXXXX' خط جديد ل/etc/my.cfg ملف التكوين.

وتكتب باش خط الأوامر عن طريق خط ومن ثم تحقق الانتاج.

وتثبيت:

pip3 install bashtest

إنشاء الاختبارات هو مجرد كتابة أوامر باش.

و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

ويمكنك العثور بعض الأمثلة هنا و <لأ href = " https://github.com/pahaz/bashtest/blob/master/test_wc.bashtest "يختلط =" نوفولو "> هنا

وربما هذا يمكن استخدامها، أو ساهم في

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

وتهدف إلى النتائج الكتابة في بروتوكول TAP الذي أتصور هو جيد ل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

وA المدى بسيط:

$ 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) (جزء من بيرل) لتشغيله:

$ 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. أداة JUnit يمكن أيضا أن تكون جنبا إلى جنب مع prove(1).

ولقد استخدمت هذه المكتبة على حد سواء وظائف اختبار من قبل مصادر ملفاتهم ومن ثم تشغيل التأكيدات مع IS / OK والسلبيات، ووالكتابات باستخدام RUN / NRUN. بالنسبة لي، ويوفر هذا الإطار معظم مكاسب لأقل النفقات العامة.

صنعت com.shellspec لأنني أردت أداة سهلة الاستخدام ومفيدة.

تمت كتابته بواسطة برنامج POSIX Shell النصي النقي.لقد تم اختباره مع العديد من القذائف أكثر من الشونيت 2.لديها ميزات قوية من الخفافيش/الخفافيش الأساسية.

على سبيل المثال، دعم الكتلة المتداخلة، سهلة الاستهزاء/الكعب، سهلة التخطي/التعليق، اختبارات ذات معلمات، رقم سطر التأكيد، التنفيذ حسب رقم السطر، التنفيذ المتوازي، التنفيذ العشوائي، تنسيق TAP/JUnit، التغطية وتكامل CI، ملف التعريف وما إلى ذلك .

انظر العرض التوضيحي على صفحة المشروع.

ولقد حاول الكثير من الحلول المقدمة هنا، ولكن وجدت معظمهم في ضخمة وصعبة الاستخدام، لذلك أنا بنيت بلدي إطار القليل الاختبار: <لأ href = "https://github.com/meonlol / تي باش "يختلط =" noreferrer نوفولو "> https://github.com/meonlol/t-bash

وانها ملف واحد فقط في الريبو التي يمكن تشغيلها ببساطة مباشرة، مع مجموعة أساسية من نمط أداة JUnit يؤكد.

ولقد استعملت مهنيا في العديد من المشاريع الداخلية وتمكنوا من جعل لدينا باش مخطوطات مستقرة فائقة ومقاومة الانحدار.

وأنت قد ترغب في إلقاء نظرة على bash_unit:

https://github.com/pgrange/bash_unit

نلقي نظرة على أصلي, إنه بسيط وقابل للتوسيع بواسطة العديد من اللغات (Perl وPython وRuby وBash عند الاختيار) وإطار عمل متعدد المنصات (Linux وWindows) لاختبار أي تطبيقات سطر أوامر.

لقد وجدت صعوبة في تبرير استخدام bash للنصوص الأكبر حجمًا بايثون لديه مثل هذه المزايا الضخمة:

  • يسمح Try/Except بكتابة نصوص برمجية أكثر قوة مع إمكانية التراجع عن التغييرات في حالة حدوث خطأ.
  • ليس عليك استخدام بناء جملة غامض مثل "if [ x"$foo" = x"$bar"]; then ..." والتي هي عرضة للأخطاء.
  • من السهل تحليل الخيارات والوسائط باستخدام getopt الوحدة النمطية (وهناك وحدة أسهل لتحليل الوسائط، لكن الاسم يغيب عني).
  • تتيح لك Python العمل مع القوائم/الإملاءات والكائنات بدلاً من السلاسل والمصفوفات الأساسية.
  • الوصول إلى أدوات اللغة المناسبة مثل regex وقواعد البيانات (بالتأكيد يمكنك توجيه كل شيء إلى ملف mysql أمر في bash، ولكنها ليست أفضل طريقة لكتابة التعليمات البرمجية).
  • لا داعي للقلق بشأن استخدام النموذج الصحيح $* أو "$*" أو "$@" أو $1 أو "$1", ، المسافات في أسماء الملفات ليست مشكلة، وما إلى ذلك، وما إلى ذلك.

الآن أستخدم bash فقط لأبسط البرامج النصية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top