Testing Guides

Monkey Testing Explained: Types, Examples and When to Use It

Irfan Ahmad 10 min read
Monkey testing concept: unpredictable input applied to a software interface

Monkey testing is the practice of throwing unpredictable input at software to see whether it falls over. No test plan, no expected results, no careful setup — just interaction, at volume, in an order nobody designed for.

The name comes from the infinite monkey theorem: a monkey hitting keys at random for long enough will eventually type Hamlet. Point enough random input at an application for long enough and you will eventually find the input that crashes it.

It sounds unserious. It is one of the oldest and most stubbornly useful techniques in QA, and after twenty years as a niche tool it is worth another look — because the thing that always limited it has finally been solved.

Why monkey testing exists at all

Every test you write encodes an assumption about how the software will be used. That is the point of a test, and it is also its blind spot. You test the checkout flow because you know checkout matters. You do not test what happens when someone hits the back button mid-payment, opens a second tab, and submits the form twice — because it never occurred to you, and it never occurred to your test suite either.

Real users do all of this. Not because they are trying to break anything, but because they get interrupted, they misread a label, their connection drops, they tab backwards through a form, they paste 4,000 characters into a field expecting a postcode.

Monkey testing covers the space your imagination did not. It is deliberately unguided so that it explores paths a person designing tests would never write down.

The three kinds of monkey

The literature splits monkey testing into three tiers, and the distinction matters a lot in practice because they find completely different classes of bug.

Dumb monkeys

A dumb monkey knows nothing about the application. It taps random coordinates, sends random keystrokes, swipes in random directions. It has no idea what a button is, let alone what your app does.

Android’s built-in adb shell monkey is the canonical example: it fires a stream of pseudo-random UI events at a device and reports when the app crashes.

What dumb monkeys find: hard crashes, unhandled exceptions, memory leaks, race conditions from rapid input, and anything that dies when handed input outside the expected range.

What they miss: everything that requires reaching a meaningful state first. A dumb monkey will essentially never fill in a valid email, a valid password, and click “Sign up” in that order. So it never gets past your login screen, which means it never tests your product.

Smart monkeys

A smart monkey has some model of the application. It knows where the clickable elements are, it knows which states exist, it may know that certain regions of the app are more valuable to explore than others. It still chooses unpredictably, but from a set of plausible actions rather than arbitrary screen coordinates.

Gremlins.js, which unleashes clicking, scrolling and typing “gremlins” on a web page, sits roughly here: it targets real DOM elements rather than raw pixels.

What smart monkeys find: everything a dumb monkey finds, plus broken navigation, state that gets corrupted by an unusual sequence of legitimate actions, and UI that breaks under rapid interaction.

What they miss: anything requiring semantically valid data. Knowing that a field is a text input does not tell you it wants a UK postcode.

Brilliant monkeys

A brilliant monkey understands the domain. It knows this is an e-commerce checkout, so it knows a user would add an item, enter a shipping address, choose a payment method, and expect a confirmation. It behaves like a user with an agenda rather than a user with a twitch.

This tier has been described in testing literature for decades and, until recently, was effectively theoretical. Encoding domain understanding meant a human writing it down — at which point you have not built a monkey, you have written a test suite by hand, and you are back where you started.

What changed

Large language models are, among other things, quite good at looking at a rendered page and inferring what it is for.

Show one a page with a product grid, a cart icon and a “Proceed to checkout” button, and it will tell you this is an e-commerce site and that a user would probably add an item to the basket and try to buy it. It will generate a plausible name, a plausible address, a plausible card number format. It knows what “valid input” means for a field labelled “Postcode” because it has read the internet.

That is the missing ingredient the brilliant monkey always needed, and it is available now for fractions of a cent per call.

This is what modern AI monkey testing actually is: the unguided, no-test-plan, explore-what-nobody-thought-of spirit of monkey testing, with a model supplying the domain understanding that used to have to come from a person.

It is also why the technique is worth revisiting if you dismissed it years ago. The objection was always “random clicking never gets anywhere useful”. That objection no longer holds.

Monkey testing vs the things it gets confused with

Four techniques share DNA with monkey testing and get used interchangeably, usually incorrectly.

Fuzz testing feeds malformed or unexpected data into a program’s inputs — file parsers, network protocols, APIs — looking for crashes and memory-safety failures. Fuzzing operates at the data layer; monkey testing operates at the interaction layer. Tools like AFL++ and libFuzzer are fuzzers, not monkeys. They are excellent at finding buffer overflows and terrible at finding a checkout button that does nothing.

