本文转自测试人社区,原文链接:https://ceshiren.com/t/topic/30218

httprunner 是支持用例以Yaml形式维护,但是在运行的时候其实是要先将其转换成py文件。

hmake xxxx

或者是

hrun xxxx

其中hrun等价于hmake xxx && httprunner run xxx
这部分逻辑可以参考
httprunner/cli.py

def main():
    """API test: parse command line options and run commands."""
    if sys.argv[1] == "run":
        sys.exit(main_run(extra_args))
    elif sys.argv[1] == "make":
        main_make(args.testcase_path)

用例转换的相关代码在httprunner/make.py

加载指定路径下的测试文件:

可以参考httprunner/loader.pyload_folder_files

归一化测试脚本内容

httprunner/make.py__make方法中

# 这里其实就是解析json或者yaml文件
test_content = load_test_file(test_file)
# 统一用例格式
test_content = ensure_testcase_v4_api(test_content)

将脚本内容渲染成xxx_test.py文件,这里主要用的是Jinja2来做模板

具体怎么生成data中各个字段的,直接参考其函数就好

data = {
        "version": __version__,
        "testcase_path": testcase_path,
        "class_name": f"TestCase{testcase_cls_name}",
        "imports_list": imports_list,
        "config_chain_style": make_config_chain_style(config),
        "skip": make_config_skip(config),
        "marks": config.get("marks", []),
        "parameters": config.get("parameters"),
        "reference_testcase": any(step.get("testcase") for step in teststeps),
        "teststeps_chain_style": [
            make_teststep_chain_style(step) for step in teststeps
        ],
    }
    content = __TEMPLATE__.render(data)

httprunner执行用例底层用的是pytest,所以后续有功能需要扩展,部分修改点就可以在jinja模板上进行修改。

__TEMPLATE__ = jinja2.Template(
    """# NOTE: Generated By HttpRunner {{ version }}
# FROM: {{ testcase_path }}

{%- if parameters or skip %}
import pytest
{% endif %}
from httprunner import HttpRunner, Config, Step, RunRequest

{%- if parameters %}
from httprunner import Parameters
{%- endif %}

{%- if reference_testcase %}
from httprunner import RunTestCase
{%- endif %}

{%- for import_str in imports_list %}
{{ import_str }}
{%- endfor %}

class {{ class_name }}(HttpRunner):

    {% if parameters and skip and marks%}
    @pytest.mark.parametrize("param", Parameters({{ parameters }}))
    @pytest.mark.skip(reason="{{ skip }}")
    {% for mark in marks %}
    @pytest.mark.{{ mark }}
    {% endfor %}
    def test_start(self, param):
        super().test_start(param)

    {% elif parameters and marks %}
    @pytest.mark.parametrize("param", Parameters({{parameters}}))
    {% for mark in marks %}
    @pytest.mark.{{ mark }}
    {% endfor %}
    def test_start(self, param):
        super().test_start(param)

    {% elif parameters %}
    @pytest.mark.parametrize("param", Parameters({{ parameters }}))
    def test_start(self, param):
        super().test_start(param)

    {% elif skip %}
    @pytest.mark.skip(reason="{{ skip }}")
    def test_start(self):
        super().test_start()
    {% endif %}

    config = {{ config_chain_style }}

    teststeps = [
        {% for step_chain_style in teststeps_chain_style %}
            {{ step_chain_style }},
        {% endfor %}
    ]

if __name__ == "__main__":
    {{ class_name }}().test_start()

"""
)

比如原本httprunner不支持mark标记用例,我就直接修改了模板,增加了一个marks的参数来实先标记用例功能,那么我就可以可以通过命令行参数来筛选执行用例

hrun -m "qa and sometag" xxx