Reply 모듈을 위한 품질 보증 전략

발행: (2025년 12월 13일 오후 06:38 GMT+9)
5 min read
원문: Dev.to

Source: Dev.to

Problem Statement: 왜 테스트 도구가 중요한가?

직면한 문제

문제영향예시
시스템 용량을 모름프로덕션에서 예상치 못한 다운타임 발생얼마나 많은 사용자를 처리할 수 있나요?
기능이 요구사항과 불일치개발자와 이해관계자 간 혼란요구사항을 어떻게 검증하나요?
보안 이슈 누락침해 또는 데이터 노출모든 OWASP 시나리오를 테스트했나요?
성능 저하 미탐지경고 없이 느린 APIP95 레이턴시는 얼마인가? 상승했나요?

체계적인 도구 없이 팀은 다음과 같이 할 수밖에 없습니다:

  • 수동 테스트 (확장성 부족)
  • 사용자가 버그를 보고할 때까지 기다림 (지연)
  • 성능을 추측 (데이터 기반이 아님)

솔루션 레벨 3: 현대 도구 구현

2.1 k6를 이용한 스트레스 테스트: 시스템 용량 측정

도구: k6 (현대적인 부하 테스트 프레임워크)

구현

File: apps/reply/tests/performance/k6_reply_stress_test.js

export const options = {
  stages: [
    { duration: '1m', target: 60 },   // Ramp up
    { duration: '1m', target: 80 },   // Peak load
    { duration: '1m', target: 100 },  // Stress test
  ],
  thresholds: {
    'http_req_duration': ['p(95) 2000 ms, test FAIL → Force improvement

2.2 침투 테스트: 사이버 위협으로부터 보호

도구: OWASP API Top 10 기반 커스텀 침투 테스트

구현

File: apps/reply/tests/test_penetration.py

def test_api1_broken_object_level_authorization(self):
    """Attacker mencoba ubah reply orang lain"""
    attacker_user = User.objects.create_user("attacker")
    victim_reply = Reply.objects.create(..., author="victim")

    client = APIClient()
    client.force_authenticate(user=attacker_user)

    response = client.patch(
        f'/forums/{forum_id}/replies/{victim_reply.id}/',
        {"content": "Hacked content"},
    )

    # ✅ MUST be 403 Forbidden
    assert response.status_code == 403

    # ✅ Content tidak berubah
    victim_reply.refresh_from_db()
    assert victim_reply.content == "Original content"

테스트 결과

Ran 40+ penetration tests:
✅ API1 (BOLA) - PASSED
✅ API2 (Authentication) - PASSED
✅ API3 (Data Exposure) - PASSED
✅ API5 (Access Control) - PASSED
✅ API6 (Mass Assignment) - PASSED
✅ API7 (Injection) - PASSED
✅ API8 (Asset Management) - PASSED
✅ API9 (Logging) - PASSED
✅ Rate Limiting - PASSED
✅ Concurrent Modification - PASSED

프로젝트에 실질적인 이점

  • 보안 신뢰도: OWASP Top 10이 테스트됨.
  • 취약점 예방: 레이스 컨디션 같은 엣지 케이스 탐지.
  • 컴플라이언스 준비: 보안 테스트 문서가 감사에 바로 사용 가능.
  • 소유권 검증: 사용자가 다른 사람의 데이터를 접근·수정할 수 없음.

실행 방법

# 릴리즈 전, 보안 테스트 실행
$ python manage.py test apps.reply.tests.test_penetration

# 테스트 FAIL 시, 보안 이슈를 먼저 수정
# 이는 릴리즈에 대한 게이팅 요구사항이 됨

2.3 BDD 테스트: 기능을 요구사항과 정렬

도구: Behave (실행 가능한 요구사항을 위한 Gherkin 문법)

구현

Feature file: apps/reply/tests/bdd/features/reply.feature

Feature: Reply Management - Business Requirements & Acceptance Criteria

  Scenario: User can create a new reply
    When alice creates a reply with content "Hello forum!"
    Then the reply should be created successfully with status 201
    And the reply status should be "pending" by default
    And alice should be the author of the reply

  Scenario: User cannot modify other user's reply
    Given a reply exists by bob with content "Bob's reply"
    When alice attempts to update bob's reply to "Hacked content"
    Then the modification should be rejected with status 403 Forbidden
    And bob's reply content should remain "Bob's reply"

  Scenario: Rate limiting prevents abuse
    When alice creates 100 replies in quick succession
    Then the reply creation should be rate limited
    And alice should receive 429 Too Many Requests after threshold

Step implementation: apps/reply/tests/bdd/steps/reply_steps.py

@when(u'{username} creates a reply with content "{content}"')
def step_create_reply(context, username, content):
    """Execute: Create reply via API"""
    context.response = context.client.post(
        f'/api/forums/{context.forum.id}/replies/',
        {'content': content, 'status': 'active'},
        format='json'
    )

@then(u'the reply should be created successfully with status 201')
def step_reply_created_success(context):
    """Verify: Response status and data"""
    assert context.response.status_code == 201
    assert 'id' in context.response.data

테스트 결과

$ behave apps/reply/tests/bdd/

Running 20+ scenarios:
 User can create a new reply
 User can view all replies in a forum
 User can update their own reply
 User can delete their own reply
 User cannot modify other user's reply (403 check)
✅ Rate limiting prevents abuse
...
Back to Blog

관련 글

더 보기 »

리팩토링 없이 레거시 Laravel 코드 테스트

실제 PHP 프로젝트를 위한 실용적인 전략 레거시 코드베이스는 삶의 일부입니다. 대부분 우리는 그린필드 프로젝트에 참여하지 않습니다. 우리는 애플리케이션을 물려받습니다.