给出一个swagger.json 配合skill让其生成自动化测试api

可以参考文档: https://under-ctrl.com/notes/use-swagger-json-for-copilot/

使用
#fetch https://swaggerurl
和
#file:swagger.json
提示词加载

image

 

image

 

1.仓库代码结构:

image

 2.skill内容:

(让他基于swagger.json文件读取数据,生成自动化测试用例子)-----这个效果比较好

---
name: swagger-api-test-case-generator
description: Generate API automation test cases, according to JSON Swagger file.
---
# Swagger API Test Case Generator
#OVerview
- This skill Generate API automation test case, according to JSON Swagger file.
- It takes the Swagger documentation as input and creates auto api test cases. 
- Generated one api for each swagger api.
- The generated api need to use pytest framework, each api test case including inputs parameters, and requests information and response ,need to assert response.

-API call in test case should only use parameters contained in the JSON Swagger file.
- The test case should be in the same format as the example.
- Generate test cases ,you need to refer to ocr_fin_operations.py and ocr_fin_operations.py ,  keep same style with their python files' testcase format and structure, need to follow the same coding style.
# reference

- firstly please refer to assets/swagger.json for the input JSON Swagger file.
- you can also please refer to swagger documentation URL: You swagger html address replace here
# Input 

- Swagger documentation URL: You swagger html address replace here
 # Output 

- Test case file name should match pytest convention and also refer to JSON Swagger file name. - Each test case should include: - Test case name: should be descriptive and follow pytest naming conventions. - Input parameters: should be based on the parameters defined in the JSON Swagger file. - Request information: should include the HTTP method, endpoint URL, and any necessary headers or body data. - Response assertion: should assert the expected response status code and any relevant response data based on the JSON Swagger file.

 3.提示词:

Generate API automation test cases, according to JSON Swagger file: assets/swagger.json

4.结果:

生成的测试用例代码(test_swagger_planned_maintenance_api.py):

#!/usr/bin/env python
# _*_ coding: utf-8 _*_

import os
import time
import uuid

import pytest
import requests


