"""CLI接口单元测试""" import pytest from click.testing import CliRunner from pathlib import Path import json import tempfile from apitest.cli_module import cli @pytest.fixture def runner(): """创建CLI测试运行器""" return CliRunner() @pytest.fixture def sample_test_cases(tmp_path): """创建示例测试用例文件""" test_data = [ { "id": "TC001", "name": "测试用例1", "description": "测试用例1", "module": "test", "endpoint": "/api/test1", "method": "GET", "headers": {}, "enabled": True }, { "id": "TC002", "name": "测试用例2", "description": "测试用例2", "module": "user", "endpoint": "/api/user", "method": "POST", "headers": {}, "enabled": True, "tags": ["smoke", "regression"], "priority": 1 } ] test_file = tmp_path / "test_cases.json" with open(test_file, "w", encoding="utf-8") as f: json.dump(test_data, f) return test_file def test_cli_version(runner): """测试CLI版本命令""" result = runner.invoke(cli, ["--version"]) assert result.exit_code == 0 assert "1.0.0" in result.output def test_cli_help(runner): """测试CLI帮助命令""" result = runner.invoke(cli, ["--help"]) assert result.exit_code == 0 assert "黑盒API测试工具" in result.output def test_list_command(runner, sample_test_cases): """测试列出测试用例命令""" result = runner.invoke(cli, ["list", str(sample_test_cases)]) assert result.exit_code == 0 assert "测试用例总数: 2" in result.output assert "TC001" in result.output assert "TC002" in result.output def test_list_command_with_module_filter(runner, sample_test_cases): """测试列出测试用例命令(模块过滤)""" result = runner.invoke(cli, ["list", str(sample_test_cases), "--module", "test"]) assert result.exit_code == 0 assert "TC001" in result.output assert "TC002" not in result.output def test_list_command_with_tag_filter(runner, sample_test_cases): """测试列出测试用例命令(标签过滤)""" result = runner.invoke(cli, ["list", str(sample_test_cases), "--tag", "smoke"]) assert result.exit_code == 0 assert "TC001" not in result.output assert "TC002" in result.output def test_list_command_with_priority_filter(runner, sample_test_cases): """测试列出测试用例命令(优先级过滤)""" result = runner.invoke(cli, ["list", str(sample_test_cases), "--priority", "1"]) assert result.exit_code == 0 assert "TC001" not in result.output assert "TC002" in result.output def test_validate_command(runner, sample_test_cases): """测试验证测试用例命令""" result = runner.invoke(cli, ["validate", str(sample_test_cases)]) assert result.exit_code == 0 assert "验证通过" in result.output def test_validate_command_invalid_file(runner, tmp_path): """测试验证测试用例命令(无效文件)""" invalid_file = tmp_path / "invalid.json" with open(invalid_file, "w", encoding="utf-8") as f: f.write("{ invalid json }") result = runner.invoke(cli, ["validate", str(invalid_file)]) assert result.exit_code != 0 def test_config_command(runner): """测试配置命令""" result = runner.invoke(cli, ["config"]) assert result.exit_code == 0 assert "当前配置" in result.output def test_config_command_with_key(runner): """测试配置命令(指定键)""" result = runner.invoke(cli, ["config", "--key", "target.base_url"]) assert result.exit_code == 0 def test_run_command_no_test_cases(runner): """测试运行命令(无测试用例)""" result = runner.invoke(cli, ["run"]) assert result.exit_code != 0 assert "请指定测试用例文件路径" in result.output or "错误:" in result.output def test_run_command_help(runner): """测试运行命令帮助""" result = runner.invoke(cli, ["run", "--help"]) assert result.exit_code == 0 assert "运行测试用例" in result.output def test_list_command_help(runner): """测试列出命令帮助""" result = runner.invoke(cli, ["list", "--help"]) assert result.exit_code == 0 assert "列出测试用例" in result.output def test_validate_command_help(runner): """测试验证命令帮助""" result = runner.invoke(cli, ["validate", "--help"]) assert result.exit_code == 0 assert "验证测试用例文件" in result.output def test_config_command_help(runner): """测试配置命令帮助""" result = runner.invoke(cli, ["config", "--help"]) assert result.exit_code == 0 assert "查看配置" in result.output def test_run_command_with_verbose(runner, sample_test_cases): """测试运行命令(详细模式)""" result = runner.invoke(cli, ["run", "--test-cases", str(sample_test_cases), "--verbose"]) assert result.exit_code in [0, 1] def test_run_command_with_stop_on_failure(runner, sample_test_cases): """测试运行命令(失败时停止)""" result = runner.invoke(cli, ["run", "--test-cases", str(sample_test_cases), "--stop-on-failure"]) assert result.exit_code in [0, 1] def test_run_command_with_no_report(runner, sample_test_cases): """测试运行命令(不生成报告)""" result = runner.invoke(cli, ["run", "--test-cases", str(sample_test_cases), "--no-report"]) assert result.exit_code in [0, 1] def test_run_command_with_report_format_json(runner, sample_test_cases): """测试运行命令(JSON报告格式)""" result = runner.invoke(cli, ["run", "--test-cases", str(sample_test_cases), "--report-format", "json"]) assert result.exit_code in [0, 1] def test_run_command_with_report_path(runner, sample_test_cases, tmp_path): """测试运行命令(指定报告路径)""" report_path = tmp_path / "report.html" result = runner.invoke(cli, ["run", "--test-cases", str(sample_test_cases), "--report-path", str(report_path)]) assert result.exit_code in [0, 1] def test_run_command_with_module_filter(runner, sample_test_cases): """测试运行命令(模块过滤)""" result = runner.invoke(cli, ["run", "--test-cases", str(sample_test_cases), "--module", "test"]) assert result.exit_code in [0, 1] def test_run_command_with_tag_filter(runner, sample_test_cases): """测试运行命令(标签过滤)""" result = runner.invoke(cli, ["run", "--test-cases", str(sample_test_cases), "--tag", "smoke"]) assert result.exit_code in [0, 1] def test_run_command_with_priority_filter(runner, sample_test_cases): """测试运行命令(优先级过滤)""" result = runner.invoke(cli, ["run", "--test-cases", str(sample_test_cases), "--priority", "1"]) assert result.exit_code in [0, 1] def test_run_command_with_no_matching_cases(runner, sample_test_cases): """测试运行命令(无匹配测试用例)""" result = runner.invoke(cli, ["run", "--test-cases", str(sample_test_cases), "--module", "nonexistent"]) assert result.exit_code == 0 assert "没有匹配的测试用例" in result.output or "警告" in result.output def test_run_command_with_test_data(runner, sample_test_cases, tmp_path): """测试运行命令(带测试数据)""" test_data = [ {"username": "test1", "password": "pass1"}, {"username": "test2", "password": "pass2"} ] test_data_file = tmp_path / "test_data.csv" with open(test_data_file, "w", encoding="utf-8") as f: f.write("username,password\n") f.write("test1,pass1\n") f.write("test2,pass2\n") result = runner.invoke(cli, ["run", "--test-cases", str(sample_test_cases), "--test-data", str(test_data_file)]) assert result.exit_code in [0, 1] def test_run_command_with_exception(runner, tmp_path): """测试运行命令(异常处理)""" invalid_file = tmp_path / "invalid.json" with open(invalid_file, "w", encoding="utf-8") as f: f.write("{ invalid json }") result = runner.invoke(cli, ["run", "--test-cases", str(invalid_file)]) assert result.exit_code == 1 assert "执行测试时出错" in result.output or "错误:" in result.output def test_run_command_with_verbose_exception(runner, tmp_path): """测试运行命令(详细模式异常)""" invalid_file = tmp_path / "invalid.json" with open(invalid_file, "w", encoding="utf-8") as f: f.write("{ invalid json }") result = runner.invoke(cli, ["run", "--test-cases", str(invalid_file), "--verbose"]) assert result.exit_code == 1 def test_list_command_with_exception(runner, tmp_path): """测试列出命令(异常处理)""" invalid_file = tmp_path / "invalid.json" with open(invalid_file, "w", encoding="utf-8") as f: f.write("{ invalid json }") result = runner.invoke(cli, ["list", str(invalid_file)]) assert result.exit_code == 1 assert "列出测试用例时出错" in result.output or "错误:" in result.output def test_validate_command_with_missing_fields(runner, tmp_path): """测试验证命令(缺少字段)""" invalid_test_data = [ { "id": "", "name": "测试用例", "endpoint": "/api/test", "method": "GET" } ] invalid_file = tmp_path / "invalid.json" with open(invalid_file, "w", encoding="utf-8") as f: json.dump(invalid_test_data, f) result = runner.invoke(cli, ["validate", str(invalid_file)]) assert result.exit_code == 1 assert "验证失败" in result.output def test_validate_command_with_missing_id(runner, tmp_path): """测试验证命令(缺少ID)""" invalid_test_data = [ { "name": "测试用例", "endpoint": "/api/test", "method": "GET" } ] invalid_file = tmp_path / "invalid.json" with open(invalid_file, "w", encoding="utf-8") as f: json.dump(invalid_test_data, f) result = runner.invoke(cli, ["validate", str(invalid_file)]) assert result.exit_code == 1 def test_validate_command_with_missing_name(runner, tmp_path): """测试验证命令(缺少名称)""" invalid_test_data = [ { "id": "TC001", "endpoint": "/api/test", "method": "GET" } ] invalid_file = tmp_path / "invalid.json" with open(invalid_file, "w", encoding="utf-8") as f: json.dump(invalid_test_data, f) result = runner.invoke(cli, ["validate", str(invalid_file)]) assert result.exit_code == 1 def test_validate_command_with_missing_endpoint(runner, tmp_path): """测试验证命令(缺少端点)""" invalid_test_data = [ { "id": "TC001", "name": "测试用例", "method": "GET" } ] invalid_file = tmp_path / "invalid.json" with open(invalid_file, "w", encoding="utf-8") as f: json.dump(invalid_test_data, f) result = runner.invoke(cli, ["validate", str(invalid_file)]) assert result.exit_code == 1 def test_validate_command_with_exception(runner, tmp_path): """测试验证命令(异常处理)""" invalid_file = tmp_path / "invalid.json" with open(invalid_file, "w", encoding="utf-8") as f: f.write("{ invalid json }") result = runner.invoke(cli, ["validate", str(invalid_file)]) assert result.exit_code == 1 assert "验证测试用例时出错" in result.output or "错误:" in result.output def test_config_command_with_exception(runner): """测试配置命令(异常处理)""" result = runner.invoke(cli, ["config", "--key", "nonexistent.key"]) assert result.exit_code in [0, 1] def test_list_command_with_tags_and_dependencies(runner, tmp_path): """测试列出命令(显示标签和依赖)""" test_data = [ { "id": "TC001", "name": "测试用例1", "description": "测试用例1", "module": "test", "endpoint": "/api/test1", "method": "GET", "headers": {}, "enabled": True, "tags": ["smoke", "regression"], "dependencies": ["TC000"] } ] test_file = tmp_path / "test_cases.json" with open(test_file, "w", encoding="utf-8") as f: json.dump(test_data, f) result = runner.invoke(cli, ["list", str(test_file)]) assert result.exit_code == 0 assert "标签" in result.output assert "依赖" in result.output