test(models): Add comprehensive tests for all model classes
- TestAuthModel: default values, credentials - TestRequestModel: default/custom values - TestExtractModel: values, header source - TestAssertModel: status/json asserts - TestStepModel: with request, extracts, asserts - TestTestModel: default values, full model - TestContext: resolve variables, extracted values - TestExtractor: body, nested, status, header extraction - TestValidator: status success/failure, empty asserts - TestExecutor: URL resolution with variables - TestStepResult: step result creation - TestTestResult: all passed, one failed, empty steps
This commit is contained in:
1 parent
6ae350b48c
commit
e9cfdd9e94
1 file changed
+281
@@ -0,0 +1,281 @@
|
||||
import pytest
|
||||
from models import (
|
||||
AuthModel,
|
||||
RequestModel,
|
||||
ExtractModel,
|
||||
AssertModel,
|
||||
StepModel,
|
||||
TestModel,
|
||||
)
|
||||
from models.context import Context
|
||||
from models.executor import Executor, Response
|
||||
from models.extractor import Extractor
|
||||
from models.validator import Validator
|
||||
from models.runner import TestRunner, TestResult, StepResult
|
||||
|
||||
|
||||
class TestAuthModel:
|
||||
def test_default_values(self):
|
||||
auth = AuthModel()
|
||||
assert auth.type == "none"
|
||||
assert auth.credentials == {}
|
||||
|
||||
def test_with_credentials(self):
|
||||
auth = AuthModel(type="bearer", credentials={"token": "abc123"})
|
||||
assert auth.type == "bearer"
|
||||
assert auth.credentials["token"] == "abc123"
|
||||
|
||||
|
||||
class TestRequestModel:
|
||||
def test_default_values(self):
|
||||
req = RequestModel()
|
||||
assert req.method == "GET"
|
||||
assert req.path == "/"
|
||||
assert req.headers == {}
|
||||
assert req.query == {}
|
||||
assert req.body is None
|
||||
assert req.body_type == "json"
|
||||
assert req.timeout == 30
|
||||
|
||||
def test_custom_values(self):
|
||||
req = RequestModel(
|
||||
method="POST",
|
||||
path="/api/users",
|
||||
headers={"Content-Type": "application/json"},
|
||||
body={"name": "Test"},
|
||||
timeout=60,
|
||||
)
|
||||
assert req.method == "POST"
|
||||
assert req.path == "/api/users"
|
||||
assert req.headers["Content-Type"] == "application/json"
|
||||
assert req.body["name"] == "Test"
|
||||
assert req.timeout == 60
|
||||
|
||||
|
||||
class TestExtractModel:
|
||||
def test_values(self):
|
||||
ext = ExtractModel(name="token", json_path="$.token")
|
||||
assert ext.name == "token"
|
||||
assert ext.json_path == "$.token"
|
||||
assert ext.source == "body"
|
||||
|
||||
def test_header_source(self):
|
||||
ext = ExtractModel(name="auth", json_path="Authorization", source="header")
|
||||
assert ext.source == "header"
|
||||
|
||||
|
||||
class TestAssertModel:
|
||||
def test_status_assert(self):
|
||||
assertion = AssertModel(type="status", value=200)
|
||||
assert assertion.type == "status"
|
||||
assert assertion.value == 200
|
||||
|
||||
def test_json_assert(self):
|
||||
assertion = AssertModel(type="json", path="$.id", operator="exists")
|
||||
assert assertion.type == "json"
|
||||
assert assertion.path == "$.id"
|
||||
assert assertion.operator == "exists"
|
||||
|
||||
|
||||
class TestStepModel:
|
||||
def test_step_with_request(self):
|
||||
step = StepModel(
|
||||
name="Login",
|
||||
request=RequestModel(method="POST", path="/login"),
|
||||
)
|
||||
assert step.name == "Login"
|
||||
assert step.request.method == "POST"
|
||||
assert step.extract == []
|
||||
assert step.assert_ == []
|
||||
|
||||
def test_step_with_extracts_and_asserts(self):
|
||||
step = StepModel(
|
||||
name="Login",
|
||||
request=RequestModel(method="POST", path="/login"),
|
||||
extract=[ExtractModel(name="token", json_path="$.token")],
|
||||
assert_=[AssertModel(type="status", value=200)],
|
||||
)
|
||||
assert len(step.extract) == 1
|
||||
assert len(step.assert_) == 1
|
||||
|
||||
|
||||
class TestTestModel:
|
||||
def test_default_values(self):
|
||||
model = TestModel()
|
||||
assert model.name == "Unnamed Test"
|
||||
assert model.base_url == ""
|
||||
assert model.variables == {}
|
||||
assert model.auth is None
|
||||
assert model.steps == []
|
||||
|
||||
def test_full_model(self):
|
||||
model = TestModel(
|
||||
name="API Test",
|
||||
base_url="http://localhost:8080",
|
||||
variables={"email": "test@x.com"},
|
||||
auth=AuthModel(type="bearer"),
|
||||
steps=[
|
||||
StepModel(
|
||||
name="Step1",
|
||||
request=RequestModel(method="GET", path="/"),
|
||||
)
|
||||
],
|
||||
)
|
||||
assert model.name == "API Test"
|
||||
assert model.base_url == "http://localhost:8080"
|
||||
assert model.variables["email"] == "test@x.com"
|
||||
assert model.auth.type == "bearer"
|
||||
assert len(model.steps) == 1
|
||||
|
||||
|
||||
class TestContext:
|
||||
def test_resolve_simple(self):
|
||||
model = TestModel(variables={"name": "Kirill"})
|
||||
ctx = Context(model)
|
||||
assert ctx.resolve("Hello {{name}}") == "Hello Kirill"
|
||||
|
||||
def test_resolve_extracted(self):
|
||||
model = TestModel()
|
||||
ctx = Context(model)
|
||||
ctx.set_extracted("token", "abc123")
|
||||
assert ctx.resolve("Bearer {{token}}") == "Bearer abc123"
|
||||
|
||||
def test_resolve_multiple(self):
|
||||
model = TestModel(variables={"host": "localhost"})
|
||||
ctx = Context(model)
|
||||
ctx.set_extracted("port", "8080")
|
||||
assert ctx.resolve("{{host}}:{{port}}") == "localhost:8080"
|
||||
|
||||
def test_resolve_no_variable(self):
|
||||
model = TestModel()
|
||||
ctx = Context(model)
|
||||
assert ctx.resolve("No variables here") == "No variables here"
|
||||
|
||||
|
||||
class TestExtractor:
|
||||
def test_extract_from_body(self):
|
||||
model = TestModel()
|
||||
ctx = Context(model)
|
||||
extractor = Extractor(ctx)
|
||||
|
||||
response = Response(status=200, body={"token": "abc123"}, headers={})
|
||||
configs = [ExtractModel(name="token", json_path="$.token")]
|
||||
|
||||
extractor.extract(configs, response)
|
||||
|
||||
assert ctx.extracted["token"] == "abc123"
|
||||
|
||||
def test_extract_nested(self):
|
||||
model = TestModel()
|
||||
ctx = Context(model)
|
||||
extractor = Extractor(ctx)
|
||||
|
||||
response = Response(
|
||||
status=200,
|
||||
body={"user": {"id": 123, "name": "Test"}},
|
||||
headers={},
|
||||
)
|
||||
configs = [ExtractModel(name="user_id", json_path="$.user.id")]
|
||||
|
||||
extractor.extract(configs, response)
|
||||
|
||||
assert ctx.extracted["user_id"] == 123
|
||||
|
||||
def test_extract_from_status(self):
|
||||
model = TestModel()
|
||||
ctx = Context(model)
|
||||
extractor = Extractor(ctx)
|
||||
|
||||
response = Response(status=201, body={}, headers={})
|
||||
configs = [ExtractModel(name="status", json_path="status", source="status")]
|
||||
|
||||
extractor.extract(configs, response)
|
||||
|
||||
assert ctx.extracted["status"] == 201
|
||||
|
||||
def test_extract_from_header(self):
|
||||
model = TestModel()
|
||||
ctx = Context(model)
|
||||
extractor = Extractor(ctx)
|
||||
|
||||
response = Response(status=200, body={}, headers={"X-Request-Id": "req-123"})
|
||||
configs = [ExtractModel(name="req_id", json_path="X-Request-Id", source="header")]
|
||||
|
||||
extractor.extract(configs, response)
|
||||
|
||||
assert ctx.extracted["req_id"] == "req-123"
|
||||
|
||||
|
||||
class TestValidator:
|
||||
def test_validate_status_success(self):
|
||||
validator = Validator()
|
||||
response = Response(status=200, body={}, headers={})
|
||||
asserts = [AssertModel(type="status", value=200)]
|
||||
|
||||
assert validator.validate(asserts, response) is True
|
||||
|
||||
def test_validate_status_failure(self):
|
||||
validator = Validator()
|
||||
response = Response(status=404, body={}, headers={})
|
||||
asserts = [AssertModel(type="status", value=200)]
|
||||
|
||||
assert validator.validate(asserts, response) is False
|
||||
|
||||
def test_validate_empty_asserts(self):
|
||||
validator = Validator()
|
||||
response = Response(status=200, body={}, headers={})
|
||||
|
||||
assert validator.validate([], response) is True
|
||||
|
||||
|
||||
class TestExecutor:
|
||||
def test_resolve_url(self):
|
||||
model = TestModel(base_url="http://localhost:8080")
|
||||
ctx = Context(model)
|
||||
executor = Executor(ctx)
|
||||
|
||||
request = RequestModel(method="GET", path="/api/users")
|
||||
assert executor._resolve_url(request) == "http://localhost:8080/api/users"
|
||||
|
||||
def test_resolve_url_with_variables(self):
|
||||
model = TestModel(base_url="http://localhost:8080")
|
||||
ctx = Context(model)
|
||||
ctx.set_extracted("user_id", "123")
|
||||
executor = Executor(ctx)
|
||||
|
||||
request = RequestModel(method="GET", path="/api/users/{{user_id}}")
|
||||
assert executor._resolve_url(request) == "http://localhost:8080/api/users/123"
|
||||
|
||||
|
||||
class TestStepResult:
|
||||
def test_step_result(self):
|
||||
response = Response(status=200, body={}, headers={})
|
||||
result = StepResult(name="Test", passed=True, response=response)
|
||||
|
||||
assert result.name == "Test"
|
||||
assert result.passed is True
|
||||
assert result.response.status == 200
|
||||
|
||||
|
||||
class TestTestResult:
|
||||
def test_all_passed(self):
|
||||
response = Response(status=200, body={}, headers={})
|
||||
steps = [
|
||||
StepResult(name="S1", passed=True, response=response),
|
||||
StepResult(name="S2", passed=True, response=response),
|
||||
]
|
||||
result = TestResult(steps=steps)
|
||||
assert result.passed is True
|
||||
|
||||
def test_one_failed(self):
|
||||
response = Response(status=200, body={}, headers={})
|
||||
steps = [
|
||||
StepResult(name="S1", passed=True, response=response),
|
||||
StepResult(name="S2", passed=False, response=response),
|
||||
]
|
||||
result = TestResult(steps=steps)
|
||||
assert result.passed is False
|
||||
|
||||
def test_empty_steps(self):
|
||||
result = TestResult(steps=[])
|
||||
assert result.passed is True
|
||||
Reference in new issue
Block a user