如果你自己创建了 Ansible 模块,就来进行单元测试吧

上一篇文章中,我曾提到编写自己的Ansible模块后应进行正常性测试,而这一次我想尝试进行自己编写模块的单元测试。
在Ansible的测试工具中,使用了pytest作为单元测试。

1. 环境

項目バージョンOSCentOS7.5Python3.6.6Ansibledevel

2. 测试用文档 ​

    https://docs.ansible.com/ansible/latest/dev_guide/testing_units.html#testing-units

在进行单元测试时使用的源代码。

3-1. 创建的模块

我会对上次创建的output_name.py进行修改。
我会添加一个名为”sum”的函数,它可以接受参数并返回它们的总和。
为了帮助您理解,我会做一个简单的单元测试。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Copyright: (c) 2018, sky_joker
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

from __future__ import absolute_import, division, print_function
__metaclass__ = type


ANSIBLE_METADATA = {
    'metadata_version': '1.1',
    'status': ['preview'],
    'supported_by': 'community'
}


DOCUMENTATION = '''
module: output_name
short_description: module that outputs a name.
description:
    - Output the specified name.
requirements:
    - python >= 2.7
options:
    name:
        description:
            - Specify name.
        required: True
'''

EXAMPLE = '''
---
- output_name:
    name: taro
  register: r

- debug: msg="{{ r }}"
'''

from ansible.module_utils.basic import AnsibleModule


def sum(a, b):
    return a + b


def main():
    argument_spec = dict(
        name=dict(type="str", required=True)
    )

    module = AnsibleModule(argument_spec, supports_check_mode=True)

    result = dict(changed=False)

    name = module.params['name']
    if(name):
        result['name'] = name
        module.exit_json(**result)
    else:
        module.fail_json(msg="Please specify name.")


if __name__ == "__main__":
    main()

3-2. 测试模块

考试模块将使用以下内容。

from ansible.modules.salf_made.output_name import sum

def test_sum():
    assert sum(1, 2) == 3

4. 考试的准备

克隆存储库

[example@localhost ~]$ git clone https://github.com/ansible/ansible.git

创建虚拟环境venv。

为了测试目的,将安装一个模块,因此创建一个venv。

[example@localhost ~]$ cd ansible/
[example@localhost ansible]$ python36 -m venv venv

4-3. 安装必要的模块

[example@localhost ansible]$ source venv/bin/activate
(venv) [example@localhost ansible]$ yum -y install gcc python36-devel
(venv) [example@localhost ansible]$ pip3 install -r test/runner/requirements/units.txt

5. 进行考试

由于单元测试需要从测试模块调用主体模块,所以需要将其保存在指定的位置。
在这里,我们将其保存在以下位置。

項目場所output_name.py$ANSIBLE/lib/ansible/modules/salf_madetest_output_name.py$ANSIBLE/test/units/modules/salf_made

5-1. 创建目录并移动模块。

进行目录创建。

(venv) [example@localhost ansible]$ mkdir lib/ansible/modules/salf_made
(venv) [example@localhost ansible]$ mkdir test/units/modules/salf_made

创建实体模块和测试模块。

(venv) [example@localhost ansible]$ vi lib/ansible/modules/salf_made/output_name.py
(venv) [example@localhost ansible]$ vi test/units/modules/salf_made/test_output_name.py

5-2. 考试进行

在ansible目录中执行测试。
在单元测试中,将模块名称而不是模块主体作为参数传递给测试工具。

如果成功的话,会是这样的。

success_unit_test.gif
(venv) [example@localhost ansible]$ ./bin/ansible-test units --python 3.6 output_name
Unit test with Python 3.6
============================================= test session starts ==============================================
platform linux -- Python 3.6.6, pytest-3.9.2, py-1.7.0, pluggy-0.8.0
rootdir: /home/example/ansible, inifile: tox.ini
plugins: xdist-1.23.2, forked-0.2
gw0 [1] / gw1 [1]
scheduling tests via LoadScheduling
.
--------------- generated xml file: /home/example/ansible/test/results/junit/python3.6-units.xml ---------------
=========================================== 1 passed in 0.33 seconds ===========================================

如果测试返回意外的值,将会发生如下失败。

fail_unit_test.gif
(venv) [example@localhost ansible]$ ./bin/ansible-test units --python 3.6 output_name
Unit test with Python 3.6
============================================= test session starts ==============================================
platform linux -- Python 3.6.6, pytest-3.9.2, py-1.7.0, pluggy-0.8.0
rootdir: /home/example/ansible, inifile: tox.ini
plugins: xdist-1.23.2, forked-0.2
gw0 [1] / gw1 [1]
scheduling tests via LoadScheduling
F
=================================================== FAILURES ===================================================
___________________________________________________ test_sum ___________________________________________________
[gw0] linux -- Python 3.6.6 /home/example/ansible/venv/bin/python
def test_sum():
>       assert sum(1, 2) == 4
E       assert 3 == 4
E        +  where 3 = sum(1, 2)

test/units/modules/salf_made/test_output_name.py:6: AssertionError
--------------- generated xml file: /home/example/ansible/test/results/junit/python3.6-units.xml ---------------
=========================================== short test summary info ============================================
FAIL test/units/modules/salf_made/test_output_name.py::test_sum
=========================================== 1 failed in 0.34 seconds ===========================================
ERROR: Command "pytest --boxed -r a -n auto --color yes --junit-xml test/results/junit/python3.6-units.xml test/units/modules/salf_made/test_output_name.py" returned exit status 1.

6. 参考 -> 参阅

    https://docs.pytest.org/en/latest/
bannerAds