class TestSwaggerPlannedMaintenanceApi:
    @classmethod
    def setup_class(cls):
        """Load runtime config for live API execution."""
        cls.base_url = os.getenv("SWAGGER_BASE_URL", "http://test:8080")
        cls.mbr_no = os.getenv("SWAGGER_MBR_NO", "111")
        cls.timeout = int(os.getenv("SWAGGER_TIMEOUT", "30"))
        cls.session = requests.Session()

    @classmethod
    def teardown_class(cls):
        cls.session.close()

    def setup_method(self, method):
        self._method_name = method.__name__

    def teardown_method(self, method):
        _ = method

    def _headers(self):
        headers = {"Accept": "application/json"}
        if self.mbr_no:
            headers["mbrNo"] = self.mbr_no
        return headers

    def _auth_or_skip(self):
        # if not os.getenv("RUN_LIVE_API_TESTS"):
        #     pytest.skip("Set RUN_LIVE_API_TESTS=1 to run live API tests.")
        if not self.mbr_no:
            pytest.skip("Set SWAGGER_MBR_NO for the required mbrNo header.")

    def _build_schedule_payload(self):
        now_ms = int(time.time() * 1000)
        start_ms = now_ms + 60 * 60 * 1000
        end_ms = start_ms + 60 * 60 * 1000
        unique = str(uuid.uuid4())[:8]
        return {
            "title": f"swagger-auto-{unique}",
            "desc": "Created by pytest automation",
            "startTime": start_ms,
            "endTime": end_ms,
            "dimensions": {
                "sampleProduct": [
                    {"resourceId": f"resource-{unique}", "productKey": "sample-product-key"}
                ]
            },
        }

    @pytest.fixture
    def created_schedule_id(self):
        self._auth_or_skip()
        payload = self._build_schedule_payload()

        response = self.session.post(
            f"{self.base_url}/test/planned-maintenances",
            headers={**self._headers(), "Content-Type": "application/json"},
            json=payload,
            timeout=self.timeout,
        )

        assert response.status_code == 200, response.text
        schedule_id = response.json() if response.headers.get("Content-Type", "").startswith("application/json") else response.text
        assert schedule_id

        yield str(schedule_id)

        self.session.delete(
            f"{self.base_url}/test/planned-maintenances/{schedule_id}",
            headers=self._headers(),
            timeout=self.timeout,
        )

    def test_get_planned_maintenance_list_using_get(self):
        """GET /test/getuser"""
        self._auth_or_skip()

        params = {
            "pageNum": 1,
            "pageSize": 10,
        }

        response = self.session.get(
            f"{self.base_url}/test/planned-maintenances",
            headers=self._headers(),
            params=params,
            timeout=self.timeout,
        )

        assert response.status_code == 400, response.text
        body = response.text
        print('---------')
        print(body)
        assert isinstance(body, str)
        # assert "data" in body

    def test_create_maintenance_schedule_using_post(self):
        """POST /test/planned-maintenances"""
        self._auth_or_skip()

        payload = self._build_schedule_payload()

        response = self.session.post(
            f"{self.base_url}/cw/api/external/planned-maintenances",
            headers={**self._headers(), "Content-Type": "application/json"},
            json=payload,
            timeout=self.timeout,
        )

        assert response.status_code == 200, response.text
        created_id = response.json() if response.headers.get("Content-Type", "").startswith("application/json") else response.text
        assert created_id

        cleanup = self.session.delete(
            f"{self.base_url}/test/planned-maintenances/{created_id}",
            headers=self._headers(),
            timeout=self.timeout,
        )
        assert cleanup.status_code in (200, 400, 404), cleanup.text

    def test_get_planned_maintenance_by_id_using_get(self, created_schedule_id):
        """GET /test/planned-maintenances/{id}"""
        self._auth_or_skip()

        response = self.session.get(
            f"{self.base_url}/test/planned-maintenances/{created_schedule_id}",
            headers=self._headers(),
            timeout=self.timeout,
        )

        assert response.status_code == 200, response.text
        body = response.json()
        assert isinstance(body, dict)
        assert str(body.get("id")) == str(created_schedule_id)

    def test_update_maintenance_schedule_using_put(self, created_schedule_id):
        """PUT /test/planned-maintenances/{id}"""
        self._auth_or_skip()

        payload = self._build_schedule_payload()
        payload["title"] = f"updated-{payload['title']}"

        response = self.session.put(
            f"{self.base_url}/test/{created_schedule_id}",
            headers={**self._headers(), "Content-Type": "application/json"},
            json=payload,
            timeout=self.timeout,
        )

        assert response.status_code == 200, response.text

    def test_delete_maintenance_schedule_using_delete(self):
        """DELETE /test/planned-maintenances/{id}"""
        self._auth_or_skip()

        payload = self._build_schedule_payload()
        create_response = self.session.post(
            f"{self.base_url}/test/planned-maintenances",
            headers={**self._headers(), "Content-Type": "application/json"},
            json=payload,
            timeout=self.timeout,
        )

        assert create_response.status_code == 200, create_response.text
        created_id = (
            create_response.json()
            if create_response.headers.get("Content-Type", "").startswith("application/json")
            else create_response.text
        )
        assert created_id

        delete_response = self.session.delete(
            f"{self.base_url}/test/planned-maintenances/{created_id}",
            headers=self._headers(),
            timeout=self.timeout,
        )

        assert delete_response.status_code == 200, delete_response.text

这个结果还是比较符合需求的。

 

5.修改skill内容

(让他基于swagger html文件读取数据,生成自动化测试用例子)-----这个效果比较差

---
name: swagger-api-test-case-generator
description: Generate API automation test cases, according to JSON Swagger file.
---
# Swagger API Test Case Generator
#OVerview
- This skill Generate API automation test case, according to JSON Swagger file.
- It takes the Swagger documentation as input and creates auto api test cases. 
- Generated one api for each swagger api.
- The generated api need to use pytest framework, each api test case including inputs parameters, and requests information and response ,need to assert response.

