What is Ad-hoc Testing?
Ad-hoc testing is an informal, unplanned testing approach where testers explore the application without predefined test cases or formal documentation. Unlike structured testing methods such as exploratory testing, ad-hoc testing relies on the tester’s intuition, experience, and domain knowledge to identify defects through spontaneous exploration.
Key Characteristics:
- No formal test planning or documentation
- Performed without following specific test design techniques
- Relies on tester’s creativity and experience
- Focuses on breaking the application through unconventional use
- Typically performed once, not repeated
- Can be done at any stage of testing
Purpose: Find defects that formal test cases might miss, especially edge cases and unusual scenarios.
What is Monkey Testing?
Monkey testing is a random testing technique where inputs are provided without any predefined test cases, simulating random user behavior. The name comes from the “infinite monkey theorem”—given enough time, a monkey randomly typing would eventually produce meaningful text.
Key Characteristics:
- Completely random actions without any specific goal
- No knowledge of application functionality required
- Can be automated or performed manually
- Tests application stability under random inputs
- No expected results predefined
- Focus on crashes, hangs, or unexpected errors
Purpose: Assess application robustness against random, unpredictable inputs and user actions.
Ad-hoc vs Monkey Testing: Key Differences
Aspect | Ad-hoc Testing | Monkey Testing |
---|---|---|
Approach | Informal but purposeful | Completely random |
Tester Knowledge | Requires domain knowledge | No knowledge needed |
Planning | Minimal planning | Zero planning |
Goal | Find defects through creative exploration | Test stability under random inputs |
Execution | Guided by tester intuition | Random actions |
Reproducibility | Difficult but possible | Extremely difficult |
Automation | Rarely automated | Often automated |
Coverage | Focused on suspected weak areas | Broad, unpredictable coverage |
Documentation | Minimal notes | Usually none |
Skill Required | High (experienced testers) | Low (can be anyone/anything) |
Types of Ad-hoc Testing
1. Buddy Testing
Two team members (typically developer + tester) work together to test a feature immediately after development.
Example:
Developer: "I just finished the password reset feature."
Tester: "Let me test it right now while you're here."
They explore together:
- Reset with valid email
- Reset with invalid email
- Multiple reset requests
- Expired reset tokens
- Reset while logged in
Developer fixes issues immediately.
Benefits:
- Instant feedback
- Immediate bug fixes
- Knowledge sharing
- Reduced documentation overhead
2. Pair Testing
Two testers work together—one executes tests while the other observes and takes notes.
Roles:
- Driver: Operates the application, performs actions
- Navigator: Observes, suggests test ideas, documents findings
Benefits:
- Combined experience and perspectives
- Better defect detection
- Mentoring opportunity for junior testers
3. Monkey Testing (as a type of Ad-hoc)
Random testing without predefined path (covered in detail below). Unlike the structured approach of exploratory testing, monkey testing involves completely random actions.
Types of Monkey Testing
1. Dumb Monkey Testing
Completely random actions without any knowledge of the application.
Characteristics:
- No understanding of valid vs invalid inputs
- Random clicking, typing, navigation
- No awareness of application state or context
Example Script:
import random
import time
from selenium import webdriver
def dumb_monkey_test(url, duration_minutes=10):
"""
Dumb monkey: Clicks random elements, types random text.
"""
driver = webdriver.Chrome()
driver.get(url)
end_time = time.time() + (duration_minutes * 60)
actions = ['click', 'type', 'scroll', 'back', 'forward']
while time.time() < end_time:
action = random.choice(actions)
try:
if action == 'click':
elements = driver.find_elements_by_xpath("//*")
if elements:
random.choice(elements).click()
elif action == 'type':
inputs = driver.find_elements_by_tag_name('input')
if inputs:
random_text = ''.join(random.choices('abcdefghijklmnopqrstuvwxyz0123456789', k=10))
random.choice(inputs).send_keys(random_text)
elif action == 'scroll':
driver.execute_script(f"window.scrollBy(0, {random.randint(-500, 500)});")
elif action == 'back':
driver.back()
elif action == 'forward':
driver.forward()
time.sleep(random.uniform(0.1, 2))
except Exception as e:
print(f"Error during {action}: {e}")
# Continue testing even if an action fails
driver.quit()
# Run dumb monkey test
dumb_monkey_test('https://example.com', duration_minutes=5)
2. Smart Monkey Testing
Random testing with some knowledge of the application, avoiding completely invalid actions.
Characteristics:
- Understands valid input formats
- Knows which elements are interactive
- Respects application context and state
- Focuses on valid user workflows
Example Script:
def smart_monkey_test(url, duration_minutes=10):
"""
Smart monkey: Understands application structure, performs valid actions.
"""
driver = webdriver.Chrome()
driver.get(url)
end_time = time.time() + (duration_minutes * 60)
while time.time() < end_time:
try:
# Focus on clickable elements only
clickable = driver.find_elements_by_xpath("//button | //a | //input[@type='submit']")
if clickable:
element = random.choice(clickable)
if element.is_displayed() and element.is_enabled():
element.click()
time.sleep(random.uniform(0.5, 2))
# Type realistic data in input fields
inputs = driver.find_elements_by_xpath("//input[@type='text'] | //input[@type='email']")
for inp in inputs:
if inp.is_displayed():
input_type = inp.get_attribute('type')
if input_type == 'email':
inp.send_keys(f"test{random.randint(1,1000)}@example.com")
else:
inp.send_keys(f"TestData{random.randint(1,1000)}")
except Exception as e:
print(f"Smart monkey encountered: {e}")
driver.quit()
3. Brilliant Monkey Testing
Highly intelligent testing that understands user patterns, business logic, and application context.
Characteristics:
- Simulates realistic user behavior
- Understands business workflows
- Tests meaningful scenarios
- Adapts based on application state
Note: Brilliant monkey testing overlaps significantly with exploratory testing, which uses structured investigation methods.
Comparison Table: Monkey Testing Types
Type | Knowledge Level | Validity | Automation | Use Case |
---|---|---|---|---|
Dumb Monkey | None | Random (valid + invalid) | Easy | Stress testing, crash detection |
Smart Monkey | Basic | Mostly valid | Moderate | Workflow stability testing |
Brilliant Monkey | High | Contextually valid | Complex | User behavior simulation |
When to Use Ad-hoc Testing
Ideal Scenarios:
✅ Time constraints: Need quick feedback without formal test case preparation
✅ New features: Initial exploration of unfamiliar functionality
✅ Supplement to formal testing: Finding defects that structured tests miss
✅ After bug fixes: Verifying fixes and exploring related areas
✅ Before major testing: Gaining understanding before writing formal test cases
✅ Critical path testing: Quick sanity check of core functionality
Example Workflow:
Sprint Day 5: Feature "Share Post" completed
→ Ad-hoc testing (30 min): Tester explores share functionality
→ Finds: Share button doesn't work on mobile, shared link missing preview
→ Bugs logged, developers fix same day
→ Formal test cases written for regression suite
When to Use Monkey Testing
Ideal Scenarios:
✅ Stability testing: Assess application robustness
✅ Load testing supplement: Random user behavior under load
✅ Regression testing: Verify no crashes after changes
✅ Mobile app testing: Simulating unpredictable user interactions
✅ Endurance testing: Long-running random tests to find memory leaks
✅ Exploratory automation: Discover unexpected behaviors
Example Application:
Mobile Game Testing with Dumb Monkey:
- Random taps on screen
- Random swipes
- Rapid button pressing
- Switching between apps
- Rotating device
- Simulating low memory conditions
Goal: Ensure game doesn't crash regardless of user actions
Ad-hoc Testing Best Practices
1. Document Your Findings
Even though ad-hoc testing is informal, document:
- Areas tested
- Issues found
- Steps to reproduce defects
- Questions raised
Template:
## Ad-hoc Testing Notes - [Feature Name]
**Date**: 2025-10-02
**Tester**: Your Name
**Duration**: 45 minutes
### Areas Covered:
- User registration flow
- Password validation
- Email verification
### Bugs Found:
1. [P2] Email verification link expires immediately
2. [P3] Password strength indicator doesn't update in real-time
Note: Proper [bug reporting](/blog/bug-reports-developers-love) helps ensure quick resolution.
### Questions:
- Should we allow special characters in usernames?
- What's the password complexity requirement?
### Follow-up Ideas:
- Test registration with existing email
- Test concurrent registrations from same IP
2. Focus on High-Risk Areas
Prioritize areas with:
- Complex logic
- Recent changes
- Historical defect density
- High business impact
3. Think Like a User
Perform actions users would actually do:
- Common workflows
- Shortcuts and workarounds
- Error recovery scenarios
4. Think Like an Attacker
Try to break the application:
- Invalid inputs
- Boundary values
- Unexpected sequences
- Security vulnerabilities
5. Time-box Your Sessions
Ad-hoc testing can be endless. Set limits:
- 30-60 minute focused sessions
- Specific area or feature
- Clear objectives
Monkey Testing Best Practices
1. Define Clear Objectives
Even random testing needs goals:
- Test for crashes? Memory leaks? UI freezes?
- What constitutes a failure?
- How long should testing run?
2. Monitor and Log
Capture evidence of issues:
def monitored_monkey_test(url, duration_minutes=10):
"""
Monkey test with logging and monitoring.
"""
driver = webdriver.Chrome()
driver.get(url)
log_file = open('monkey_test_log.txt', 'w')
error_count = 0
end_time = time.time() + (duration_minutes * 60)
while time.time() < end_time:
action = random.choice(['click', 'type', 'navigate'])
try:
# Perform action
if action == 'click':
elements = driver.find_elements_by_xpath("//*[@onclick or @href]")
if elements:
element = random.choice(elements)
log_file.write(f"Clicking: {element.tag_name} - {element.get_attribute('id')}\n")
element.click()
# Check for errors
errors = driver.find_elements_by_xpath("//*[contains(text(), 'Error') or contains(text(), 'Exception')]")
if errors:
error_count += 1
log_file.write(f"ERROR DETECTED: {errors[0].text}\n")
driver.save_screenshot(f"error_{error_count}.png")
except Exception as e:
log_file.write(f"Exception: {e}\n")
log_file.write(f"\nTotal errors found: {error_count}\n")
log_file.close()
driver.quit()
3. Use Seeded Randomness
Make tests reproducible:
import random
# Set seed for reproducible random tests
random.seed(12345)
# Now random actions can be reproduced
# by using the same seed
4. Combine with Health Checks
Monitor application health during monkey testing:
- CPU usage
- Memory consumption
- Response times
- Error logs
- Crash reports
5. Analyze Results
Look for patterns in failures:
- Specific actions causing crashes?
- Memory leaks over time?
- Performance degradation?
Limitations and Risks
Ad-hoc Testing Limitations
❌ Non-repeatable: Hard to reproduce exact test scenarios
❌ Skill-dependent: Quality varies based on tester expertise
❌ No coverage metrics: Difficult to measure completeness
❌ Documentation gaps: May not capture all findings
❌ Not suitable for compliance: Regulatory testing requires formal documentation
Monkey Testing Limitations
❌ Low defect detection rate: Most random actions are meaningless
❌ No expected results: Hard to determine if behavior is correct
❌ Inefficient: Wastes time on unlikely scenarios
❌ False positives: May report issues that aren’t really bugs
❌ Doesn’t test business logic: Random inputs don’t validate requirements
Real-World Examples
Example 1: Mobile App Ad-hoc Testing
Scenario: New "Dark Mode" feature added to mobile app
Ad-hoc Testing Session:
1. Enable dark mode → Check all screens
2. Toggle dark mode rapidly → Check for flickers
3. Enable dark mode mid-workflow → Check consistency
4. Dark mode + low battery mode → Check interaction
5. Dark mode + accessibility settings → Check contrast
Bugs Found:
- Images not optimized for dark mode (hard to see)
- Notification pop-ups still use light theme
- Settings screen doesn't reflect dark mode immediately
Example 2: Website Monkey Testing
Scenario: E-commerce checkout process stability testing
Monkey Test (Automated, 2 hours):
- Random product selections
- Random quantity changes
- Random navigation (back/forward/refresh)
- Random form inputs in checkout
- Random payment method selections
Results:
- 5 crashes detected
- 12 JavaScript errors logged
- 3 timeout issues
- Memory leak identified (memory grew from 100MB to 1.2GB)
Follow-up: Formal test cases created for identified issues
Integration with Formal Testing
Recommended Workflow:
Phase 1: Requirements Analysis
→ Create formal test plan
Phase 2: Initial Development
→ Ad-hoc testing by developers (buddy testing)
→ Early defect detection
Phase 3: Feature Complete
→ Formal scripted testing
→ Ad-hoc testing for edge cases
→ Monkey testing for stability
Phase 4: Pre-Release
→ Automated regression tests
→ Monkey testing (overnight runs)
→ Ad-hoc testing of critical paths
Phase 5: Production
→ Monitored monkey testing in staging
→ Ad-hoc testing of user-reported issues
Conclusion
Ad-hoc and monkey testing are valuable complements to structured testing approaches, not replacements. They excel at finding unexpected issues that formal test cases miss, but should be used strategically alongside systematic testing methods.
Key Takeaways:
- Ad-hoc testing: Informal, purposeful exploration by experienced testers
- Monkey testing: Random actions to test stability and robustness
- Both approaches: Supplement formal testing, don’t replace it
- Document findings: Even informal testing needs basic documentation
- Time-box sessions: Prevent endless, unfocused testing
- Balance is key: Combine chaotic testing with systematic approaches
Use ad-hoc testing when you need creative, experience-driven exploration. Use monkey testing when you want to stress-test stability with random inputs. But always ensure the bulk of your testing follows structured, repeatable, documented approaches that provide measurable coverage and confidence in quality.