뜨문뜨문 생각날 때마다 만들고 있던 도구가 있었다.
오랜만에 개발 IDE를 열고 코드 작업을 하려고 보다가 ChatGPT가 같은 목적으로 어느정도 수준까지 해줄까 싶어서
확인해 봤다.
결론은... 음... ChatGPT가 나보다 나은 것 같다.
이제 이런 류의 접근은... 그냥 AI 연동해서 AI한테 부탁하는 코드 정도나 작성하면 될 것 같다...
하려던 바.
1) Input API Spec
<- xxx_swagger.json
2) Analyze Spec
-> ApiInfo
3) Extract TestCases
->ApiTCInfo
4) Write TestCode
-> [Test Code] pytest+requests
-> [Test Script] PostMan Collection
ChatGPT한테 테스트용 샘플 Swagger json 파일을 업로드한 후 비슷한 방식으로 테스트 케이스를 생성해 달라고 해봤다.
https://chatgpt.com/share/67fdb565-a4c4-8001-a1c5-355646f132bd
첨부한 petstore에 대한 HTTP API 스펙을 기반으로 (PUT) /pet API에 대한 테스트 케이스를 작성해 줘
다음은 OpenAPI 스펙에 정의된 (PUT) /pet API를 기준으로 작성한 테스트 케이스입니다. 이 API는 기존의 Pet 정보를 갱신하는 데 사용됩니다.
✅ 기본 정보
- Endpoint: PUT /pet
- 요약: 기존 Pet 정보 갱신
- 요청 형식: application/json 또는 application/xml, application/x-www-form-urlencoded
- 요청 본문 필수: ✅
- 보안 요구사항: petstore_auth (write:pets, read:pets)
테스트 케이스
1. 정상 케이스
TC001. 유효한 Pet 객체로 기존 Pet 정보 갱신
- 입력:
-
json{ "id": 10, "name": "Rex", "category": { "id": 1, "name": "Dogs" }, "photoUrls": ["https://example.com/rex.jpg"], "tags": [{ "id": 1, "name": "friendly" }], "status": "available" }
- 예상 결과: HTTP 200 OK, 업데이트된 Pet 객체 반환
2. 예외/에러 케이스
TC002. ID가 누락된 Pet 객체 전송
- 입력:
-
json{ "name": "NoID", "photoUrls": ["url"] }
- 예상 결과: HTTP 400 Bad Request (Invalid ID supplied)
TC003. 존재하지 않는 ID로 업데이트 시도
- 입력: id가 존재하지 않는 Pet 객체
- 예상 결과: HTTP 404 Not Found (Pet not found)
TC004. 필수 필드(name, photoUrls)가 누락된 객체
- 입력:
-
json{ "id": 10 }
- 예상 결과: HTTP 405 Validation Exception
TC005. status에 유효하지 않은 값 입력
- 입력:
-
json{ "id": 10, "name": "Rex", "photoUrls": ["https://example.com/rex.jpg"], "status": "lost" }
- 예상 결과: HTTP 405 Validation Exception (Enum validation 실패)
3. 보안 관련 케이스
TC006. 인증 토큰 없이 요청
- 입력: 유효한 Pet 객체, Authorization 헤더 없음
- 예상 결과: HTTP 401 Unauthorized 또는 403 Forbidden
4. 엣지 케이스
TC007. 매우 큰 photoUrls 배열
- 입력: photoUrls에 1000개 이상의 URL
- 예상 결과: HTTP 200 또는 413 Payload Too Large (서버 설정에 따라)
TC008. name에 특수문자/이모지 포함
- 입력:
-
json{ "id": 10, "name": "🐶Rex★", "photoUrls": ["https://example.com/rex.jpg"] }
- 예상 결과: HTTP 200 OK
위 테스트 케이스를 Postman 스크립트로 만들어 줘
pytest 기반의 테스트 코드로도 작성해 줘
test_update_pet_api.py
import pytest
import requests
BASE_URL = "https://petstore3.swagger.io/api/v3"
ACCESS_TOKEN = "YOUR_ACCESS_TOKEN" # 필요한 경우 사용
HEADERS = {
"Content-Type": "application/json",
"Authorization": f"Bearer {ACCESS_TOKEN}"
}
@pytest.mark.parametrize("payload, expected_status", [
# TC001: 정상 케이스
({
"id": 10,
"name": "Rex",
"category": {"id": 1, "name": "Dogs"},
"photoUrls": ["https://example.com/rex.jpg"],
"tags": [{"id": 1, "name": "friendly"}],
"status": "available"
}, 200),
# TC002: ID 없음
({
"name": "NoID",
"photoUrls": ["url"]
}, 400),
# TC003: 존재하지 않는 ID
({
"id": 999999,
"name": "Ghost",
"photoUrls": ["url"]
}, 404),
# TC004: 필수 필드 누락 (photoUrls)
({
"id": 10
}, 405),
# TC005: status에 유효하지 않은 값
({
"id": 10,
"name": "Rex",
"photoUrls": ["https://example.com/rex.jpg"],
"status": "lost"
}, 405),
# TC007: 큰 photoUrls 배열
({
"id": 10,
"name": "BigPhotoList",
"photoUrls": ["https://example.com/img.jpg"] * 1000
}, 200),
# TC008: 특수문자 포함 name
({
"id": 10,
"name": "🐶Rex★",
"photoUrls": ["https://example.com/rex.jpg"],
"status": "available"
}, 200)
])
def test_put_pet(payload, expected_status):
response = requests.put(f"{BASE_URL}/pet", json=payload, headers=HEADERS)
print(f"\n[TEST] Status Code: {response.status_code}, Response: {response.text}")
assert response.status_code == expected_status
# TC006: 인증 없이 요청
def test_put_pet_no_auth():
payload = {
"id": 10,
"name": "Rex",
"photoUrls": ["https://example.com/rex.jpg"],
"status": "available"
}
headers = {"Content-Type": "application/json"}
response = requests.put(f"{BASE_URL}/pet", json=payload, headers=headers)
print(f"\n[TEST] No Auth - Status: {response.status_code}, Response: {response.text}")
assert response.status_code in (401, 403, 200) # 서버 설정에 따라 다를 수 있음