Software testing means deliberately using your app the way your customers will, and comparing what actually happens with what should happen, before they do. Each written try is a test case: clear steps and an expected result. Anything that differs from the expectation is recorded as a bug with its evidence, then fixed and tested again. The goal is not to prove the app has no bugs, which is impossible, but to know its real condition before launch and after every change.
What testing is, and what it is not
Imagine you are opening a restaurant. Before opening day you invite a few friends, ask them to book, order and pay, and watch where things stumble. That is exactly what testing is: a deliberate try with a critical eye, meant to let you find the problem before a real guest does.
In software, testing answers one question over and over: does the app do what we promised the customer? When they press “Book”, is the booking saved? When they type a wrong number, do they get a message they can understand? When two people book the same slot, what happens?
- Opening the home page and saying “looks fine”.
- The developer trying what they built in the way they know works.
- Waiting for customer complaints to learn what broke.
- Trying once before launch and never again.
- Written steps and an expected result known before you start.
- Trying the right path and the wrong paths too.
- Evidence for every result: a screenshot or a recorded response.
- Running the same tries again after every change.
One thing has to be said plainly: testing does not prove your app has no bugs. It proves that what you tried works, and it exposes what does not work among the things you tried. That is why the value of testing lies in choosing what to try, not in how many tries you make.
Why does a bug cost more the later you find it?
The same bug has a different price depending on who finds it and when. Think of a bug that lets the same table be booked twice:
- During the build: it is fixed in minutes and nobody ever hears of it.
- The day before launch: it is fixed in a hurry, and the launch may slip a little.
- After launch, found by your staff: a fix, an apology to a guest or two, and bookings corrected by hand.
- After launch, found by customers: two guests standing at one table, a bad review, and customers who will not tell you; they just will not come back.
The cost of the code barely changed between those cases. What multiplied is everything around the code: your team’s time, data that has to be corrected, and a customer’s trust that is hard to win back. A customer who hits a bug at checkout usually does not write to you; they close the tab.
Test as close to the moment of change as you can. Every change, however small, is a chance for a new bug, and finding it the same day is as cheap as it gets.
The kinds of testing that matter to a business owner
Testing books list dozens of kinds. You do not need to memorise them. These five cover most of what matters to a small or mid-sized business:
1. Flow testing: can the customer finish what they came for?
The most important kind. You walk the whole path as a customer does: open the site, choose, fill in the form, pay, receive the confirmation. Then you try the wrong ways: an empty field, a phone number with a digit missing, two quick taps on the pay button.
2. Regression testing: does what worked still work?
You add a discount coupon and the tax calculation breaks. This is the most common bug in any product that keeps evolving: a change in one place breaks another. The answer is to keep your test cases and run all of them again after each change. It is known as regression testing, and we cover it on the regression testing page.
3. API testing: does your system talk properly to other systems?
If a mobile app, a delivery partner or an accounting system connects to yours, it connects through the API, not through the screens. Here you check that each request returns the right data, refuses whoever lacks permission and answers with an error message that makes sense. The details are on the API testing page.
4. Phone-size layout: does everything work on a small screen?
Most of your customers open your site on a phone. A button hidden under the keyboard, a table that runs off the screen, Arabic text that flips direction: none of these show up on a desktop screen. Try the important flows at phone width, not just the home page.
5. Acceptance testing: is this actually what I asked for?
This one is yours. Everything may work technically and still not match how you run things: the system allows cancelling until the last minute while you want it closed two hours ahead. Nobody knows your business rules but you, so set time aside to try it yourself before you sign off.
Load testing (thousands of visitors at the same moment), security reviews and penetration testing, and trying native mobile apps on a range of real devices are disciplines of their own, with their own tools and experts. Do not assume flow testing covers them, and ask anyone who tests for you what their work includes and what it does not.
Manual vs automated testing: the difference, and when each is enough
Manual means a person walks through the steps. Automated means the steps are written once, then a program carries them out in a real browser whenever you ask. Neither is “better”; each has its place:
| Manual testing | Automated testing | |
|---|---|---|
| Best at | Noticing what feels odd or confusing, and trying what nobody thought of | Repeating the same steps with the same precision every time |
| Weak point | People get bored and skip steps the tenth time round | It only notices what it was told to check |
| Cost | Low to start, paid again in full on every round | Effort up front to write the cases, then nearly free reruns |
| Suits | A new product whose shape changes daily, and acceptance testing | The core flows that must work after every change |
When is manual enough? When the product is small, changes are rare and you have a written list to go through. Start from the website testing checklist.
When is it not enough? When you ship changes every week, when the list of tries has grown longer than anyone can finish with full attention, or when money or appointments run through the app. That is when skipping the test “just this once” becomes the habit, and that is where the bugs come from.
What is a test case, and how is one written?
A test case is the smallest unit of testing: one try, written so that anyone can carry it out and reach the same verdict. If the person running it has to ask you “what exactly do you mean?”, it is incomplete. It has five parts:
- Title: what we are checking, in one line.
- Prerequisites: what must be in place before starting (a test account, a free slot).
- Steps: specific actions in order, one action per step.
- Expected result: what the customer should see or what should be saved in the system.
- Priority: how bad is it if this case fails?
- Title
- A slot already taken with the same dentist cannot be booked again
- Prerequisites
- Two test patient accounts, and a free slot tomorrow at 10:00 am
- Steps
- 1) Sign in as the first patient and book 10:00. 2) Sign out and sign in as the second patient. 3) Open the booking page for the same dentist and day. 4) Try to choose 10:00.
- Expected result
- The 10:00 slot shows as unavailable to the second patient, and no second booking is created
- Priority
- High: two patients in one slot is a problem the customer sees first-hand
Notice that the case does not say “make sure booking works”. That is a wish, not a test case. A good case pins down the situation, the action and what must happen next. And when it fails, its steps turn straight into a ready bug report.
What do test results mean?
A test run does not end with just “passed” or “failed”. An honest report separates a bug in your app from a problem with the test itself or its conditions:
| Result | What it means | What to do |
|---|---|---|
| Passed | Exactly the expected thing happened | Nothing. Run it again after the next change |
| Failed | The app did something other than expected | Record a bug with its evidence, then fix and retest |
| Blocked | It never started because an earlier step broke, such as sign-in | Deal with the first cause; it is not a new bug in itself |
| Inconclusive | No verdict possible: the connection dropped, or the page changed and the steps no longer match it | Update the case or try again before concluding anything |
| Flaky | It failed once and passed on a rerun with nothing changed | Do not ignore it: it may be a bug that shows under a particular condition |
Illustration: a ready / not-ready verdict at the end of a test run. The numbers are examples.
Twenty passing cases say nothing about the twenty-first that was never written. A good report states its limits openly: what it covered and what it left out.
How much testing does a small product need?
Not everything deserves the same effort. A typo on the About page is annoying; a checkout bug stops your income. Rank by risk, not by page order. Start with these four questions:
- 1Where does money move?
Checkout, refunds, discounts, tax and the invoice. Any bug here is a direct loss or a dispute with a customer.
- 2Who gets in, and what do they see?
Sign-up, sign-in, password recovery and permissions: can staff see what is not theirs? Can one customer see another customer’s data?
- 3Where could data be lost or duplicated?
A booking that is not saved, an order recorded twice, an edit that wipes what came before. These are silent bugs that surface only after they pile up.
- 4Which flow do most of your customers take?
The single flow that nine out of ten visitors go through deserves closer testing than ten pages nobody opens.
Write five to ten test cases covering the answers to those questions: the right path and the most common wrong ones. That is your core set: you rerun it before every launch and after every change. Then add a new case each time a bug turns up, so the same bug never comes back twice.
- The main flow completes from start to finish on a phone.
- Forms reject wrong input with a message people can understand.
- Payment succeeds, and a failed payment does not leave a dangling order.
- Each role sees only what concerns it.
- Repeated taps or simultaneous requests do not duplicate a booking or an order.
- Confirmation messages arrive, in correct Arabic.
Where does an AI QA engineer fit, and what are its limits?
Automated testing traditionally needed someone to write the cases and maintain them, which kept it out of reach of small businesses. An AI QA engineer closes that gap: you describe in your own words what you want to be sure of, and it proposes the test cases, runs them and documents what it found.
In Fanann, the QA engineer works this way: it explores your app, shows you a test plan to review before anything runs, then carries it out in a real browser and checks the API where there is one. Every bug reaches you with a screenshot, steps that reproduce it and expected vs actual, and it does not count as fixed until a retest passes. At the end you get a clear verdict: ready, not ready or inconclusive, with a note of what was not covered. It works on apps built with Fanann and on external websites once you add their address.
Illustration: a bug report backed by a screenshot and steps to reproduce. The data is an example.
A QA engineer sees your app the way a visitor does. It cannot guess a business rule you never stated: if cancelling is not allowed within two hours of the appointment, tell it so. And a passing run is not proof of a bug-free app; it is proof that what was tested works. Acceptance testing remains yours to do.
Common testing mistakes
- Testing only the happy path. Customers make mistakes, rush and tap twice. Try what they will do, not what you hope they do.
- Testing on a desktop while customers are on phones. Test where your customers are.
- Testing with perfect data. A very long name, a number starting with zero, Arabic and English in the same field: reality is messier than your sample data.
- Treating a bug as fixed because someone said so. A bug closes when the case that exposed it passes, not before.
- Trying only the new change. What broke is usually not what you changed but what sits next to it. Rerun the whole core set.
- Testing on real customer data without care. Use test accounts and decide what must never be changed before you begin.
- Leaving testing to the night before launch. There will be no time left to fix anything, so you launch knowing something is broken.
The question is not “does my app have bugs?”; the answer is always yes. The question is “do I know about them before my customers do?”
Key takeaways
- Testing is a deliberate try with written steps and an expected result, not a quick look at the home page.
- The same bug costs more the later it is found, and most of all when a customer finds it.
- Rank by risk: money, sign-in and permissions, data loss and the most-used flow.
- Keep your test cases and rerun them after every change; most bugs come from a change that broke something nearby.
- A bug does not count as fixed until a retest passes.
- A passing run proves that what was tested works, not that the app has no bugs. Always ask what was not tested.