Web app testing

Software Testing Basics: The Fundamentals Every Team Needs

Key takeaways

  • Testing gives you evidence to ship, not proof that software is bug-free.

    It verifies that you built the product right and validates that you built the right product. A green run means you didn't find bugs, not that there are none, so the goal is enough evidence to ship with confidence and to catch the failures that matter before customers do.

  • End-to-end tests give the clearest signal that a release is safe.

    Unit and integration tests catch mistakes close to the code, but only E2E tests run complete workflows the way a customer would. The old advice to keep them few came from slow, flaky suites. With parallel runs and maintained tests, run as much E2E coverage as you can keep fast and reliable.

  • Test continuously, not just before release.

    The longer a bug survives, the harder it is to find and the more it costs to fix. Test requirements before development starts, then add or update tests with every new feature, change, bug fix and refactor.

  • Manual and automated testing do different jobs, and you need both.

    People bring judgment: A tester notices that a photo filter makes portraits look washed out. Automation brings repeatability: It can re-check hundreds of workflows on every deploy, which no team can do by hand.

  • The hard part of testing is keeping your suite trustworthy, not writing tests.

    Flaky tests, broken selectors, unstable data and unreadable failures are what make teams stop trusting a suite. Treat tests like production code: Update them in the same pull request as the change, fix flakes instead of retrying them, and capture logs, video and traces on every run.

Every team says quality matters. Then the sprint ends, the release is due, and testing is the thing that gets squeezed. In Tricentis's 2026 Quality Transformation Report, 60% of organizations say they deploy untested code to production, most often because of pressure to ship faster (32%) or because there's too much AI-generated code to test fully (30%). Not because they don't care, but because testing well is hard.

Software testing is the practice of checking that an application behaves the way it should, under real conditions, before your users find out it doesn't. The basics come down to a few things: knowing which kinds of tests exist, which ones protect your release, when to run them, and how to keep them trustworthy as the product changes. This guide covers each one.

Thinking about who'll do all this testing? QA Wolf's agent writes, runs and maintains your E2E tests. Book a demo to see it on your own app.

What is software testing?

Software testing verifies that software works as intended and validates that it does what users need. In practice, that means pages load, buttons work, forms submit, payments go through, and yesterday's features still work after today's change.

