1
2 Comments

I have zero coding skills but ended up being the sole QA tester for our tiny studio’s 2nd app — here’s what that taught me

Hey Indie Hackers,

We're a tiny indie studio, and we just launched our second iOS app on the App Store (ExplantFlow, a specialized lab assistant for plant tissue culture growers).

As the only non-technical person on the team, my focus is usually marketing and operations. But for the month leading up to this submission, I took full ownership as the sole QA tester. Over dozens of TestFlight builds on iPad, we ran a lightweight Trello board (Issue Found → Dev Fixed → QA Verified).

Coming in with zero coding background, this experience taught me that being non-technical isn't a handicap in QA — it gives you the exact outsider perspective needed to catch the blind spots developers naturally miss.

Here are the 3 biggest takeaways from this testing cycle:

  1. Devs verify "the trigger"; QA must verify "the physical artifact"
    Developers naturally verify that the code executed and the UI reacted. A user-first tester has to look at the actual output:

Don't just watch the share sheet, open the actual export: When testing our data export, seeing the iOS native share sheet pop up wasn't the test. I extracted the generated ZIP archive to manually verify that all 4 CSVs, photo assets, and the README were present, correctly formatted, and uncorrupted.

  1. The most valuable tests actively break the "Happy Path"
    Developers instinctively test along the intended, ideal user path. Real users do the exact opposite:

Erase-and-restore destruction test: I wiped all local storage on the iPad, uninstalled the build, reinstalled, and tapped "Restore Purchases" to verify that Pro entitlement genuinely survived at the Apple ID level rather than relying on local cache.

Cross-stage state bleeding: I caught a tricky edge case where observation notes logged during early stages were erroneously bleeding across all subsequent completed phases—a bug you only catch when you simulate prolonged, messy usage rather than single-screen checks.

  1. Turn "this feels weird" into structured, reproducible cards
    Telling a developer "this screen feels off" creates friction. On Trello, I forced myself to write standardized cards:

Exact reproduction path: Step 1 → Step 2 → Step 3.

Expected vs. Actual: "What I expected to see" vs. "What actually rendered."

Visual proof: A quick screen recording or screenshot attached directly to the card.
This single shift eliminated back-and-forth ambiguity and drastically sped up fix turnarounds.

Testing taught me that QA isn't just "clicking around to see if it works" — it's stress-testing every underlying assumption on behalf of paying users before launch.

For other solo founders and small teams:
What is an "unhappy path" or edge-case test you almost skipped before shipping, and how did you make sure it never gets missed again — did you adopt a new habit, update a checklist, or switch your tooling?

on August 18, 2026
  1. 1

    The ZIP check is the part that stuck. Share sheet popping up is a trigger. Four uncorrupted CSVs plus the README is the artifact.

    Write one sentence that says what still has to be true after you wipe the iPad, reinstall, and tap Restore Purchases. If you cannot write it, the next TestFlight will keep passing the trigger and failing the product.

    I use a 10-min check for that exact green-test, dead-artifact mess: https://durablefoundations.gumroad.com/l/pyramid-reality-check

    What's the unhappy path you almost skipped on ExplantFlow, the one that would have shipped if you had only trusted the share sheet?

    Kael Voss / DurableFoundations

    1. 1

      Good framing — the "what must stay true" sentence is a nice forcing function. One that got us: observation logs added during one growth stage were bleeding into every other completed stage's history — the trigger (log saved, no error shown) passed clean, but the actual invariant ("a log belongs only to the stage it was created in") was silently broken. Wouldn't have caught it without deliberately simulating messy, prolonged usage instead of a single clean pass.