Files
everything-is-suitable/everything-is-suitable-api/api-test-tool/tests/unit/test_test_engine.py
T
张翔 08ea5fbe98 feat(admin): 添加用户管理相关文件
添加用户管理视图、API和状态管理文件
2026-03-28 14:37:29 +08:00

506 lines
17 KiB
Python

import pytest
from unittest.mock import MagicMock, patch
from datetime import datetime
from apitest.models.test_models import (
TestCase, TestResult, TestSuiteResult, HTTPMethod, PerformanceMetrics
)
from apitest.core.test_engine import TestEngine
from apitest.core.validation_engine import ValidationEngine
from apitest.models.exceptions import TestRunException
class TestTestEngine:
"""测试TestEngine测试引擎"""
@pytest.fixture
def mock_api_client(self):
"""模拟API客户端"""
api_client = MagicMock()
api_client.request.return_value = {
"status_code": 200,
"response_body": {"message": "success"},
"response_headers": {"Content-Type": "application/json"},
"performance": PerformanceMetrics(
timestamp=datetime.now(),
response_time=1000,
request_size=100,
response_size=200
)
}
return api_client
@pytest.fixture
def mock_auth_manager(self):
"""模拟认证管理器"""
auth_manager = MagicMock()
auth_manager.get_auth_headers.return_value = {"Authorization": "Bearer token"}
return auth_manager
@pytest.fixture
def mock_validation_engine(self):
"""模拟验证引擎"""
validation_engine = MagicMock()
validation_engine.validate_response.return_value = (True, "")
return validation_engine
@pytest.fixture
def test_engine(self, mock_api_client, mock_auth_manager, mock_validation_engine):
"""创建测试引擎实例"""
return TestEngine(
api_client=mock_api_client,
auth_manager=mock_auth_manager,
validation_engine=mock_validation_engine
)
def test_test_engine_initialization(self, test_engine):
"""测试测试引擎初始化"""
assert test_engine.api_client is not None
assert test_engine.auth_manager is not None
assert test_engine.validation_engine is not None
assert test_engine._context == {}
def test_set_context(self, test_engine):
"""测试设置上下文变量"""
test_engine.set_context("user_id", "12345")
assert test_engine.get_context("user_id") == "12345"
def test_get_context_with_default(self, test_engine):
"""测试获取上下文变量(带默认值)"""
assert test_engine.get_context("nonexistent", "default") == "default"
def test_topological_sort_no_dependencies(self, test_engine):
"""测试拓扑排序(无依赖)"""
test_cases = [
TestCase(
id="TC001",
name="测试1",
description="测试用例1",
module="test",
endpoint="/api/test1",
method=HTTPMethod.GET,
headers={}
),
TestCase(
id="TC002",
name="测试2",
description="测试用例2",
module="test",
endpoint="/api/test2",
method=HTTPMethod.GET,
headers={}
)
]
sorted_cases = test_engine._topological_sort(test_cases)
assert len(sorted_cases) == 2
def test_topological_sort_with_dependencies(self, test_engine):
"""测试拓扑排序(有依赖)"""
test_cases = [
TestCase(
id="TC001",
name="测试1",
description="测试用例1",
module="test",
endpoint="/api/test1",
method=HTTPMethod.GET,
headers={},
dependencies=[]
),
TestCase(
id="TC002",
name="测试2",
description="测试用例2",
module="test",
endpoint="/api/test2",
method=HTTPMethod.GET,
headers={},
dependencies=["TC001"]
),
TestCase(
id="TC003",
name="测试3",
description="测试用例3",
module="test",
endpoint="/api/test3",
method=HTTPMethod.GET,
headers={},
dependencies=["TC002"]
)
]
sorted_cases = test_engine._topological_sort(test_cases)
assert len(sorted_cases) == 3
assert sorted_cases[0].id == "TC001"
assert sorted_cases[1].id == "TC002"
assert sorted_cases[2].id == "TC003"
def test_topological_sort_circular_dependency(self, test_engine):
"""测试拓扑排序(循环依赖)"""
test_cases = [
TestCase(
id="TC001",
name="测试1",
description="测试用例1",
module="test",
endpoint="/api/test1",
method=HTTPMethod.GET,
headers={},
dependencies=["TC002"]
),
TestCase(
id="TC002",
name="测试2",
description="测试用例2",
module="test",
endpoint="/api/test2",
method=HTTPMethod.GET,
headers={},
dependencies=["TC001"]
)
]
with pytest.raises(TestRunException, match="存在循环依赖"):
test_engine._topological_sort(test_cases)
def test_resolve_context_variables_string(self, test_engine):
"""测试解析上下文变量(字符串)"""
test_engine.set_context("user_id", "12345")
result = test_engine._resolve_context_variables("${user_id}")
assert result == "12345"
def test_resolve_context_variables_dict(self, test_engine):
"""测试解析上下文变量(字典)"""
test_engine.set_context("user_id", "12345")
data = {"user_id": "${user_id}", "name": "test"}
result = test_engine._resolve_context_variables(data)
assert result == {"user_id": "12345", "name": "test"}
def test_resolve_context_variables_list(self, test_engine):
"""测试解析上下文变量(列表)"""
test_engine.set_context("user_id", "12345")
data = ["${user_id}", "test"]
result = test_engine._resolve_context_variables(data)
assert result == ["12345", "test"]
def test_execute_test_case_success(self, test_engine):
"""测试执行测试用例(成功)"""
test_case = TestCase(
id="TC001",
name="测试用例",
description="测试用例描述",
module="test",
endpoint="/api/test",
method=HTTPMethod.GET,
headers={},
validations=[{"type": "status_code", "value": 200}]
)
result = test_engine._execute_test_case(test_case)
assert isinstance(result, TestResult)
assert result.passed == True
assert result.status_code == 200
assert result.test_case == test_case
def test_execute_test_case_with_auth(self, test_engine):
"""测试执行测试用例(带认证)"""
test_case = TestCase(
id="TC001",
name="测试用例",
description="测试用例描述",
module="test",
endpoint="/api/test",
method=HTTPMethod.GET,
headers={},
auth_required=True
)
result = test_engine._execute_test_case(test_case)
assert result.passed == True
test_engine.auth_manager.get_auth_headers.assert_called_once()
def test_execute_test_case_failure(self, test_engine, mock_validation_engine):
"""测试执行测试用例(失败)"""
mock_validation_engine.validate_response.return_value = (False, "验证失败")
test_case = TestCase(
id="TC001",
name="测试用例",
description="测试用例描述",
module="test",
endpoint="/api/test",
method=HTTPMethod.GET,
headers={},
validations=[{"type": "status_code", "value": 200}]
)
result = test_engine._execute_test_case(test_case)
assert result.passed == False
assert result.error_message == "验证失败"
def test_execute_test_case_with_setup(self, test_engine):
"""测试执行测试用例(带前置操作)"""
test_case = TestCase(
id="TC001",
name="测试用例",
description="测试用例描述",
module="test",
endpoint="/api/test",
method=HTTPMethod.GET,
headers={},
setup={"type": "set_context", "key": "test_key", "value": "test_value"}
)
result = test_engine._execute_test_case(test_case)
assert test_engine.get_context("test_key") == "test_value"
def test_execute_test_case_with_teardown(self, test_engine):
"""测试执行测试用例(带后置操作)"""
test_engine.set_context("test_key", "test_value")
test_case = TestCase(
id="TC001",
name="测试用例",
description="测试用例描述",
module="test",
endpoint="/api/test",
method=HTTPMethod.GET,
headers={},
teardown={"type": "clear_context", "key": "test_key"}
)
result = test_engine._execute_test_case(test_case)
assert test_engine.get_context("test_key") is None
def test_execute_test_suite(self, test_engine):
"""测试执行测试套件"""
test_cases = [
TestCase(
id="TC001",
name="测试1",
description="测试用例1",
module="test",
endpoint="/api/test1",
method=HTTPMethod.GET,
headers={}
),
TestCase(
id="TC002",
name="测试2",
description="测试用例2",
module="test",
endpoint="/api/test2",
method=HTTPMethod.GET,
headers={}
)
]
result = test_engine.execute_test_suite(test_cases)
assert isinstance(result, TestSuiteResult)
assert len(result.results) == 2
assert result.passed == 2
assert result.failed == 0
def test_execute_test_suite_with_dependencies(self, test_engine):
"""测试执行测试套件(有依赖)"""
test_cases = [
TestCase(
id="TC001",
name="测试1",
description="测试用例1",
module="test",
endpoint="/api/test1",
method=HTTPMethod.GET,
headers={},
dependencies=[]
),
TestCase(
id="TC002",
name="测试2",
description="测试用例2",
module="test",
endpoint="/api/test2",
method=HTTPMethod.GET,
headers={},
dependencies=["TC001"]
)
]
result = test_engine.execute_test_suite(test_cases)
assert len(result.results) == 2
assert result.passed == 2
def test_execute_test_suite_stop_on_failure(self, test_engine, mock_validation_engine):
"""测试执行测试套件(失败时停止)"""
mock_validation_engine.validate_response.return_value = (False, "验证失败")
test_cases = [
TestCase(
id="TC001",
name="测试1",
description="测试用例1",
module="test",
endpoint="/api/test1",
method=HTTPMethod.GET,
headers={}
),
TestCase(
id="TC002",
name="测试2",
description="测试用例2",
module="test",
endpoint="/api/test2",
method=HTTPMethod.GET,
headers={}
)
]
result = test_engine.execute_test_suite(test_cases, stop_on_failure=True)
assert len(result.results) == 1
assert result.passed == 0
assert result.failed == 1
def test_execute_test_suite_skip_disabled(self, test_engine):
"""测试执行测试套件(跳过已禁用的用例)"""
test_cases = [
TestCase(
id="TC001",
name="测试1",
description="测试用例1",
module="test",
endpoint="/api/test1",
method=HTTPMethod.GET,
headers={},
enabled=False
),
TestCase(
id="TC002",
name="测试2",
description="测试用例2",
module="test",
endpoint="/api/test2",
method=HTTPMethod.GET,
headers={},
enabled=True
)
]
result = test_engine.execute_test_suite(test_cases)
assert len(result.results) == 1
assert result.skipped == 1
def test_execute_test_cases_by_filter_module(self, test_engine):
"""测试按模块过滤执行测试用例"""
test_cases = [
TestCase(
id="TC001",
name="测试1",
description="测试用例1",
module="module1",
endpoint="/api/test1",
method=HTTPMethod.GET,
headers={}
),
TestCase(
id="TC002",
name="测试2",
description="测试用例2",
module="module2",
endpoint="/api/test2",
method=HTTPMethod.GET,
headers={}
)
]
result = test_engine.execute_test_cases_by_filter(test_cases, module_filter="module1")
assert len(result.results) == 1
assert result.results[0].test_case.module == "module1"
def test_execute_test_cases_by_filter_tag(self, test_engine):
"""测试按标签过滤执行测试用例"""
test_cases = [
TestCase(
id="TC001",
name="测试1",
description="测试用例1",
module="test",
endpoint="/api/test1",
method=HTTPMethod.GET,
headers={},
tags=["smoke", "regression"]
),
TestCase(
id="TC002",
name="测试2",
description="测试用例2",
module="test",
endpoint="/api/test2",
method=HTTPMethod.GET,
headers={},
tags=["regression"]
)
]
result = test_engine.execute_test_cases_by_filter(test_cases, tag_filter=["smoke"])
assert len(result.results) == 1
assert "smoke" in result.results[0].test_case.tags
def test_execute_test_cases_by_filter_priority(self, test_engine):
"""测试按优先级过滤执行测试用例"""
test_cases = [
TestCase(
id="TC001",
name="测试1",
description="测试用例1",
module="test",
endpoint="/api/test1",
method=HTTPMethod.GET,
headers={},
priority=1
),
TestCase(
id="TC002",
name="测试2",
description="测试用例2",
module="test",
endpoint="/api/test2",
method=HTTPMethod.GET,
headers={},
priority=2
)
]
result = test_engine.execute_test_cases_by_filter(test_cases, priority_filter=1)
assert len(result.results) == 1
assert result.results[0].test_case.priority == 1
def test_extract_response_data(self, test_engine):
"""测试提取响应数据到上下文"""
test_case = TestCase(
id="TC001",
name="测试用例",
description="测试用例描述",
module="test",
endpoint="/api/test",
method=HTTPMethod.GET,
headers={},
validations=[{"type": "extract", "field": "user_id", "var_name": "extracted_id"}]
)
response_body = {"user_id": "12345", "name": "test"}
test_engine._extract_response_data(test_case, response_body)
assert test_engine.get_context("extracted_id") == "12345"