Two words do most of the work here:

  • Verification: Did we build it right? (Does it match the spec?)
  • Validation: Did we build the right thing? (Does it solve the user's problem?)

Testing isn't about perfection. No test suite proves software is bug-free. Its job is to give you enough evidence to ship with confidence, and to catch the failures that matter before customers do.

What are the main types of software testing?

There are dozens of testing types, but they sort into four groupings. Most teams use a mix of all four.

Grouping Types What it tells you
By approach Manual, automated Who (or what) runs the test
By level Unit, integration, end-to-end (system), acceptance How much of the system the test covers
By objective Functional, regression, smoke, performance, security, usability What risk the test checks for
By visibility Black-box, white-box, gray-box How much of the code the tester can see

Testing levels: from one function to the whole product

  • Unit tests check a single function or component in isolation. They're fast and cheap, and they catch mistakes close to the code change. They don't tell you whether a user can finish checkout.
  • Integration tests check how components and services work together: data flow, APIs, interfaces.
  • End-to-end (E2E) tests run complete user workflows across the UI, services and environments, the way a customer would. They're the clearest signal that a release is safe. (More in our end-to-end testing 101 guide.)
  • Acceptance tests confirm the software meets business requirements. Many teams write acceptance criteria as E2E tests, with stakeholders signing off.

Classic guidance (the test pyramid) said to keep E2E tests few because they were slow, flaky and expensive. We think that constraint is out of date: With parallel execution and maintained tests, you should run as much E2E coverage as you can keep fast and reliable.

Testing objectives: what each test is for

  • Functional testing checks that features behave correctly: Workflows complete, rules are enforced.
  • Regression testing checks that new changes didn't break existing behavior. It works best anchored in E2E workflows.
  • Smoke testing is a quick pass over the most critical paths to decide whether a build is stable enough for deeper testing.
  • Performance testing measures speed, throughput and stability under load.
  • Security testing looks for vulnerabilities and protects user data.
  • Usability testing checks whether real people find the product easy to use.

Black-box, white-box and gray-box testing

Black-box testing judges behavior from the outside (inputs and outputs) with no knowledge of the code. White-box testing uses knowledge of the code's structure and logic, usually at the unit level. Gray-box testing sits in between, using some knowledge of internals to design sharper functional or integration tests.

What are the 7 principles of software testing?

The ISTQB, which runs the most widely used tester certification, lists seven principles of software testing. They're worth knowing because each one explains a mistake teams keep making:

  1. Testing shows the presence of defects, not their absence. A green run means you didn't find bugs, not that there are none.
  2. Exhaustive testing is impossible. You can't test every input and path, so prioritize by risk.
  3. Early testing saves time and money. A bug caught in a design review costs less than one caught in production.
  4. Defects cluster together. A small number of modules usually holds most of the bugs. Test there harder.
  5. Tests wear out (the pesticide paradox). Running the same tests forever stops finding new bugs. Update and extend them.
  6. Testing is context dependent. A banking app and a game need different testing.
  7. The absence-of-errors fallacy. Bug-free software that doesn't meet user needs is still a failure.

What are the steps in the software testing life cycle?

The software testing life cycle (STLC) is the order of work most teams follow. Sources number the steps differently (six or seven is common), but the shape is the same:

  1. Requirement analysis: Figure out what needs testing and what "working" means.
  2. Test planning: Decide scope, approach, tools, owners and schedule.
  3. Test case design: Write the test cases and the data they need.
  4. Environment setup: Prepare clean, realistic environments to run them in.
  5. Test execution: Run the tests, log results, file bugs.
  6. Test closure: Review coverage and results, and feed what you learned into the next cycle.

In teams that ship daily, this isn't a waterfall. The steps happen continuously, inside every pull request and every deploy.

When should you test?

Test continuously, not just at the end. The longer a bug survives, the harder it is to find and the more it costs to fix. Build and run tests:

  • Before development starts: Test requirements and assumptions. Bugs in the design are still bugs.
  • When you add a feature: Prove it works and add it to your regression suite.
  • When you change a feature: Confirm the change and check nothing nearby broke.
  • When you fix a bug: Make sure the fix holds and add a test so it can't quietly return.
  • Before you refactor: A solid suite is the safety net that makes refactoring safe. (See how regression coverage enables refactoring.)

Manual vs. automated testing: which do you need?

You need both, for different jobs. Manual testing brings judgment; automation brings repeatability.

Take a photo-editing app. An automated test confirms the "enhance" filter applies without errors. A human tester notices it makes portraits look washed out. But a person can't re-check 400 workflows on every deploy. Automation can.

Automation can take on some judgment, too. When a correct result can be worded many ways, like a chatbot's reply or AI-generated copy, an exact-match assertion rejects valid output. An LLM-as-judge assertion handles that check instead: A model decides whether non-deterministic output meets a stated requirement, while the rest of the test still asserts exact state. QA Wolf tests can use them alongside standard Playwright assertions. (Here's how we use semantic assertions and external judges for generative AI output.) People still decide what's worth testing, and notice when something works but feels wrong.

Manual testing Automated testing
Best for Exploratory testing, usability, visual review, undefined behavior Regression, critical workflows, checks that must pass every release
Speed Limited by human time Minutes, in parallel
Scale Each run needs more people Same tests run across environments at no extra labor
Cost Ongoing labor every run Higher upfront, lower over time
Maintenance Testers adapt to UI changes Tests must be updated as the app changes
Judgment High Narrow: LLM-as-judge assertions for output that can vary

Automated tests are usually written in code with frameworks like Playwright, Cypress or Selenium and run in CI/CD. The catch: They don't maintain themselves. When the UI changes, selectors break. When business logic changes, assertions go stale. Teams that fall behind end up with a suite nobody trusts.

AI agents can now take on that upkeep. Many "self-healing" tools only patch broken selectors, but selectors cause a minority of test failures. QA Wolf's agent diagnoses each failure first, from DOM diffs, network traces, console errors and test data. Real bugs get reported to you, and tests broken by a product change get fixed, whether the fix is a longer wait, a missing step or a new selector. (More in the six types of self-healing test automation.)

How do you know your tests are working?

