问题 测试命令行实用程序


我正在寻找一种方法来运行用bash或任何其他语言编写的命令行实用程序的测试。

我想找一个会有类似语句的测试框架

setup:
    command = 'do_awesome_thing'
    filename = 'testfile'
    args = ['--with', 'extra_win', '--file', filename]
    run_command command args

test_output_was_correct
    assert_output_was 'Creating awesome file "' + filename + '" with extra win.'

test_file_contains_extra_win
    assert_file_contains filename 'extra win'

据推测,基本测试用例将设置一个临时目录来运行这些命令,并在拆卸时将其删除。

我更喜欢在Python中使用某些东西,因为我比其他似乎合理的候选语言更熟悉它。

我想可能会有一些使用DSL的东西会使它有效地与语言无关(或者它自己的语言,取决于你如何看待它);但是这可能不太理想,因为我的测试技术通常涉及编写生成测试的代码。

这对谷歌来说有点困难,因为有很多关于运行测试的实用程序的信息,这与我正在寻找的东西有些相反。

支持嵌入在输出中的doctests command --help 将是一个额外的奖金:)


11964
2018-06-21 21:12


起源

您可能会从我询问有关单元测试shell脚本的问题中获得一些有用的信息: stackoverflow.com/questions/971945/... - gareth_bowles
@gareth_bowles:很酷,谢谢你的链接。我可能会尝试使用shunit2,如果它是bash兼容的。 - intuited


答案:


查看 ScriptTest :

from scripttest import TestFileEnvironment

env = TestFileEnvironment('./scratch')

def test_script():
    env.reset()
    result = env.run('do_awesome_thing testfile --with extra_win --file %s' % filename)
    # or use a list like ['do_awesome_thing', 'testfile', ...]
    assert result.stdout.startswith('Creating awesome file')
    assert filename in result.files_created

它也是合理的doctest可用的。


13
2018-06-22 05:16



听起来太酷了!谢谢! - intuited


嗯......我们通常做的(以及O.O.语言的奇迹之一)是在实际应用之前编写应用程序的所有组件。为了测试目的(通常是命令行),每个组件可能都有一个独立的执行方式,这也允许您将它们视为每个组件的完整程序,并在将来的项目中使用它们。如果你想要的是测试现有程序的完整性......那么,我认为最好的方法是深入学习它是如何工作的,甚至更深入的:阅读源代码。甚至更深入:开发一个机器人来强制测试它:3

对不起,这就是我所拥有的.-。


1
2018-06-21 21:28



绝对......这是一个很好的做事方式。我认为你所描述的将被称为“单元测试”,而我希望工具集能够进行“验收测试”或“功能测试”或“集成测试”。这部分是为了提供一种额外的方法来验证可单元测试的代码,并允许对不可单元测试的代码进行某种测试:bash脚本(除非存在-shudder-一个bash单元测试框架) );专有的室外公用事业,其行为记录不当;或者在一个例程中混合了一大堆方面的代码。 - intuited
另外:随着你的术语流动,我想我正在寻找的是一个“机器人框架”。 - intuited
我明白你想要做的是用CLI找到程序的通用测试器?我发现它很难实现,因为一个如此糟糕的程序是不可预测的。如果你面对一个错误的软件,并且它的源既不可用,那么最好的选择似乎是:尝试搜索类似的程序。或者为什么不呢?在论坛中发布你的麻烦:]这样可以,还是我错过了什么?如果我这样做,请尝试更明确地了解您的个人案例。 - sadasant
一个机器人,那就是对程序进行蛮力,可能会永远存在,也可能是危险的,因为你不知道它是如何工作的或它确实做的。 - sadasant
测试总是比没有测试好。 - Ian Bicking


我知道这个问题已经过时了,但是既然我正在寻找答案,我想我会为其他发生的事情添加自己的答案。

完全免责声明:我提到的项目是我自己的,但它是完全免费和开源的。

我遇到了一个非常类似的问题,并最终滚动自己 。测试代码如下所示:

from CLITest import CLITest, TestSuite
from subprocess import CalledProcessError


class TestEchoPrintsToScreen(CLITest):
    '''Tests whether the string passed in is the string
    passed out'''

    def test_output_contains_input(self):
        self.assertNotIsInstance(self.output, CalledProcessError)
        self.assertIn("test", self.output)

    def test_ouput_equals_input(self):
        self.assertNotIsInstance(self.output, CalledProcessError)
        self.assertEqual("test", self.output)

suite = TestSuite()

suite.add_test(TestEchoPrintsToScreen("echo test"))

suite.run_tests()

这很好地解决了我的问题,但我知道它可以使用更多的工作来使它尽可能健壮(考虑发现测试发现)。这可能会有所帮助,我总是喜欢一个好的拉动请求。


1
2018-01-28 15:51





除了我可能不知道的任何预先包装的测试框架之外,我只想指出,对于这种自动化来说,期望是一个非常棒且未充分利用的工具,特别是如果你想支持多阶段交互,也就是说不仅仅是发送命令并检查输出,但响应更多输入的输出。如果您最终构建自己的系统,那么值得研究。

还有一个python reimplementation of expect叫做pexpect。也可能有一些直接接口到expect库。我不是一个蟒蛇人,所以我不能告诉你很多关于他们的事情。


0
2018-06-22 15:00