-API call in test case should only use parameters contained in the JSON Swagger file.
- The test case should be in the same format as the example.
- Generate test cases ,you need to refer to ocr_fin_operations.py and ocr_fin_operations.py ,  keep same style with their python files' testcase format and structure, need to follow the same coding style.
# reference

-firstly refer to swagger documentation URL: You swagger html address replace here
 
-you can also please refer to assets/swagger.json for the input JSON Swagger file.

# Input
- Swagger documentation URL: You swagger html address replace here # Output - Test case file name should match pytest convention and also refer to JSON Swagger file name. - Each test case should include: - Test case name: should be descriptive and follow pytest naming conventions. - Input parameters: should be based on the parameters defined in the JSON Swagger file. - Request information: should include the HTTP method, endpoint URL, and any necessary headers or body data. - Response assertion: should assert the expected response status code and any relevant response data based on the JSON Swagger file.

这里的skill和第一个版本的区别是交换了顺序:

# reference

-firstly refer to swagger documentation URL: You swagger html address replace here
-you can also please refer to assets/swagger.json for the input JSON Swagger file.

6.提示词(不变):

Generate API automation test cases, according to JSON Swagger file: assets/swagger.json

7.结果:

生成的测试用例代码(test_swagger_planned_maintenance_api.py):

# -*- coding:utf-8 -*-
'''
Create time:2026/4/23
authoer:GitHub Copilot
file: test_swagger_planned_maintenance_api.py
'''

from __future__ import absolute_import

import os
import sys

import pytest


CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
PROJECT_ROOT = os.path.abspath(os.path.join(CURRENT_DIR, '..', '..', '..'))
SAMPLE2_ROOT = os.path.join(PROJECT_ROOT, 'swagger-codegen', 'sample2')

if SAMPLE2_ROOT not in sys.path:
sys.path.insert(0, SAMPLE2_ROOT)

import swagger_client
from swagger_client.models.maintain_schedule_dto import MaintainScheduleDto
from swagger_client.models.page_info_maintain_schedule_dto import PageInfoMaintainScheduleDto
from swagger_client.models.pm_create_update_dto import PMCreateUpdateDto


class TestSwaggerPlannedMaintenanceApi:
@classmethod
def setup_class(self):
self.api_client = swagger_client.ApiClient(swagger_client.Configuration())
self.api = swagger_client.PlannedMaintenanceManagementOpenApiApi(self.api_client)

@classmethod
def teardown_class(self):
pass

def setup_method(self, method):
print('setup method of tc: {}'.format(method.__name__))
self.recorded = {}

def fake_call_api(resource_path, method, path_params=None, query_params=None, header_params=None, body=None,
post_params=None, files=None, response_type=None, auth_settings=None, async_req=None,
_return_http_data_only=None, _preload_content=True, _request_timeout=None,
collection_formats=None):
self.recorded['resource_path'] = resource_path
self.recorded['method'] = method
self.recorded['path_params'] = path_params or {}
self.recorded['query_params'] = query_params or []
self.recorded['header_params'] = header_params or {}
self.recorded['body'] = body
self.recorded['response_type'] = response_type
self.recorded['auth_settings'] = auth_settings or []

if response_type == 'str':
return 'ok'
if response_type == 'MaintainScheduleDto':
return MaintainScheduleDto(
id='pm-123',
title='Planned maintenance',
desc='test schedule',
start_time=1713763200000,
end_time=1713766800000,
dimensions={'server': [{'instanceNo': '12345'}]}
)
if response_type == 'PageInfoMaintainScheduleDto':
return PageInfoMaintainScheduleDto(
data=[],
page_num_current=1,
page_num_total=1,
page_size=20,
total=0
)
return None

self.api.api_client.call_api = fake_call_api

def teardown_method(self, method):
print('teardown method of tc: {}'.format(method.__name__))

def build_schedule_payload(self, title='Planned maintenance'):
return PMCreateUpdateDto(
title=title,
desc='test schedule',
start_time=1713763200000,
end_time=1713766800000,
dimensions={'server': [{'instanceNo': '12345'}]}
)

