Summary
Software testing ensures quality by systematically evaluating applications against requirements, finding defects, and validating functionality. Master testing principles, levels (unit/integration/system/acceptance), techniques (black/white/gray box), test design methods, automation strategies, and metrics to excel in QA interviews and deliver reliable software.
1. Fundamentals
What is Software Testing?
- Definition: Systematic process of evaluating software to identify defects and ensure requirements compliance
- Goal: Deliver quality software that meets user expectations and business objectives
Verification vs Validation
- Verification: "Are we building the product right?" - Ensures correct implementation
- Validation: "Are we building the right product?" - Confirms business needs are met
Testing Principles
- Testing shows presence of defects, not absence
- Exhaustive testing is impossible
- Early testing saves time and cost
- Defect clustering - 80% of defects in 20% of modules
- Pesticide paradox - Same tests become ineffective over time
- Testing is context dependent
- Absence of errors fallacy - Bug-free ≠ successful product
2. Types of Testing
By Approach
Black Box Testing
- Tests functionality without knowing internal structure
- Techniques: Equivalence Partitioning, Boundary Value Analysis
# Example: Testing login function
def test_login():
assert login("valid_user", "valid_pass") == True
assert login("invalid_user", "pass") == False
assert login("", "") == False
White Box Testing
- Tests with knowledge of internal structure
- Techniques: Statement/Branch/Path Coverage
# Example: Testing with code knowledge
def calculate_discount(price, customer_type):
if customer_type == "premium":
return price * 0.8
elif customer_type == "regular":
return price * 0.95
return price
# White box test covering all branches
def test_discount():
assert calculate_discount(100, "premium") == 80
assert calculate_discount(100, "regular") == 95
assert calculate_discount(100, "new") == 100
Gray Box Testing
- Combination of black box and white box
- Limited knowledge of internals
By Execution
Manual Testing
- Human testers execute test cases manually
- Good for: Exploratory, Usability, Ad-hoc testing
Automated Testing
- Scripts/tools execute tests
- Good for: Regression, Load, Repetitive tests
# Simple automation example with pytest
import pytest
def add(a, b):
return a + b
def test_add():
assert add(2, 3) == 5
assert add(-1, 1) == 0
assert add(0, 0) == 0
3. Testing Levels
Unit Testing
- Tests individual components/functions
- Smallest testable parts
- Usually done by developers
# Unit test example
def test_calculate_area():
assert calculate_area(5, 10) == 50
assert calculate_area(0, 10) == 0
Integration Testing
- Tests interaction between components
- Approaches:
- Big Bang: All at once
- Top-Down: From high to low level
- Bottom-Up: From low to high level
- Sandwich/Hybrid: Combination
System Testing
- Tests complete integrated system
- End-to-end scenarios
- Types: Functional, Performance, Security, Usability
Acceptance Testing
- Validates system meets business requirements
- Types:
- UAT (User Acceptance Testing)
- BAT (Business Acceptance Testing)
- Alpha Testing: Internal testing
- Beta Testing: Limited external release
4. Testing Techniques
Functional Testing Types
Smoke Testing
- Basic functionality check
- "Build verification testing"
Sanity Testing
- Focused testing after bug fixes
- Subset of regression testing
Regression Testing
- Ensures new changes don't break existing functionality
# Regression test suite example
class RegressionTests:
def test_existing_login(self):
# Test that still works after new feature
assert login_works() == True
def test_existing_checkout(self):
# Ensure checkout still functions
assert checkout_process() == True
Exploratory Testing
- Simultaneous learning, test design, and execution
- No predetermined test cases
Non-Functional Testing Types
Performance Testing
- Load Testing: Normal expected load
- Stress Testing: Beyond normal capacity
- Spike Testing: Sudden load increases
- Volume Testing: Large amounts of data
# Simple performance test example
import time
def test_response_time():
start = time.time()
result = api_call()
end = time.time()
assert (end - start) < 2.0 # Should respond within 2 seconds
Security Testing
- Authentication, Authorization, Data integrity
- SQL injection, XSS, CSRF testing
Usability Testing
- User experience, Interface design
- Accessibility compliance
Compatibility Testing
- Different browsers, OS, devices
- Forward/Backward compatibility
5. Test Design Techniques
Equivalence Partitioning
Divide input into groups that should behave similarly
# Example: Age validation (0-17: minor, 18-65: adult, 65+: senior)
def test_age_groups():
assert get_category(10) == "minor" # Test one from each partition
assert get_category(30) == "adult"
assert get_category(70) == "senior"
Boundary Value Analysis
Test at boundaries of input ranges
# Example: Testing age boundaries
def test_boundaries():
assert get_category(17) == "minor"
assert get_category(18) == "adult"
assert get_category(65) == "adult"
assert get_category(66) == "senior"
Decision Table Testing
Test all combinations of conditions
| Premium User | Order > $100 | Discount |
|-------------|--------------|----------|
| Yes | Yes | 20% |
| Yes | No | 10% |
| No | Yes | 5% |
| No | No | 0% |
State Transition Testing
Test different states and transitions
Login States: Logged Out -> Logging In -> Logged In -> Logged Out
Test each transition and invalid transitions
Error Guessing
Based on experience, guess likely error scenarios
6. Test Automation
Test Automation Pyramid
/\
/UI\ <- Fewer tests
/----\
/ API \ <- Moderate
/--------\
/ Unit \ <- Most tests
/____________\
Automation Framework Types
- Linear: Record and playback
- Modular: Reusable modules
- Data-Driven: Separate test data
- Keyword-Driven: Action keywords
- Hybrid: Combination
Page Object Model (POM)
# Example POM structure
class LoginPage:
def __init__(self, driver):
self.driver = driver
self.username_field = "id_username"
self.password_field = "id_password"
self.login_button = "btn_login"
def login(self, username, password):
self.driver.find_element_by_id(self.username_field).send_keys(username)
self.driver.find_element_by_id(self.password_field).send_keys(password)
self.driver.find_element_by_id(self.login_button).click()
7. Testing Tools
Categories
- Unit Testing: JUnit, NUnit, pytest, Jest
- API Testing: Postman, REST Assured, SoapUI
- UI Automation: Selenium, Cypress, Playwright
- Performance: JMeter, LoadRunner, Gatling
- Mobile: Appium, Espresso, XCUITest
- CI/CD: Jenkins, GitLab CI, GitHub Actions
Sample Tool Usage
# Selenium WebDriver example
from selenium import webdriver
def test_google_search():
driver = webdriver.Chrome()
driver.get("https://google.com")
search_box = driver.find_element_by_name("q")
search_box.send_keys("software testing")
search_box.submit()
assert "software testing" in driver.title
driver.quit()
8. Test Documentation
Test Plan Components
- Test objectives
- Test scope
- Test approach
- Resources and schedule
- Test deliverables
- Risk and contingencies
- Approval
Test Case Format
Test Case ID: TC001
Title: Verify login with valid credentials
Preconditions: User account exists
Steps:
1. Navigate to login page
2. Enter valid username
3. Enter valid password
4. Click login button
Expected Result: User successfully logged in
Actual Result: [To be filled during execution]
Status: [Pass/Fail]
Defect Report Elements
- ID: Unique identifier
- Title: Brief description
- Severity: Critical/Major/Minor/Trivial
- Priority: High/Medium/Low
- Steps to Reproduce
- Expected vs Actual
- Environment: OS, Browser, Version
- Attachments: Screenshots, logs
9. Metrics and Reporting
Key Metrics
Defect Density = Number of Defects / Size (KLOC or FP)
Test Coverage = (Number of requirements tested / Total requirements) × 100
Defect Removal Efficiency = (Defects found before release / Total defects) × 100
Test Execution Rate = (Tests executed / Total tests planned) × 100
Test Status Report
- Tests planned vs executed
- Pass/Fail rates
- Defect statistics
- Risk assessment
- Recommendations
10. Advanced Concepts
Test-Driven Development (TDD)
- Write failing test
- Write minimal code to pass
- Refactor
# TDD Example
# 1. Write test first
def test_factorial():
assert factorial(5) == 120
assert factorial(0) == 1
# 2. Implement function
def factorial(n):
if n == 0:
return 1
return n * factorial(n-1)
Behavior-Driven Development (BDD)
Feature: Login functionality
Scenario: Successful login
Given I am on the login page
When I enter valid credentials
And I click the login button
Then I should be redirected to dashboard
Continuous Testing
- Testing integrated into CI/CD pipeline
- Automated test execution on code commits
- Fast feedback loops
Risk-Based Testing
- Prioritize testing based on:
- Probability of failure
- Impact of failure
- Focus on high-risk areas first
Mutation Testing
- Introduces small changes (mutations) to code
- Checks if tests detect the changes
- Measures test suite effectiveness
11. Best Practices
Do's
✓ Start testing early (Shift-Left)
✓ Maintain test independence
✓ Use meaningful test data
✓ Keep tests simple and focused
✓ Version control test scripts
✓ Regular test maintenance
✓ Clear naming conventions
✓ Implement proper waits in automation
Don'ts
✗ Test everything (be strategic)
✗ Ignore flaky tests
✗ Hardcode test data
✗ Skip documentation
✗ Automate unstable features
✗ Ignore test environment setup
12. Critical Interview Topics
Core Concepts to Master
When to Stop Testing
- Exit Criteria Met: Test coverage, pass rate, defect density targets
- Risk Assessment: Critical paths tested, acceptable risk level
- Time/Budget Constraints: Deadline-driven decisions
- Diminishing Returns: Cost of finding defects exceeds value
Test Case Prioritization
- Risk-Based: High-risk features first
- Business Priority: Critical functionality
- Frequency of Use: Most-used features
- Complexity: Error-prone areas
- Recent Changes: Modified code
Production Bug Management
- Immediate Response: Assess severity and impact
- Root Cause Analysis: Identify why it wasn't caught
- Hotfix Process: Quick fix vs proper solution
- Test Gap Analysis: Update test coverage
- Process Improvement: Prevent recurrence
Testing Without Requirements
- Exploratory Testing: Discover behavior through exploration
- Competitive Analysis: Compare with similar products
- User Personas: Test from user perspective
- Domain Knowledge: Apply industry standards
- Stakeholder Interviews: Gather implicit requirements
Manual vs Automation Decision
- Automate: Regression, data-driven, repetitive tests
- Manual: Exploratory, usability, one-time tests
- ROI Analysis: Development time vs execution savings
- Maintenance Cost: Keeping scripts updated
Practical Test Design Scenarios
Login Page Testing
- Functional: Valid/invalid credentials, password reset, remember me
- Security: SQL injection, XSS, brute force protection
- Performance: Response time, concurrent users
- Usability: Error messages, tab order, accessibility
E-commerce Checkout
- Flow Testing: Cart to payment to confirmation
- Payment Methods: Credit card, PayPal, vouchers
- Edge Cases: Out of stock, price changes, session timeout
- Integration: Payment gateway, inventory, shipping
Test Estimation Techniques
- Work Breakdown Structure: Decompose into tasks
- Three-Point Estimation: (O + 4M + P) / 6
- Function Points: Complexity-based estimation
- Historical Data: Past project metrics
- Expert Judgment: Team experience
Quick Reference
Testing Lifecycle
Requirements Analysis → Test Planning → Test Design →
Test Execution → Test Closure → Test Maintenance
Defect Lifecycle
New → Assigned → Open → Fixed →
Retest → Verified → Closed/Reopen
Test Estimation
- Work Breakdown Structure (WBS)
- Three-Point Estimation: (Optimistic + 4×Most Likely + Pessimistic) / 6
- Function Point Analysis
- Expert Judgment
Key Interview Success Factors
Technical Excellence
- Strong Foundation: Testing principles, methodologies, types
- Tool Proficiency: Automation frameworks, CI/CD, test management
- Programming Skills: At least one language fluently
- Domain Knowledge: Industry-specific testing requirements
Soft Skills to Demonstrate
- Analytical Thinking: Break down complex problems
- Communication: Report bugs clearly, collaborate with team
- Attention to Detail: Catch subtle defects
- Time Management: Balance thoroughness with deadlines
- Continuous Learning: Stay updated with testing trends
Remember
Excellent testing balances thoroughness with efficiency. Focus on high-risk areas, user impact, and business value. Quality is everyone's responsibility, but testers are the quality advocates.