Claude
Skills
Sign in
Back

qa-expert

Included with Lifetime
$97 forever

Expert-level quality assurance, testing strategies, automation, and QA processes

qaqatestingtest-automationquality-assuranceselenium

What this skill does


# 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

```python
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, "username")
    PASSWORD_INPUT = (By.ID, "password")
    LOGIN_BUTTON = (By.ID, "login-button")
    ERROR_MESSAGE = (By.CLASS_NAME, "error-message")

    def login(self, username: str, password: str):
        self.type_text(self.USERNAME_INPUT, username)
        self.type_text(self.PASSWORD_INPUT, password)
        self.click(self.LOGIN_BUTTON)

    def get_error_message(self):
        return self.get_text(self.ERROR_MESSAGE)

class TestRunner:
    """Test execution framework"""

    def __init__(self, browser: str = "chrome"):
        self.browser = browser
        self.driver = None
        self.results = []

    def setup(self):
        if self.browser == "chrome":
            options = webdriver.ChromeOptions()
            options.add_argument("--headless")
            self.driver = webdriver.Chrome(options=options)
        elif self.browser == "firefox":
            self.driver = webdriver.Firefox()

        self.driver.implicitly_wait(10)

    def teardown(self):
        if self.driver:
            self.driver.quit()

    def run_test(self, test_func, test_name: str):
        try:
            test_func()
            self.results.append({"test": test_name, "status": "PASS"})
        except Exception as e:
            self.results.append({
                "test": test_name,
                "status": "FAIL",
                "error": str(e)
            })

    def generate_report(self) -> Dict:
        total = len(self.results)
        passed = sum(1 for r in self.results if r["status"] == "PASS")
        failed = total - passed

        return {
            "total": total,
            "passed": passed,
            "failed": failed,
            "pass_rate": (passed / total * 100) if total > 0 else 0,
            "results": self.results
        }

# Pytest fixtures
@pytest.fixture
def driver():
    options = webdriver.ChromeOptions()
    options.add_argument("--headless")
    driver = webdriver.Chrome(options=options)
    yield driver
    driver.quit()

@pytest.fixture
def login_page(driver):
    driver.get("https://example.com/login")
    return LoginPage(driver)

# Test cases
def test_successful_login(login_page):
    login_page.login("testuser", "password123")
    assert "Dashboard" in login_page.driver.title

def test_invalid_credentials(login_page):
    login_page.login("invalid", "wrong")
    error = login_page.get_error_message()
    assert "Invalid credentials" in error
```

## API Testing

```python
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"] and len(missing_keys) == 0

        self.test_results.append(result)
        return result

    def test_post_endpoint(self, endpoint: str, payload: Dict,
                          expected_status: int = 201) -> Dict:
        """Test POST endpoint"""
        url = f"{self.base_url}{endpoint}"
        response = self.session.post(url, json=payload)

        result = {
            "endpoint": endpoint,
            "method": "POST",
            "status_code": response.status_code,
            "passed": response.status_code == expected_status,
            "response_time_ms": response.elapsed.total_seconds() * 1000
        }

        self.test_results.append(result)
        return result

    def test_authentication(self, login_endpoint: str,
                           credentials: Dict) -> bool:
        """Test API authentication"""
        response = self.session.post(
            f"{self.base_url}{login_endpoint}",
            json=credentials
        )

        if response.status_code == 200:
            token = response.json().get("token")
            if token:
                self.session.headers.update({"Authorization": f"Bearer {token}"})
                return True

        return False

    def test_rate_limiting(self, endpoint: str, requests_count: int = 100):
        """Test rate limiting"""
        url = f"{self.base_url}{endpoint}"
        rate_limited = False

        for i in range(requests_count):
            response = self.session.get(url)
            if response.status_code == 429:
                rate_limited = True
                break

        return {
            "rate_limited": rate_limited,
            "requests_before_limit": i if rate_limited else requests_count
        }
```

## Test Data Management

```python
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"""
        return [self.generate_user() for _ in range(count)]

    def generate_order(self, user_id: str) -> Dict:
        """Generate order test data"""
        return {
            "order_id": self.faker.uuid4(),
            "user_id": user_id,
            "items": [
                {
                    "product_id": self.faker.uuid4(),
                    "qu
Files: 1
Size: 11.8 KB
Complexity: 19/100
Category: qa