def test_get_planned_maintenance_list_using_get(self):
response = self.api.get_planned_maintenance_list_using_get(
page_num=1,
page_size=20,
_from=1713763200000,
to=1713766800000,
time_type='startTime',
product_key='ncloud',
resource_id='12345'
)

query_params = dict(self.recorded['query_params'])
assert self.recorded['method'] == 'GET'
assert self.recorded['resource_path'] == '/test/planned-maintenances'
assert query_params['pageNum'] == 1
assert query_params['pageSize'] == 20
assert query_params['from'] == 1713763200000
assert query_params['to'] == 1713766800000
assert query_params['timeType'] == 'startTime'
assert query_params['productKey'] == 'ncloud'
assert query_params['resourceId'] == '12345'
assert self.recorded['response_type'] == 'PageInfoMaintainScheduleDto'
assert isinstance(response, PageInfoMaintainScheduleDto)

def test_create_maintenance_schedule_using_post(self):
schedule_dto = self.build_schedule_payload()

response = self.api.create_maintenance_schedule_using_post(schedule_dto=schedule_dto)

assert self.recorded['method'] == 'POST'
assert self.recorded['resource_path'] == '/test/planned-maintenances'
assert isinstance(self.recorded['body'], PMCreateUpdateDto)
assert self.recorded['body'].title == 'Planned maintenance'
assert self.recorded['response_type'] == 'str'
assert response == 'ok'

def test_get_planned_maintenance_by_id_using_get(self):
response = self.api.get_planned_maintenance_by_id_using_get('pm-123')

assert self.recorded['method'] == 'GET'
assert self.recorded['resource_path'] == '/test/planned-maintenances/{id}'
assert self.recorded['path_params']['id'] == 'pm-123'
assert self.recorded['response_type'] == 'MaintainScheduleDto'
assert isinstance(response, MaintainScheduleDto)

def test_update_maintenance_schedule_using_put(self):
schedule_dto = self.build_schedule_payload(title='Planned maintenance updated')

response = self.api.update_maintenance_schedule_using_put('pm-123', schedule_dto=schedule_dto)

assert self.recorded['method'] == 'PUT'
assert self.recorded['resource_path'] == '/test/planned-maintenances/{id}'
assert self.recorded['path_params']['id'] == 'pm-123'
assert isinstance(self.recorded['body'], PMCreateUpdateDto)
assert self.recorded['body'].title == 'Planned maintenance updated'
assert self.recorded['response_type'] is None
assert response is None

def test_delete_maintenance_schedule_using_delete(self):
response = self.api.delete_maintenance_schedule_using_delete('pm-123')

assert self.recorded['method'] == 'DELETE'
assert self.recorded['resource_path'] == '/test/planned-maintenances/{id}'
assert self.recorded['path_params']['id'] == 'pm-123'
assert self.recorded['response_type'] == 'str'
assert response == 'ok'

def test_required_parameter_validation(self):
with pytest.raises(ValueError):
self.api.delete_maintenance_schedule_using_delete(None)

with pytest.raises(ValueError):
self.api.get_planned_maintenance_by_id_using_get(None)

with pytest.raises(ValueError):
self.api.get_planned_maintenance_list_using_get(page_num=None, page_size=20)

with pytest.raises(ValueError):
self.api.get_planned_maintenance_list_using_get(page_num=1, page_size=None)

with pytest.raises(ValueError):
self.api.update_maintenance_schedule_using_put(None, schedule_dto=self.build_schedule_payload())


if __name__ == '__main__':
try:
import pytest
except:
raise RuntimeError('py.test is not installed, run: pip install pytest')
pytest.main(['-s', '-x', __file__])

对比,发现风格差异很大。这个版本不是太符合qa的测试模板。

总结

  • 基于json文件数据 生成的api自动化代码比基于swagger html文件生成的代码质量会好很多。
posted @ 2026-04-24 16:58  苹果芒  阅读(76)  评论(0)    收藏  举报