如果你自己创建了 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目录中执行测试。
在单元测试中,将模块名称而不是模块主体作为参数传递给测试工具。
如果成功的话,会是这样的。

(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 ===========================================
如果测试返回意外的值,将会发生如下失败。

(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/