From c26c60f67955ec88292d773fb0157d37850ee54b Mon Sep 17 00:00:00 2001 From: Kirill Date: Mon, 24 Aug 2026 16:47:04 +0300 Subject: [PATCH] test(yamlreaders): Add tests for all parsers - TestBaseReader: abstract class - TestYamlReader: validate, parse, steps, requests, extracts, asserts - TestPostmanReader: validate, parse, nested items, headers, body - TestOpenAPIReader: validate, parse, step names, methods, paths, asserts - TestGetReader: auto-detection of formats --- tests/test_yamlreaders.py | 267 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 tests/test_yamlreaders.py diff --git a/tests/test_yamlreaders.py b/tests/test_yamlreaders.py new file mode 100644 index 0000000..02add0a --- /dev/null +++ b/tests/test_yamlreaders.py @@ -0,0 +1,267 @@ +import pytest +from pathlib import Path +import tempfile +import os + +from yamlreaders import YamlReader, PostmanReader, OpenAPIReader, get_reader +from yamlreaders.base import BaseReader, ParseError + + +TESTS_DIR = Path(__file__).parent +EXAMPLES_DIR = TESTS_DIR.parent / "examples" + + +class TestBaseReader: + def test_is_abstract(self): + with pytest.raises(TypeError): + BaseReader() + + +class TestYamlReader: + def test_validate_valid(self): + reader = YamlReader() + assert reader.validate(EXAMPLES_DIR / "custom.yaml") is True + + def test_validate_invalid(self): + reader = YamlReader() + with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f: + f.write("invalid: yaml\ncontent: here") + f.flush() + result = reader.validate(f.name) + os.unlink(f.name) + assert result is False + + def test_parse(self): + reader = YamlReader() + model = reader.parse(EXAMPLES_DIR / "custom.yaml") + + assert model.name == "Test Authorization" + assert model.base_url == "http://localhost:8080" + assert model.variables["email"] == "test@example.com" + assert model.variables["password"] == "Test123!" + assert len(model.steps) == 3 + + def test_parse_step_name(self): + reader = YamlReader() + model = reader.parse(EXAMPLES_DIR / "custom.yaml") + + assert model.steps[0].name == "Register User" + assert model.steps[1].name == "Login" + assert model.steps[2].name == "Get Profile" + + def test_parse_request(self): + reader = YamlReader() + model = reader.parse(EXAMPLES_DIR / "custom.yaml") + + req = model.steps[0].request + assert req.method == "POST" + assert req.path == "/api/register" + assert req.headers["Content-Type"] == "application/json" + assert req.body["email"] == "{{email}}" + + def test_parse_extract(self): + reader = YamlReader() + model = reader.parse(EXAMPLES_DIR / "custom.yaml") + + extract = model.steps[0].extract + assert len(extract) == 1 + assert extract[0].name == "user_id" + assert extract[0].json_path == "$.id" + + def test_parse_assert(self): + reader = YamlReader() + model = reader.parse(EXAMPLES_DIR / "custom.yaml") + + asserts = model.steps[0].assert_ + assert len(asserts) == 1 + assert asserts[0].type == "status" + assert asserts[0].value == 201 + + def test_parse_step_without_name_fails(self): + reader = YamlReader() + with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f: + f.write("steps:\n - request:\n method: GET\n url: /") + f.flush() + with pytest.raises(ParseError): + reader.parse(f.name) + os.unlink(f.name) + + def test_parse_step_without_request_fails(self): + reader = YamlReader() + with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f: + f.write("steps:\n - name: Test") + f.flush() + with pytest.raises(ParseError): + reader.parse(f.name) + os.unlink(f.name) + + +class TestPostmanReader: + def test_validate_valid(self): + reader = PostmanReader() + assert reader.validate(EXAMPLES_DIR / "postman.yaml") is True + + def test_parse(self): + reader = PostmanReader() + model = reader.parse(EXAMPLES_DIR / "postman.yaml") + + assert model.name == "Test Collection" + assert model.base_url == "http://localhost:8080" + assert model.variables["email"] == "test@example.com" + assert len(model.steps) == 2 + + def test_parse_step_names(self): + reader = PostmanReader() + model = reader.parse(EXAMPLES_DIR / "postman.yaml") + + assert model.steps[0].name == "Login" + assert model.steps[1].name == "Get Profile" + + def test_parse_request_method(self): + reader = PostmanReader() + model = reader.parse(EXAMPLES_DIR / "postman.yaml") + + assert model.steps[0].request.method == "POST" + assert model.steps[1].request.method == "GET" + + def test_parse_request_headers(self): + reader = PostmanReader() + model = reader.parse(EXAMPLES_DIR / "postman.yaml") + + headers = model.steps[0].request.headers + assert headers["Content-Type"] == "application/json" + + def test_parse_request_body(self): + reader = PostmanReader() + model = reader.parse(EXAMPLES_DIR / "postman.yaml") + + body = model.steps[0].request.body + assert body["email"] == "{{email}}" + assert body["password"] == "Test123!" + + def test_parse_nested_items(self): + reader = PostmanReader() + with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f: + f.write(""" +info: + name: Nested + +item: + - name: Folder + item: + - name: Nested Request + request: + method: GET + url: /nested +""") + f.flush() + model = reader.parse(f.name) + os.unlink(f.name) + + assert len(model.steps) == 1 + assert model.steps[0].name == "Nested Request" + + def test_validate_invalid(self): + reader = PostmanReader() + with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f: + f.write("info: {}\nother: data") + f.flush() + assert reader.validate(f.name) is False + os.unlink(f.name) + + +class TestOpenAPIReader: + def test_validate_valid(self): + reader = OpenAPIReader() + assert reader.validate(EXAMPLES_DIR / "openapi.yaml") is True + + def test_parse(self): + reader = OpenAPIReader() + model = reader.parse(EXAMPLES_DIR / "openapi.yaml") + + assert model.name == "Test API" + assert model.base_url == "http://localhost:8080" + assert len(model.steps) == 2 + + def test_parse_step_names(self): + reader = OpenAPIReader() + model = reader.parse(EXAMPLES_DIR / "openapi.yaml") + + names = [s.name for s in model.steps] + assert "loginUser" in names + assert "getProfile" in names + + def test_parse_request_methods(self): + reader = OpenAPIReader() + model = reader.parse(EXAMPLES_DIR / "openapi.yaml") + + methods = [s.request.method for s in model.steps] + assert "POST" in methods + assert "GET" in methods + + def test_parse_request_paths(self): + reader = OpenAPIReader() + model = reader.parse(EXAMPLES_DIR / "openapi.yaml") + + paths = [s.request.path for s in model.steps] + assert "/api/login" in paths + assert "/api/profile" in paths + + def test_parse_generates_asserts(self): + reader = OpenAPIReader() + model = reader.parse(EXAMPLES_DIR / "openapi.yaml") + + for step in model.steps: + assert len(step.assert_) > 0 + assert step.assert_[0].type == "status" + assert step.assert_[0].value == 200 + + def test_parse_with_servers(self): + reader = OpenAPIReader() + with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f: + f.write(""" +openapi: "3.0.0" +info: + title: Test + version: "1.0" +servers: + - url: https://api.example.com/v1 +paths: + /test: + get: + operationId: test + responses: + "200": + description: OK +""") + f.flush() + model = reader.parse(f.name) + os.unlink(f.name) + + assert model.base_url == "https://api.example.com/v1" + + def test_validate_invalid(self): + reader = OpenAPIReader() + with tempfile.NamedTemporaryFile(mode="w", suffix=".yaml", delete=False) as f: + f.write("swagger: '2.0'\ninfo:\n title: Test") + f.flush() + assert reader.validate(f.name) is False + os.unlink(f.name) + + +class TestGetReader: + def test_auto_detect_yaml(self): + reader = get_reader(EXAMPLES_DIR / "custom.yaml") + assert isinstance(reader, YamlReader) + + def test_auto_detect_postman(self): + reader = get_reader(EXAMPLES_DIR / "postman.yaml") + assert isinstance(reader, PostmanReader) + + def test_auto_detect_openapi(self): + reader = get_reader(EXAMPLES_DIR / "openapi.yaml") + assert isinstance(reader, OpenAPIReader) + + def test_file_not_found(self): + with pytest.raises(FileNotFoundError): + get_reader("nonexistent.yaml")