Gorilla testing is the opposite of monkey testing despite the primate branding. Gorilla testing hammers one specific module repeatedly and exhaustively until you are confident it is bulletproof. Monkey testing spreads thin across everything. One goes deep on a known target; the other goes wide on unknown ones.

Chaos engineering — Netflix’s Chaos Monkey and its descendants — kills infrastructure: servers, availability zones, network links. It tests whether your system survives failure. It has nothing to do with UI input, and the shared “monkey” naming has confused a decade of engineers.

Ad hoc and exploratory testing are humans poking at software without a script. Exploratory testing in particular is a skilled discipline, not randomness — a good exploratory tester forms hypotheses and chases them. Monkey testing is what you use to cover ground when you do not have a human’s time to spend.

Where monkey testing earns its place

It is worth being clear about what this technique is and is not good for, because overselling it is how it got a bad reputation in the first place.

It is good for:

  • Breadth on surfaces nobody tests. Marketing sites, admin panels, settings pages, onboarding flows — the 80% of an application that has no test coverage because it was never the priority.
  • Pre-release sanity checks. Point it at staging before you ship and let it find the obvious “this form doesn’t submit” issues before a customer does.
  • Regression surface after a refactor. When you have changed something structural, a wide sweep catches the collateral damage your targeted tests do not cover.
  • Teams with no QA function. Which is most small teams. Something covering the unknown paths beats nothing covering them.

It is not a replacement for:

  • Deterministic tests on critical paths. If a flow is business-critical, write an explicit test that always runs the same way. Unpredictable exploration is the wrong tool for a path you already know matters.
  • Load and performance testing. Different discipline, different tools.
  • Security testing. A monkey may stumble into an injection, but that is luck, not method.
  • Accessibility auditing. Use axe, Lighthouse, or a human with a screen reader.

The honest framing is that monkey testing is a complement. It covers the enormous surface area nobody has written a test for yet, which — if you look at where escaped production bugs actually come from — is where most of them live.

The historical objection, and why it stopped applying

Classic monkey testing had three problems that kept it off most teams’ roadmaps:

  1. Findings were mostly noise. A crash from clicking coordinate (417, 892) 4,000 times is technically a bug and practically nobody’s priority.
  2. Nothing was reproducible. “It crashed somewhere in this 90-minute random walk” is not a bug report anyone can act on.
  3. It never reached the interesting parts. Anything behind a login, a form, or a multi-step flow was effectively invisible.

Each of these has an answer now.

Noise goes away when the monkey is choosing goal-directed actions rather than arbitrary ones — a failure in “add to cart, checkout, pay” is a bug your customers hit today. Reproducibility comes from writing the chosen flows out as a stable, versioned plan you can re-execute exactly. And reachability is exactly what domain understanding buys you: a model that can generate a valid signup gets past the signup.

That is the shape of every serious tool in this space now, including the one we build: explore the site, decide what a real user would try, execute those flows deliberately, and record the plan so tomorrow’s run is comparable to today’s.

Getting started

If you want to try the technique on a web application, you have three realistic options.

Roll your own with Playwright or Puppeteer — write a script that walks the DOM and clicks things semi-randomly. Cheap to start, and you will spend more time filtering false positives than reading real ones.

Use a classic tool. Gremlins.js for the browser, adb shell monkey for Android. Both are free, both are dumb-to-smart tier, and both will tell you honestly what that tier can and cannot find.

Use an AI agent. This is the brilliant-monkey tier, and it is where the technique finally does what it always promised. Our round-up of monkey testing tools covers the current field across all three tiers, including the free and open-source options.

If you want to see the difference in practice, the fastest path is our free CLI:

npm install -g @mtai/monkeytest-core
monkeytest run https://your-site.com

It crawls a few pages, works out what a user would try, tries it, and hands you back the bugs with screenshots. The step-by-step walkthrough covers what the output means and how to wire it into CI.

The short version

Monkey testing is unpredictable interaction applied at volume to find bugs your test plan never imagined. It comes in three tiers, and for most of its history only the bottom two were achievable — which is why it stayed a niche technique with a reputation for noise.

The top tier, the one that understands what your application is for, is now buildable. That does not make monkey testing a replacement for your test suite. It makes it a genuinely useful sweep across everything your test suite does not cover, which is most of your application.

#monkey-testing #qa #testing #fundamentals
Irfan Ahmad

Irfan Ahmad

Software Engineering Leader , Helping teams deliver quality software.

Keep reading