linux spec 脚本,关于linux:shell脚本的单元测试

多年来,我从事的几乎所有产品都涉及到一定程度的Shell脚本(或Windows上的批处理文件,PowerShell等)。 即使我们使用Java或C ++编写了大量代码,但似乎总是存在一些集成或安装任务,而这些任务或任务可以通过Shell脚本更好地完成。

因此,shell脚本成为附带代码的一部分,因此需要像已编译的代码一样进行测试。 有没有人对其中的一些shell脚本单元测试框架有经验,例如shunit2? 目前,我主要对Linux shell脚本感兴趣。 我想知道测试工具能够很好地复制其他xUnit框架的功能和易用性,以及与持续构建系统(如CruiseControl或Hudson)进行集成的难易程度。

综述为您确定了一些任务/标签。 一旦克服了学习障碍,它就会非常有用。 我个人更喜欢haridsvs方法,因为它不需要我安装另一个pkg。 我已经将此方法应用于外壳脚本和python测试。

您还可以检查bashtest实用程序:github.com/pahaz/bashtest(这是编写bash测试的简单方法)

查看几乎所有可能工具的概述:medium.com/wemake-services/

@sobolevn非常好的文章,谢谢!

更新2019-03-01:我的偏好是现在蝙蝠。我在小型项目上使用了几年。我喜欢简洁明了的语法。我尚未将其与CI / CD框架集成在一起,但是它的退出状态确实反映了套件的整体成功/失败,这比shunit2更好,如下所述。

上一个答案:

我正在将shunit2用于与Linux环境中的Java / Ruby Web应用程序相关的shell脚本。它易于使用,并且与其他xUnit框架没有很大的不同。

我没有尝试与CruiseControl或Hudson / Jenkins集成,但是在通过其他方式实施持续集成时遇到了以下问题:

退出状态:当测试套件失败时,shunit2不会使用非零退出状态来传达失败。因此,您要么必须解析shunit2输出以确定套件的通过/失败,要么更改shunit2使其表现出某些连续集成框架所期望的行为,并通过退出状态传达通过/失败。

XML日志:shunit2不会生成JUnit样式的XML结果日志。

皮特,我即将发布一个单元测试库,该库适用于bash和ksh,使用非常简单。您可以在某个地方向我发送指向Junit样式的XML日志的链接,以便我可以看到其中包含的内容吗?如果> 0的测试失败退出1,您是否还希望退出单个失败的测试或退出测试的退出状态?现在,我的方法是可以调用一个函数来获取通过/失败的测试数量。

@EthanPost我不再使用/要求XML日志。您可以通过搜索诸如" xunit xml format"之类的内容来找到帮助。这样的事情:xunit.github.io/docs/format-xml-v2.html

shunit现在也以正确的退出代码退出:github.com/kward/shunit2/blob/

想知道为什么没人提到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

BATS +1!从github指标(12个贡献者,将近2000个星)来看,这是大多数人选择作为bash xUnit测试运行程序的工具。

+1:我前一段时间使用了BATS,但并没有完全感到不知所措。今天找到了这份出色的(独立的?)《入门指南》文档,一直沿用至今,现已在BATS上完全出售。

蝙蝠住在这里github.com/bats-core/bats-core

当我读完这个答案时,我的第一个冲动是"不,维护者没有响应问题,并且存在一些严重的错误,但是后来我发现,自从我上次使用它以来,它就已经被分叉了"。

@ blake-mizerany的综述听起来很棒,以后我应该使用它,但这是我用于创建单元测试的"穷人"方法:

将所有可测试的功能分开。

将函数移至外部文件,例如将functions.sh和source移至脚本中。您可以将source `dirname $0`/functions.sh用于此目的。

在functions.sh的结尾,如果有条件,则将测试用例嵌入以下内容:

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 $?

)

很好,谢谢-我非常喜欢针对Shell脚本的结构化编程方法。

很好的观察:将所有可测试的功能分开。即使您尚未为它编写测试,它也很重要。这是提高代码可读性的主要因素。几年前,我开始根据此原理编写(ksh)脚本。将所有内容编写为函数。

@HenkLangeveld是否会导致exit 0也导致" sourcee"(一个采购此资源)退出?我认为您正在这里寻找return。

@haridsv好问题。当您获取文件源时,您不想运行测试。通过将所有与测试相关的代码收集到一个子外壳中,我们不会破坏使用者的运行时环境。 exit 0仅终止子外壳。

@HenkLangeveld糟糕,您是对的,我没有注意您添加的括号。

太好了感谢您的详细解释。

围捕:

http://bmizerany.github.com/roundup/

自述文件中有一篇文章的链接,详细介绍了该文章。

综述还建议比赛

除了综述和shunit2之外,我对shell单元测试工具的概述还包括assert.sh和shelltestrunner。

我大体上同意综述作者对shunit2的批评(其中有些是主观的),因此在查看了文档和示例后,我排除了shunit2。虽然,对jUnit有一定的经验确实很熟悉。

我认为shelltestrunner是我看过的最原始的工具,因为它使用简单的声明性语法来定义测试用例。像往常一样,任何抽象级别都以灵活性为代价提供了一些便利。即使如此,简单性还是很吸引人,我发现该工具对我的情况而言过于局限,主要是因为缺乏定义setup / tearDown操作的方法(例如,在测试之前操作输入文件,在测试之后删除状态文件)等)。

起初我有点困惑,assert.sh只允许声明输出状态或退出状态,而我需要两者。时间足够长,可以使用总结来编写几个测试用例。但是我很快发现综述的set -e模式很不方便,因为在某些情况下,除了stdout之外,还希望使用非零退出状态来传达结果,这会使测试用例在上述模式下失败。示例之一显示了解决方案:

status=$(set +e ; rup roundup-5 >/dev/null ; echo $?)

但是,如果我既需要非零退出状态又需要输出怎么办?当然,对于整个测试用例,我可以在调用之前set +e,在调用之后set -e或set +e。但这违反了综述的原则"一切都是断言"。因此,感觉就像我开始使用该工具一样。

到那时,我已经意识到assert.sh的"缺点",即只允许声明退出状态或输出实际上是一个非问题,因为我可以使用这样的复合表达式传入test

output=$($tested_script_with_args)

status=$?

expected_output="the expectation"

assert_raises"test "$output" = "$expected_output" -a $status -eq 2"

由于我的需求确实很基本(运行一套测试,显示一切正常或失败),所以我喜欢assert.sh的简单性,因此我选择了它。

您应该尝试使用assert.sh lib,非常方便,易于使用

local expected actual

expected="Hello"

actual="World!"

assert_eq"$expected""$actual""not equivalent!"

# => x Hello == World :: not equivalent!

寻找了一个简单的shell单元测试框架后,该框架可以为Jenkins生成xml结果并且没有真正找到任何东西,然后我写了一个。

它在sourceforge上-项目的名称是jshu。

http://sourceforge.net/projects/jshu

我最近发布了称为shellspec的新测试框架。

https://shellspec.info/

https://github.com/ko1nksm/shellspec

shellspec是BDD样式测试框架。

它适用于POSIX兼容的shell脚本,包括bash,破折号,ksh,busybox等。

当然,退出状态反映了规范运行的结果

并且具有符合TAP的格式化程序。

specfile接近自然语言,易于阅读,

以及与Shell脚本兼容的语法。

#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

版本0.16.0中支持的JUnit格式化程序。并支持覆盖率,并行执行等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值