5 testing types that cover 90% of real work
When you start diving into QA, it feels like there are dozens — if not hundreds — of testing types. Textbooks and courses dump the list on you: exploratory, smoke, regression, acceptance, load, usability, localization, installation, recovery, A/B… — it goes on. And the impression forms that nobody will let you work until you’ve mastered every one of them.
After 12+ years in testing I’ve learned one thing: theory and practice are wildly different. In a real tester’s day, 90% of the time goes into 5 types. The rest are either narrow specialties (perf, security) or academic terms for the same thing.
Below — those five: where they apply, what they catch, where they fail, and the mistakes people make most often.
🔍 Exploratory testing
Testing without pre-written scenarios. No test cases, no checklist — just the product, your experience, and your intuition. The goal is to understand how the system works and where it might break.
In practice it looks simple: you open the app and interact with it. Click buttons, enter weird data, combine actions, try non-standard scenarios. It’s a “what if I…” game.
When it applies
Two situations.
When there are no docs or test cases. A new feature lands, the spec is a couple of lines in Slack, the release is in two days. You need to figure out fast how it even works.
When you need to go beyond the documented scenarios. Even good test cases only cover expected behavior. Real users make mistakes, enter junk, press buttons in the wrong order. This is exactly where exploratory testing delivers the most value.
What it catches well
Unexpected bugs. When you’re not bound by a scenario, you check the product freely — and stumble into situations nobody thought about in advance.
Sometimes it’s funny. You find a button in the UI everyone forgot about — it’s there, nobody has touched it in ages, it never made it into the test cases. Run exploratory and suddenly it turns out the button hasn’t worked for half a year. Nobody noticed.
It also works particularly well with new people on the team. A junior or someone fresh on the project has no entrenched expectations. Their eye isn’t tired. They look at the product with a fresh perspective — and find bugs where everyone else has stopped seeing them.
Where it fails
Useful as it is, exploratory isn’t a silver bullet.
- Poor repeatability. One successful pass that found a pile of issues doesn’t guarantee the next iteration will catch the same. Today you clicked one path, tomorrow a different one.
- Heavy reliance on experience. One tester finds dozens of bugs, another finds almost nothing — because they have different interaction patterns and different exposure to product issues.
- Easy to skip the basics. You get absorbed in exploring and forget to check the obvious.
The core problem: without structured coverage there’s no confidence in quality. You can’t ship a release on exploratory alone.
💨 Smoke testing
The most basic check on the principle “does it work at all, or is it completely broken?” Don’t waste hours on detailed testing if the system doesn’t even start. A first filter.
In practice — a handful of simple actions without depth. App opens → log in → add to cart → pay. If those 4 steps pass, deeper testing makes sense. If they don’t — return the build and fix the foundation.
When it applies
Before the main pass. Before opening a list of 200 test cases, it’s worth running the critical path and making sure the foundation hasn’t collapsed.
Any level: a single function in code, a single feature, a single module, the whole app. The principle is the same — quickly check that the critical path is alive.
Why it’s worth it
So you don’t end up in a situation where you spent two days testing secondary functionality only to discover the main scenario doesn’t work at all. After the fix you’d have to redo everything — because code in the main path changed, and side effects could have touched everything you already verified.
A few minutes of smoke saves hours.
Why people still skip it
Trust in the developer or the process. “Of course the basics work, no way the dev shipped a broken build.” Especially under time pressure — you want to close the task fast.
In reality, even obvious things break. The dev might have checked one chunk, not the whole flow. Or it worked locally but not on dev — different config, different environment, integrations unavailable. The earlier you catch it, the less the team suffers later.
Bonus for interviews
A favorite question: how does smoke differ from sanity testing?
Half the candidates say sanity is broader. The other half — that it’s narrower. The third group — that sanity is on prod. Everyone is partially right.
The correct answer — citing the ISTQB Glossary: smoke and sanity are synonyms. There’s no official difference. You can then add that the industry uses these terms inconsistently, but the canonical definition is one.
📱 Compatibility testing
Checking how the product behaves in different environments. Sounds obvious — in practice this is where the most pain accumulates.
Most common mistake: I tested on my machine, so it works. It doesn’t. Users come with different devices, different OS versions, different browsers, different languages, different time zones. Each axis is a potential class of bugs.
What gets checked
- Different devices (iPhone 14 vs iPhone SE, flagship vs budget Android).
- Different OS versions (iOS 16/17/18, Android 10/12/14).
- Different browsers (Safari, Chrome, Firefox, Edge — including mobile versions).
- Different resolutions and pixel densities.
- Different locales, languages, time zones.
- Different network conditions (Wi-Fi, 4G, weak signal, offline).
Even visually identical devices can behave differently.
A case from practice
I have two monitors on my desk. One FullHD, one 4K. Same diagonal, they look nearly identical. On the 4K I open the product — layout is perfect. On the FullHD — two huge inactive scrollbars appear in a small text field and break the entire page.
That’s a unique case, I hit it once in my whole career. But bugs across mobile devices and browsers surface regularly.
Why it’s critical
The user lives in their own unpredictable environment, not yours. If your testing is limited to one configuration — you’re guaranteed something will surface in prod.
These are often the most painful bugs: can’t reproduce (the right device isn’t around), can’t fix (it’s unclear what exactly is wrong), and users keep complaining.
How to do it right
Don’t try to test “everything on everything” — it’s unrealistic. Test by the numbers.
Open your analytics: what devices, OS versions, browsers do your users actually come from. Cover the top. If 99% of users come via Safari — Safari is the priority, not Chrome because you happen to like it more. If 70% Android / 30% iOS — your coverage should reflect that.
For devices you don’t have physically — cloud farms (BrowserStack, Sauce Labs, AWS Device Farm, regional providers). Not a panacea, but they cover a big chunk.
🔄 Regression testing
Checking that after a change, nothing nearby got broken.
Any edit can hit existing functionality. You added a feature — old logic started behaving differently. You fixed a bug — opened two new ones. You changed a DB query — broke reports nobody had opened in months. Regression catches exactly that.
Important nuance: regression checks what was NOT supposed to change. What was changed on purpose is no longer regression — it’s verification of new functionality.
When it runs
Pretty much constantly.
- After a bug fix — that the fix took, and neighboring features didn’t fall over.
- After a new feature — that old scenarios still work.
- Before a release — to verify the whole product is alive, not just the new part.
Regression isn’t a one-time activity; it’s a recurring part of the process.
The main problem
Volume. Over time the product grows, regression checklists swell, running everything by hand becomes impossible. Two years in you have 800 test cases and one day to regress them all.
What to do:
- Risk-based prioritization. Not all scenarios are equal. Payment and login are critical always; CSV export can be checked less often.
- Risk-based regression. Run deeply through modules touched by the change, the rest at smoke level.
- Automation. Things that haven’t changed in months and work stably — great candidates for automated tests. Brittle, frequently-changing things — better kept manual until they stabilize.
This is usually a QA lead’s job, but the general principles should be understood by every tester — otherwise within a year the team is drowning in regression.
Why skipping it is dangerous
The temptation “the change is small, let’s cut regression” is the top reason for prod bugs. It’s precisely the small edits that produce non-obvious side effects. Change one parameter in a shared helper — and three screens that use that helper break.
Regression protects the product from silent decay. Without it, every release is a lottery.
🚀 Acceptance testing in production
Checks that happen after the release goes live. Formally, testing should finish before release. In practice, you almost always need an extra pass after.
Different projects call it differently: post-release testing, smoke on prod, acceptance, release testing, post-deploy verification. The substance is the same — the product is now in a real environment, with real users and real load, and things can show up here that weren’t visible on staging.
What usually happens
Scenario №1 — something got out of sync during the release. The new frontend rolled out, the backend didn’t. Or vice versa. Two incompatible halves of the app are now sitting in prod painting errors into the logs.
Scenario №2 — prod environment differs from staging. On staging we hit test.bank.ru, in prod — bank.ru. Slightly different contracts, different timings, different error codes. It didn’t show on staging.
Scenario №3 — load. Staging: 5 requests per minute. Prod: 5000. Everything that was “fine” under small load starts falling over.
This is usually accompanied by hotfixes, rollbacks, re-runs, and general team nervousness.
Why it matters especially
Prod is the only environment where the product is used for real. No matter how well staging is set up, it never reproduces real conditions fully.
The cost of a prod mistake is high. A bug on dev — local problem. A bug in prod — user loss, reputation, revenue. So anything missed earlier hurts a lot more here.
How to lower the risk
- Canary release — roll out the new version to 1%, then 10%, then 100%. If something breaks, fewer people are affected.
- Feature flags — ship the code but enable the feature only for the internal team. Verify — open to the rest.
- Staff first — release sees only company staff first. Run the critical path, confirm, then roll out to everyone.
- Tested rollback — the rollback plan must be verified before release. Not “I think it’ll work”, but actually tested.
There’s no such thing as perfect pre-release testing. But good rollout practices turn acceptance testing from panic into a calm procedure.
Closing
There are a lot of terms in QA, even more classifications. In practice 90% of the work boils down to five types:
- Exploratory — to catch unexpected bugs when you don’t have scenarios.
- Smoke — to quickly tell whether the system is alive at all.
- Compatibility — to verify behavior on different devices and environments.
- Regression — to make sure new changes didn’t break the old.
- Acceptance in prod — the last line of defense after rollout.
These don’t exist in isolation. On a real project they’re intertwined: smoke → regression → compatibility across top devices → exploratory pass on a new feature → acceptance in prod after release. One pipeline.
Mistakes usually come not from missing a rare technique. They come from skipping a basic check or making a wrong assumption about how the system works. Master these five and you cover the bulk of the real risks.