Track a handful of metrics that measure trust and speed, not just volume:

  • Coverage of key workflows: What share of the journeys that matter are tested end to end.
  • Flaky test rate: How often tests pass and fail without a code change. (Here's what your system should do with a flaky test.)
  • Skipped tests: Every skipped test is coverage you think you have but don't.
  • Time to triage failures: How long it takes to tell a real bug from noise.
  • Time to cover new features: How quickly new functionality gets tests.

What are the most common software testing challenges?

Most testing problems aren't about writing tests. They're about keeping trust in them.

Challenge Fix
Nobody owns testing. Developers assume QA has it; QA (if it exists) is stretched thin. Name an owner for each kind of testing. If you lack the bandwidth for automation and maintenance, use a platform whose agent writes and maintains tests, or a partner, rather than letting coverage shrink.
The suite is fragile and falling behind. Fast releases break brittle tests, failures get waved off, and real bugs slip through. Treat tests like production code. Make test updates part of the pull request, use durable selectors, and delete tests that no longer earn their keep. (Why suites decay, and how to stop it.)
Test data is unstable. Shared or polluted data makes tests fail for the wrong reasons. Give each test isolated, deterministic data and reset state between runs.
Failures are hard to read. Was it a bug or a bad environment? Capture logs, video and traces on every run, and track failure patterns so flakes get fixed instead of retried. (Flaky coverage is fake coverage.)
Coverage stops at the happy path. Test edge cases, error states and third-party failures, the paths real users actually hit. (How to plan meaningful coverage.)

How we apply these basics at QA Wolf

QA Wolf is an AI testing platform. Its agent writes, runs and maintains end-to-end tests for web, mobile, Electron and Windows desktop apps, and the fundamentals above are built into how it works.

One workflow per test, written as code. The agent writes every test as Playwright or Appium code, so each step and assertion is visible and reviewable. No black-box "AI clicked around and it looked fine." Tests follow Arrange-Act-Assert, so anyone can read what's being checked:

// Illustrative example: a checkout regression test
test('customer can check out with a saved card', async ({ page }) => {
  // Arrange: start from a clean, seeded account (isolated test data)
  await page.goto('/login');
  await page.getByLabel('Email').fill(process.env.TEST_USER_EMAIL);
  await page.getByLabel('Password').fill(process.env.TEST_USER_PASSWORD);
  await page.getByRole('button', { name: 'Sign in' }).click();

  // Act: run the workflow the way a customer would
  await page.getByRole('link', { name: 'Cart' }).click();
  await page.getByRole('button', { name: 'Check out' }).click();
  await page.getByRole('button', { name: 'Pay with saved card' }).click();

  // Assert: check the outcome the user cares about
  await expect(page.getByRole('heading', { name: 'Order confirmed' })).toBeVisible();
});

Isolated, parallel runs on every pull request. QA Wolf selects the tests relevant to each PR and runs them in parallel, each in its own clean environment, so results come back in minutes and one test's data can't poison another's.

Every failure gets investigated. When a test fails, QA Wolf's agent reproduces it to tell a real bug from a broken test. Real bugs reach you as bug reports with video, steps and a trace. Broken tests get fixed, not retried into silence.

Tests stay current. When a product change breaks a test, the agent fixes it automatically. That's the maintenance work that usually sinks in-house suites.

To try it, add QA Wolf to your coding agent and ask for your first test. If your team also needs a QA strategy (what to cover, how deep to go, whether coverage is good enough), QA Wolf's Coverage-as-a-Service embeds full-time QA engineers to plan and run it. Book a demo to see either on your own app.

The bottom line

The basics of software testing aren't complicated: Know your test types, anchor coverage in the workflows users depend on, test early and continuously, and keep your suite trustworthy. The hard part is doing all of it every sprint, as the product keeps changing. That's where most teams need help.

Frequently asked questions

  • What are the basics of software testing?

    The basics are: what testing is (verification and validation), the main types (manual vs. automated; unit, integration, E2E and acceptance levels; functional, regression and non-functional objectives), the seven testing principles, the testing life cycle, and how to keep tests reliable. Most teams start with automated tests for their most critical user workflows.

  • What are the 7 principles of software testing?

    The ISTQB's seven principles are: testing shows the presence of defects, not their absence; exhaustive testing is impossible; early testing saves time and money; defects cluster together; tests wear out (the pesticide paradox); testing is context dependent; and the absence-of-errors fallacy (bug-free software can still fail users).

  • What are the 7 steps of software testing?

    Most descriptions of the software testing life cycle cover: requirement analysis, test planning, test case design, environment setup, test execution, and test closure. Some add a separate defect-reporting or retesting step, which makes seven. In fast-moving teams these steps repeat continuously rather than in sequence.

  • What is the difference between manual and automated testing?

    Manual testing uses people to explore the app and apply judgment, which is best for usability, visual review and new features. Automated testing uses code to run the same checks repeatedly, which is best for regression and critical workflows that must pass on every release. Strong teams use both.

  • Is QA harder than coding?

    It's a different kind of hard. Coding asks "how do I make this work?" QA asks "how could this break?" and needs broad product knowledge, attention to edge cases and, for automation, real coding skills. Writing reliable automated tests and keeping them current is a software engineering job in its own right.

  • Will QA testers be replaced by AI?

    No. AI can now write, run and maintain tests, but people will always play a critical role in QA. Someone has to decide what quality means for the product, choose what's worth testing, and judge whether software that technically works is right for its users. As AI takes on the repetitive work, testers spend more of their time on strategy, coverage and the judgment calls that need a person.

More from the blog

All posts