| name | qa-expert |
| version | 1.0.0 |
| description | Expert-level quality assurance, testing strategies, automation, and QA processes |
| category | qa |
| tags | ["qa","testing","test-automation","quality-assurance","selenium"] |
| allowed-tools | ["Read","Write","Edit","Bash(*)"] |
Quality Assurance Expert
Expert guidance for quality assurance, testing strategies, test automation, and QA best practices.
Core Concepts
Testing Types
- Unit testing
- Integration testing
- System testing
- Acceptance testing
- Regression testing
- Performance testing
- Security testing
Test Automation
- Selenium WebDriver
- Cypress, Playwright
- API testing (Postman, REST Assured)
- Mobile testing (Appium)
- CI/CD integration
- Test frameworks (JUnit, pytest, Jest)
QA Processes
- Test planning
- Test case design
- Defect management
- Test metrics and reporting
- Risk-based testing
- Exploratory testing
Test Automation Framework
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from typing import Dict, List
class BasePage:
"""Base page object"""
def __init__(self, driver):
self.driver = driver
self.wait = WebDriverWait(driver, 10)
def find_element(self, locator):
return self.wait.until(EC.presence_of_element_located(locator))
def click(self, locator):
element = self.find_element(locator)
element.click()
def type_text(self, locator, text):
element = self.find_element(locator)
element.clear()
element.send_keys(text)
def get_text(self, locator):
element = self.find_element(locator)
return element.text
class LoginPage(BasePage):
"""Login page object"""
USERNAME_INPUT = (By.ID, )
PASSWORD_INPUT = (By.ID, )
LOGIN_BUTTON = (By.ID, )
ERROR_MESSAGE = (By.CLASS_NAME, )
():
.type_text(.USERNAME_INPUT, username)
.type_text(.PASSWORD_INPUT, password)
.click(.LOGIN_BUTTON)
():
.get_text(.ERROR_MESSAGE)
:
():
.browser = browser
.driver =
.results = []
():
.browser == :
options = webdriver.ChromeOptions()
options.add_argument()
.driver = webdriver.Chrome(options=options)
.browser == :
.driver = webdriver.Firefox()
.driver.implicitly_wait()
():
.driver:
.driver.quit()
():
:
test_func()
.results.append({: test_name, : })
Exception e:
.results.append({
: test_name,
: ,
: (e)
})
() -> :
total = (.results)
passed = ( r .results r[] == )
failed = total - passed
{
: total,
: passed,
: failed,
: (passed / total * ) total > ,
: .results
}
():
options = webdriver.ChromeOptions()
options.add_argument()
driver = webdriver.Chrome(options=options)
driver
driver.quit()
():
driver.get()
LoginPage(driver)
():
login_page.login(, )
login_page.driver.title
():
login_page.login(, )
error = login_page.get_error_message()
error
API Testing
import requests
from typing import Dict, Any
class APITestClient:
"""API testing client"""
def __init__(self, base_url: str):
self.base_url = base_url
self.session = requests.Session()
self.test_results = []
def test_get_endpoint(self, endpoint: str, expected_status: int = 200,
expected_keys: List[str] = None) -> Dict:
"""Test GET endpoint"""
url = f"{self.base_url}{endpoint}"
response = self.session.get(url)
result = {
"endpoint": endpoint,
"method": "GET",
"status_code": response.status_code,
"passed": response.status_code == expected_status
}
if expected_keys and response.status_code == 200:
data = response.json()
missing_keys = [k for k in expected_keys if k not in data]
result["missing_keys"] = missing_keys
result["passed"] = result["passed"] (missing_keys) ==
.test_results.append(result)
result
() -> :
url =
response = .session.post(url, json=payload)
result = {
: endpoint,
: ,
: response.status_code,
: response.status_code == expected_status,
: response.elapsed.total_seconds() *
}
.test_results.append(result)
result
() -> :
response = .session.post(
,
json=credentials
)
response.status_code == :
token = response.json().get()
token:
.session.headers.update({: })
():
url =
rate_limited =
i (requests_count):
response = .session.get(url)
response.status_code == :
rate_limited =
{
: rate_limited,
: i rate_limited requests_count
}
Test Data Management
import random
from faker import Faker
from typing import Dict, List
class TestDataGenerator:
"""Generate test data"""
def __init__(self):
self.faker = Faker()
def generate_user(self) -> Dict:
"""Generate user test data"""
return {
"username": self.faker.user_name(),
"email": self.faker.email(),
"first_name": self.faker.first_name(),
"last_name": self.faker.last_name(),
"phone": self.faker.phone_number(),
"address": {
"street": self.faker.street_address(),
"city": self.faker.city(),
"state": self.faker.state(),
"zip": self.faker.zipcode()
}
}
def generate_users(self, count: int) -> List[Dict]:
"""Generate multiple users"""
[.generate_user() _ (count)]
() -> :
{
: .faker.uuid4(),
: user_id,
: [
{
: .faker.uuid4(),
: random.randint(, ),
: (random.uniform(, ), )
}
_ (random.randint(, ))
],
: ,
: random.choice([, , , ])
}
() -> :
invalid_patterns = {
: [, , ],
: [, , ],
: [, , ],
: [, , ]
}
random.choice(invalid_patterns.get(field, []))
Defect Tracking
from dataclasses import dataclass
from datetime import datetime
from enum import Enum
class Severity(Enum):
CRITICAL = "critical"
HIGH = "high"
MEDIUM = "medium"
LOW = "low"
class Priority(Enum):
P0 = "p0"
P1 = "p1"
P2 = "p2"
P3 = "p3"
@dataclass
class Defect:
defect_id: str
title: str
description: str
severity: Severity
priority: Priority
status: str
reported_by: str
assigned_to: str
created_at: datetime
environment: str
steps_to_reproduce: List[str]
expected_result: str
actual_result: str
class DefectTracker:
"""Track and manage defects"""
def __init__(self):
self.defects: Dict[str, Defect] = {}
def create_defect(self, defect: Defect) -> str:
"""Create new defect"""
.defects[defect.defect_id] = defect
defect.defect_id
():
defect_id .defects:
.defects[defect_id].status = new_status
() -> [Defect]:
[d d .defects.values()
d.severity == Severity.CRITICAL d.status != ]
() -> :
total = (.defects)
by_severity = {}
by_status = {}
defect .defects.values():
severity = defect.severity.value
status = defect.status
by_severity[severity] = by_severity.get(severity, ) +
by_status[status] = by_status.get(status, ) +
{
: total,
: by_severity,
: by_status,
: (.get_critical_defects())
}
Best Practices
Test Strategy
- Define clear test objectives
- Use risk-based testing
- Maintain test coverage metrics
- Automate regression tests
- Perform exploratory testing
- Test early and often
- Review and update test cases
Automation
- Follow Page Object Model
- Make tests independent
- Use explicit waits
- Implement proper error handling
- Maintain test data separately
- Use CI/CD integration
- Monitor test stability
Defect Management
- Write clear bug reports
- Include reproduction steps
- Attach screenshots/logs
- Prioritize appropriately
- Track to closure
- Analyze root causes
- Share lessons learned
Anti-Patterns
❌ Testing only happy paths
❌ No test automation strategy
❌ Vague bug reports
❌ Testing without requirements
❌ Ignoring flaky tests
❌ No regression testing
❌ Testing in production only
Resources