如何测试Fabric任务?

12

有人成功测试过他们的fabric任务吗?是否有任何可以帮助的库?

我对补丁/模拟非常熟悉,但是使用fabric却很困难,我也查看了fabric自己的测试套件,可惜没有帮助,fabric文档中似乎也没有相关主题。

这些是我正在尝试测试的任务...如果可能的话,我想避免启动虚拟机。

感谢您的帮助,提前致谢。


为什么布料测试套件没有用?我刚看了一下,虽然它非常复杂,但我怀疑他们可能在其中某个地方正在做你试图做的事情。 - David Sanders
看起来有点复杂、交织在一起,非常适合直接测试布料,但乍一看似乎需要复制粘贴他们的大量代码,我希望有一个像 "moto" 为 "boto" 所做的那样的库。无论如何,我会更深入地研究的。 - farridav
是的,当你不得不深入研究库代码来弄清楚如何做某事时,确实令人失望。官方文档对这个主题没有更多的说明似乎有点可惜。听起来像是一个提交请求的好机会。 - David Sanders
1个回答

6
免责声明:以下,功能测试与系统测试是同义词。对于大多数Fabric项目缺乏正式规范,这种区别变得无关紧要。此外,由于配置管理软件的边界模糊,我可能会在功能测试和集成测试之间随意使用术语。

Fabric的本地功能测试很难(或不可能)

我相信在不启动虚拟机(你提出的其中一个约束条件)的情况下进行功能测试是不可能的,或者需要进行极其广泛的模拟(这将使你的测试套件天生脆弱)。
考虑以下简单函数:
def agnostic_install_lsb():
    def install_helper(installer_command):
        ret = run('which %s' % installer_command)
        if ret.return_code == 0:
            sudo('%s install -y lsb-release' % installer_command)
            return True
        return False

    install_commands = ['apt-get', 'yum', 'zypper']
    for cmd in install_commands:
        if install_helper(cmd):
            return True

     return False

如果您有一个调用 agnostic_install_lsb 的任务,如何在本地机器上进行功能测试?
您可以通过模拟对 runlocalsudo 的调用来进行单元测试,但在集成测试方面并没有太多的选择。 如果您愿意满足于简单的单元测试,那么除了使用 mocknose 之外,就不需要太多的测试框架,因为所有的单元测试都在严格控制的条件下进行。
如何进行模拟
您可以模拟 sudolocalrun 函数将其命令记录到一组 StringIO 或文件中,但是,除非我忽略了某些聪明的东西,否则您还必须非常小心地模拟它们的返回值。 继续陈述您可能已经知道的事情,您的模拟要么必须了解 Fabric 上下文管理器(困难),要么必须模拟您使用的所有上下文管理器(仍然困难,但不像前者那么糟糕)。
如果您确实想走这条路,我认为更安全、更容易的方法是构建一个测试类,其设置实例化了所有上下文管理器、runsudo 和您正在使用的 Fabric 的任何其他部分的模拟,而不是尝试在每个测试基础上进行更少量的模拟。 此时,您将构建一个相对通用的 Fabric 测试框架,应该将其作为 "mabric" 在 PyPi 上共享。
我认为这对大多数情况没有太大用处,因为您的测试最终关心的是运行方式,而不仅仅是结束时完成的任务。 从 run('echo "cthulhu" | sudo tee /etc/hostname') 切换到 sudo('echo "cthulhu" > /etc/hostname') 不应该破坏测试,但很难看到如何通过简单的模拟来实现这一点。 这是因为我们开始模糊功能和单元测试之间的界限,而这种基本的模拟是试图将单元测试方法应用于功能测试。
在虚拟机上测试配置管理软件是一种已经被接受的做法
我敦促您重新考虑是否要避免为功能测试启动虚拟机。 这是 Chef 测试的常见做法,面临许多相同的挑战。
如果您担心自动化问题,Vagrant 很好地简化了从模板创建虚拟机的过程。 如果您是 Docker 粉丝,我甚至听说有很好的 Vagrant/Docker 集成。 唯一的缺点是,如果您是 VMWare 粉丝,Vagrant 需要 VMWare Workstation ($$$)。 或者,只需使用免费的 Virtualbox 运行 Vagrant 即可。
如果你在像AWS这样的云环境中工作,你甚至可以选择使用与生产服务器相同的基础映像来启动新的虚拟机以进行测试。 当然,一个明显的缺点是这会花费金钱。 然而,如果您已经在公共云中运行完整的软件堆栈,测试服务器总共只需要几个小时,这并不占您成本的重要部分。
简而言之,在虚拟机上进行全面功能测试有很多方法,这是其他配置管理软件的可靠技术。
如果不使用Vagrant(或类似工具),请保留一套可在本地执行的单元测试
将测试依赖于运行虚拟机的一个明显问题是它使得开发人员难以进行测试。 这对于迭代测试(例如Web UI dev)尤其如此。
如果您正在使用Vagrant + Virtualbox、Docker(或原始LXC)或类似的解决方案进行测试虚拟化,则本地测试并不需要花费太多。 这些解决方案可以在廉价笔记本电脑硬件上不到十分钟内启动新的虚拟机。 对于非常快速的迭代,您可以多次对同一虚拟机进行测试(然后用新的虚拟机进行最终测试运行)。
但是,如果您在公共云或类似环境中进行虚拟化,过多对虚拟机进行测试会很昂贵,您应该将测试分为一个广泛的单元测试套件和需要虚拟机的集成或系统测试。 这个单独的测试集允许在开发过程中不使用完整的测试套件,而是针对单元测试进行开发。 然后,在合并/出货/签署更改之前,他们应该在虚拟机上运行功能测试。
最终,任何没有通过功能测试的内容都不应该进入您的代码库,但是您应该尽可能地实现对这样一套单元测试的全面覆盖率。 您可以做的越多以增强单元测试给您的信心,就越好,因为它减少了系统测试的虚假(潜在昂贵)运行次数。

非常感谢您提供如此全面的答案,其中包含一些非常有价值的观点。我之前不想使用虚拟机,因为我不知道是否可以在travis CI(LXC内部的LXC)中使用vagrant。我对vagrant和chef非常熟悉,但现在我是Ansible的忠实拥护者:) 但我认为您是正确的,我将启动一个vagrant box,并对其运行一些测试,这是最接近实际使用情况的测试,也是最准确/有价值的测试。 - farridav
如果 LXC-in-LXC 这个问题太麻烦的话,您可以考虑是否可以在简单的 chroot 环境中运行测试,并在其中运行 SSH 服务器。这个问题之前在 ServerFault 上被提出过:http://serverfault.com/questions/366575 @farridav - sirosen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接