我正在为一个函数编写单元测试(使用Python 3.7,Pytest 3.6和tox 3.0),该函数将一系列shell命令编译为字符串列表,然后使用subprocess
模块执行它们。 shell命令执行以下操作:
cd
进入给定目录。我现在的测试是模拟子进程模块,然后断言它是用一个包含一些测试参数的所有预期命令的字符串列表调用的。
有没有办法测试命令是否符合预期?现在我的测试只是检查我提供给子进程模块的命令列表是否与我声明的命令列表相同。这并没有告诉我这些命令是否适合我想要实现的目标。相反,它仅用于测试我是否可以在两个不同的源文件中写下相同的字符串。
我可以模拟我期望shell命令具有的副作用吗?
使用pytest-mock,您可以在mocker
函数上请求spy夹具然后subprocess
:
def test_xxx(mocker):
mocker.spy(subprocess, 'call')
subprocess.call(...)
assert subprocess.call.call_count == 1
附:带有副作用的测试通常是不好的做法,因此我建议在tmpdir
(创建临时目录的pytest fixture)中运行所有shell命令。
您的问题结合了两个有趣的主题:a)测试代码生成器生成的代码和b)测试shell代码。
为了测试来自生成器的代码,您原则上要执行以下操作:i)测试生成器创建预期的代码 - 您已经完成的代码,ii)测试生成器实际粘合在一起的代码片段/片段按照预期的行为(独立地和组合地)(在你的情况下是shell代码片段,最终将形成一个有效的shell程序) - 这是关于测试下面将要解决的shell代码的部分,以及iii )测试控制发电机的输入是否正确。
它与编译器相当:i)是编译器代码,ii)是编译器组合以获得最终汇编程序的汇编代码片段,以及iii)是给编译器编译的源代码。一旦测试了i),ii)和iii),就很少需要测试汇编代码(即汇编代码级别)。特别地,源代码iii)理想地由相同编程语言中的测试框架测试。
在你的情况下,不清楚部分iii)的外观以及如何测试它。
关于shell代码/ shell代码片段的测试:Shell代码由与其他可执行文件或操作系统的交互支配。 shell代码中的交互中存在的问题类型是指向我的方向,我是以正确的顺序调用正确的可执行文件,并使用正确的格式参数值,并且是我希望它们的形式的输出要测试所有这些,你不应该应用单元测试,而应该进行集成测试。
在您的情况下,这意味着shell代码段应该在不同的目标操作系统上进行集成测试(即,不与操作系统隔离)。并且,生成器将这些片段组合在一起的各种方式也应该进行集成测试,以确定它们是否在操作系统上一起运行良好。
但是,可以有适用于单元测试的shell代码。例如,这是在shell中执行计算的代码,或字符串操作。我甚至会考虑使用某些基本工具(如basename)调用shell代码,以适合单元测试(如果你愿意,可以将这些工具解释为'标准库'的一部分)。在您的情况下,您描述生成的shell代码
从函数参数创建一个文件名。
这听起来像是“单元测试”shell代码的良好候选者的一个例子:这个文件名创建功能可以放入shell函数中,然后进行单独测试。