Quality Assurance Strategy untuk Modul Reply
Source: Dev.to
Problem Statement: Mengapa Testing Tools Penting?
Masalah yang Dihadapi
| Masalah | Dampak | Contoh |
|---|---|---|
| Tidak tahu kapasitas sistem | Unexpected downtime di production | Berapa banyak user yang bisa handle? |
| Feature tidak match requirement | Kebingungan antara dev dan stakeholder | Bagaimana cara verifikasi requirement? |
| Security issues terlewat | Breach atau data exposure | Sudah test semua OWASP scenarios? |
| Performance degradation tidak terdeteksi | Slow API tanpa warning | P95 latency berapa? Naik tidak? |
Tanpa tools systematic, tim hanya bisa:
- Manual testing (tidak scalable)
- Menunggu user melaporkan bug (terlambat)
- Guessing tentang performance (tidak data‑driven)
Solusi Level 3: Implementasi Tools Modern
2.1 Stress Testing dengan k6: Mengukur Kapasitas Sistem
Tool: k6 (modern load testing framework)
Implementasi
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 Penetration Testing: Melindungi dari Cyber Threats
Tool: Custom penetration tests berbasis OWASP API Top 10
Implementasi
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"
Hasil Pengujian
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
Manfaat Nyata untuk Project
- Security Confidence: OWASP Top 10 sudah di‑test.
- Vulnerability Prevention: Edge case seperti race condition terdeteksi.
- Compliance Ready: Dokumentasi security testing siap untuk audit.
- Ownership Validation: Pengguna tidak dapat mengakses atau memodifikasi data orang lain.
Praktik
# Sebelum release, jalankan security tests
$ python manage.py test apps.reply.tests.test_penetration
# Jika ada test FAIL, security issue harus di‑fix terlebih dahulu
# Ini menjadi gating requirement untuk release
2.3 BDD Testing: Align Feature dengan Requirement
Tool: Behave (Gherkin syntax untuk executable requirements)
Implementasi
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
Hasil Pengujian
$ 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
...