Why QA Testing Is the Most Satisfying Kind of Problem-Solving

Share
Why QA Testing Is the Most Satisfying Kind of Problem-Solving

There's a difference between looking at something linearly and looking at it multifaceted. Most people go through life linearly. In fact, our entire western culture teaches us to think linearly. In the majority of my world at work, that means you encounter a problem, you follow the steps to reproduce it, you confirm it's real, you hand it off. One path in, one result out. A to B. Done.

QA testing is not that (the smaller but really exciting part of my job).

QA testing is the deliberate act of looking at one thing from every possible angle at the same time. You're not asking "does this work?" You're asking "does this work and does everything connected to it still work and does it work when I do it in a different order and does it work when the API is slow and does it work when the user has a different subscription plan and does it work when they're on mobile and does it work when two users hit it at the same time?" You're holding a gem up to the light and turning it, facet by facet, checking each reflection for a crack.

That's the reason I enjoy QA testing so much. It's not linear. It's multifaceted. And the fact that there are a plethora of testing methods — different lenses, different angles, different approaches — exists for that very reason. Because when you test, you are testing in context. You're not verifying a single behavior in isolation. You're checking that the things around a bug fix still work after the fix lands. You're running through the entire new feature, end to end, in every configuration you can think of, before release day. You're asking: what is the full picture of this feature's behavior — not just the happy path, but every path?

If you're the kind of person who naturally thinks in webs instead of lines — who sees connections between things that other people treat as separate — QA testing is deeply, structurally satisfying in a way that few other roles are.

Let me show you what I mean. First, by laying out the full landscape of testing methods. Then, by contrasting it with the kind of testing you do in support — which is a completely different mental mode — so you can see exactly why the multifaceted approach is what makes QA feel like real problem-solving.


The Top 20 Testing Methods — With Examples From DuckBuddy

DuckBuddy is a social networking platform for remote workers. The frontend is JavaScript and React. The service layer is Python with FastAPI. The data layer is PostgreSQL, MongoDB, Redis, Cassandra, and Neo4j. Users can find other remote workers through AI suggestions, search for people, search and create chat rooms, direct message, video call, and screenshare. It's a complex, interconnected system — which makes it a perfect example for showing how different testing methods approach the same product from different facets.

Here are the top 20 testing methods used in software testing, each with a concrete DuckBuddy example.


1. Functional Testing

What it is: Verifying that each function of the software operates in conformance with its intended specification. Does the feature do what it was built to do?

DuckBuddy example: A developer builds a new "Create Chat Room" feature. Functional testing verifies that when a user clicks "Create Chat Room," enters a name, selects a category, and clicks "Create," the room is actually created in the database, appears in the chat room list, and the user is automatically joined to it. Does the feature work as specified? That's functional testing.


2. Regression Testing

What it is: Re-running existing tests after a code change to verify that previously working functionality hasn't broken. The "did the fix break something else" test.

DuckBuddy example: A developer fixes a bug where DM notifications weren't sending when a user was offline. Regression testing means re-running the full notification test suite — not just DM notifications, but chat room notifications, connection request notifications, and video call invitations — to make sure the fix didn't accidentally break any of the other notification paths that share the same underlying Python service.


3. Integration Testing

What it is: Testing the interface between two or more components or systems to verify they work together correctly.

DuckBuddy example: The AI matching feature uses Neo4j to find connections between users based on shared attributes. Integration testing verifies that the Python FastAPI service correctly sends queries to Neo4j, receives the graph data back, and transforms it into the JSON format the React frontend expects. You're not testing the AI logic itself or the frontend rendering — you're testing the seam between the two systems.


4. End-to-End (E2E) Testing

What it is: Testing the entire application flow from start to finish, simulating a real user journey through the complete system.

DuckBuddy example: A user signs up, completes their profile, gets AI-suggested connections, clicks on one, sends a DM, starts a video call, shares their screen, and then creates a chat room. The E2E test exercises every layer — React frontend, Python FastAPI, PostgreSQL for user data, Neo4j for matching, Redis for session state, MongoDB for message storage — in one continuous flow, verifying the whole system works together as a user would actually experience it.


5. Smoke Testing

What it is: A quick, preliminary test of the most critical functions to determine whether the build is stable enough for further testing. If smoke testing fails, you stop and send it back.

DuckBuddy example: After a new build is deployed to the QA environment, smoke testing verifies four things: can a user log in, can they load their dashboard, can they send a DM, and can they join a chat room. If any of those four fail, there's no point running the rest of the test suite — the build is broken at a foundational level and goes back to the developer immediately.


6. Unit Testing

What it is: Testing the smallest individual units of code — usually individual functions or methods — in isolation, to verify each one produces the correct output for a given input.

DuckBuddy example: The Python service has a function that calculates the "connection strength" score between two users based on shared profession, timezone overlap, and mutual connections in Neo4j. A unit test passes in two specific user profiles and verifies the function returns the expected score. The database isn't involved. The frontend isn't involved. Just the function, the input, the output.


7. API Testing

What it is: Testing the API endpoints directly — sending requests and verifying the responses — without going through the frontend UI.

DuckBuddy example: DuckBuddy's FastAPI service exposes a GET /api/connections/suggestions endpoint that returns AI-matched user suggestions. API testing sends a request with a valid auth token, verifies the response is a 200 with a JSON array of user objects, checks that each object has the required fields (user_id, name, profession, match_score), and then sends a request with an invalid token to verify it returns a 401. You're testing the contract the API promises to uphold.


8. UI/UX Testing

What it is: Testing the user interface and user experience — not just whether things function, but whether they look right, feel right, and are usable.

DuckBuddy example: The new chat room interface has a sidebar that lists active rooms, a main panel for messages, and a top bar with the room name and member count. UI testing verifies that the sidebar collapses on mobile screens, that the message input field is visible without scrolling, that the member count updates when someone joins or leaves, and that the room name doesn't truncate at awkward points on different screen sizes. Does it feel right? That's UI testing.


9. Performance Testing

What it is: Testing how the system performs under various load conditions — speed, responsiveness, stability.

DuckBuddy example: A chat room has 500 concurrent users sending messages during a live co-working session. Performance testing simulates 500 virtual users connecting to the same room via WebSocket, each sending a message every 5 seconds, and measures the message delivery latency, the CPU usage on the Python service, the Redis pub/sub throughput, and the MongoDB write performance. If messages start arriving more than 2 seconds late under that load, the system has a performance problem.


10. Load Testing

What it is: A subset of performance testing that specifically tests the system at its expected normal and peak load levels to verify it can handle the volume.

DuckBuddy example: DuckBuddy expects 10,000 concurrent users during peak morning hours when remote workers log on and start their day. Load testing simulates 10,000 simultaneous logins over a 5-minute window, then 10,000 users loading their dashboards and receiving AI connection suggestions. Can PostgreSQL handle 10,000 concurrent session lookups? Can Neo4j return graph queries for 10,000 users at once? Can Redis manage 10,000 active session tokens without contention? Load testing answers those questions.


11. Stress Testing

What it is: Testing the system beyond its designed capacity to find the breaking point and observe how it fails.

DuckBuddy example: Take the same 10,000-user load test and keep increasing — 15,000, 20,000, 30,000 concurrent users — until something breaks. Stress testing discovers how the system breaks. Does FastAPI start returning 503 errors? Does MongoDB write latency spike to 30 seconds? Does the React frontend crash with out-of-memory errors? Does Neo4j run out of heap space? The goal isn't to fix the breaking point — it's to know where it is and what happens when you reach it, so you can set alerts and scaling thresholds in production.


12. Security Testing

What it is: Testing the system for vulnerabilities — unauthorized access, data exposure, injection attacks, authentication bypasses.

DuckBuddy example: Security testing verifies that User A cannot read User B's direct messages by manipulating API request parameters (changing /api/dms/123 to /api/dms/456 where 456 belongs to someone else). It tests for SQL injection in the search field (' OR 1=1; --). It verifies that the Zoom integration OAuth token is stored encrypted in PostgreSQL and never exposed to the frontend. It checks that the Cassandra connection credentials aren't visible in the FastAPI error responses.


13. Compatibility Testing

What it is: Testing the application across different browsers, operating systems, and devices to verify consistent behavior.

DuckBuddy example: The video call feature uses WebRTC for screensharing. Compatibility testing verifies that screenshare works in Chrome, Firefox, and Safari on macOS, in Chrome and Edge on Windows, and in Safari on iOS and Chrome on Android. It turns out that Safari on iOS handles WebRTC screen capture differently than desktop browsers — the screen broadcast picker has a different API. Compatibility testing catches that before a user on an iPad tries to screenshare and gets a blank screen.


14. Usability Testing

What it is: Testing with real users (or simulated real users) to determine how easy and intuitive the application is to use.

DuckBuddy example: A new user signs up and is asked to find a connection using the AI suggestions, send them a DM, and start a video call — without any instructions. Usability testing observes where they hesitate, where they click the wrong thing, where they get confused by the UI. If 8 out of 10 users try to click the user's profile picture to start a video call instead of clicking the "Video Call" button, the button placement needs to be reconsidered.


15. Exploratory Testing

What it is: Simultaneous learning, test design, and test execution — unscripted testing where the tester explores the application freely, following their instincts and curiosity.

DuckBuddy example: There's no formal test case for this. The tester logs in, starts clicking around, and wonders: "What happens if I create a chat room, invite 5 people, then delete the chat room while 3 of them are actively typing messages?" The tester tries it. The room disappears from the list, but the 3 users who were typing see their messages silently fail with no error. That's a bug no test case would have caught — because nobody thought to write a test case for "delete room while users are mid-message." Exploratory testing catches the things you didn't know to look for.


16. Ad Hoc Testing

What it is: Informal, unplanned testing done without documentation or structure — often a quick "let me just try this" check.

DuckBuddy example: A developer mentions offhand that they changed how the Redis cache invalidates when a user updates their profile. There's no formal test case for this yet. The tester quickly logs in, updates their profile bio, refreshes the page, and checks whether the updated bio appears or whether the old cached version still shows. Two minutes. No documentation. Just a quick check to make sure the change didn't break something obvious. If it passes, the tester moves on. If it fails, a formal test case gets written.


17. Black Box Testing

What it is: Testing the application's functionality without knowledge of its internal code structure, implementation, or internal pathways. You test from the outside — input in, output out.

DuckBuddy example: The tester knows nothing about how the AI matching algorithm works internally — they don't know what Neo4j queries are being run, what weight is assigned to each attribute, or how the Python service calculates match scores. They only know: "When I complete my profile with profession = 'Designer,' timezone = 'EST,' and hobbies = 'Photography,' I should get suggestions that include other designers in similar timezones who like photography." They test the observable behavior — the output — not the internal logic.


18. White Box Testing

What it is: Testing with full knowledge of the internal code structure, implementation, and logic — testing the internal pathways, branches, and conditions directly.

DuckBuddy example: The tester reads the Python source code for the AI matching service and sees that it has a branch: if the user has fewer than 10 connections in Neo4j, it uses a "broad match" strategy; if more than 10, it uses a "refined match" strategy. White box testing means writing tests that exercise both branches — creating a test user with 5 connections and verifying broad match behavior, then creating a test user with 15 connections and verifying refined match behavior. You're testing the code's internal logic, not just its external output.


19. Cross-Platform Testing

What it is: Testing the application across different platforms — web, desktop, mobile (iOS and Android), and potentially different app stores or distribution channels.

DuckBuddy example: DuckBuddy has a web application and a mobile-responsive version. Cross-platform testing verifies that a user on the web app can start a video call with a user on mobile, that a chat room created on desktop appears correctly on mobile, that DM notifications are delivered on both platforms, and that the screenshare feature — which works in the browser — degrades gracefully on mobile (where full-screen screenshare may not be supported) by showing a "screenshare not available on mobile" message instead of crashing.


20. Acceptance Testing

What it is: Formal testing conducted to determine whether the system satisfies its acceptance criteria and whether the user (or product owner) accepts the system. The final gate before release.

DuckBuddy example: The product owner wrote acceptance criteria for the new Slack integration: "When a user receives a DM in DuckBuddy and has Slack integration enabled, a Slack alert must appear in their configured Slack channel within 30 seconds. The alert must include the sender's name and a preview of the message. Clicking the alert must open DuckBuddy to that DM." Acceptance testing walks through each criterion exactly as written. Does the alert appear within 30 seconds? Does it include the sender's name? Does clicking it open the right DM? If every criterion passes, the feature is accepted. If any fails, it goes back.


QA Testing vs. Support Testing: Two Completely Different Mental Modes

Now let me contrast all of that with the kind of testing you do in support, because the difference is where the real insight lives — and it's the difference between multifaceted and linear thinking.

When you're in support and a customer reports a bug, your job is to validate that bug. You need to reproduce it. And here's the critical constraint: you only care about the exact steps to replicate the issue based on the same parameters as the customer's account. The customer is on the Basic plan. The customer is using Chrome on Windows. The customer has 12 connections and is in 3 chat rooms. The customer clicked the DM icon, selected a contact, typed a message, hit send, and the message disappeared. That's the report. Your job in support is to reproduce that exact scenario — same plan, same browser, same OS, same number of connections, same steps — and confirm whether the bug is real.

You are not testing what happens if the customer was on the Pro plan instead. You are not testing whether the message disappears in Firefox too. You are not testing whether the DM feature still works when the user has 50 connections instead of 12. You are not testing whether the chat room feature still works after the DM fix. You are not testing whether the notification system still fires when a DM is sent. You are testing one path — the customer's path — to validate one issue. A to B. Linear.

And there's a reason for that. In support, each issue has to be tracked separately. Each customer's bug is its own ticket, its own investigation, its own resolution. You can't merge a bug reported by Customer A with a bug reported by Customer B even if they look similar, because they might have different root causes, different account parameters, different environments. So testing in support is inherently broken up. Split. Each test is its own silo. You open the ticket, you read the customer's steps, you reproduce them, you confirm or deny, you update the ticket, you close it. Next ticket. Next customer. Next set of exact steps. Each one a straight line from report to reproduction.

It doesn't flow the same way QA testing flows. In support, you're not looking at the system. You're looking at one user's experience of one issue at one point in time. And that's important work — it's how you validate customer reports, how you confirm bugs are real before they reach engineering, and how you give the customer an honest answer about whether their issue is reproducible. But it's a different mental mode. It's linear by design. It has to be, because the question you're answering is narrow: "Did this specific thing happen to this specific user under these specific conditions?"

QA testing asks a completely different question: "Does this feature work — and does everything around it still work — across every condition we can think of?"


The Multifaceted Approach: One Thing, Every Angle

In QA, you're not validating one customer's experience. You're validating one feature or one bug fix — but from every possible angle. You're testing holistically. You take the thing you're validating and you turn it, facet by facet, the way you'd turn a gem under a light.

A developer fixes a bug where file uploads in chat rooms were failing when the file was larger than 5 MB. In support, the test would be: reproduce the customer's exact steps, upload a 6 MB file, confirm it fails, apply the fix, upload the 6 MB file again, confirm it succeeds. Linear. Done. Ticket closed.

In QA, that same fix triggers a multifaceted investigation:

  • Does the 6 MB file upload now work? (Functional — the fix itself)
  • Does the 4 MB file that was already working still work? (Regression — did the fix break the working case)
  • Does the file upload work in every chat room, not just the one the customer was in? (Cross-context — is the fix global or did it only patch one room's configuration)
  • Does the file upload work on the DM screen too, which shares the same upload component? (Integration — did the fix affect the shared component)
  • Does the file upload work when two users upload at the same time? (Concurrency — what happens under simultaneous load)
  • Does the file upload work when the user is on mobile and selects a file from their camera roll? (Cross-platform — does the fix hold on a different platform)
  • Does the file upload work when the MongoDB storage is under heavy write load? (Performance — does the storage layer still handle it under stress)
  • Does the file upload still trigger the notification that tells room members a file was shared? (Integration — did the fix accidentally silence the notification path)
  • Does the file upload work when the user's Redis session has expired and they need to re-authenticate mid-upload? (Edge case — what happens when auth state changes during the operation)
  • What happens if the user uploads a file, navigates away from the chat room mid-upload, and then navigates back? (Exploratory — what does the user experience when they interrupt the flow)

One fix. Ten angles. And that's not exhaustive — that's just the first ten that come to mind. A thorough QA tester might find twenty more. The point is that QA testing doesn't ask "did the fix work?" It asks "did the fix work and what else happened?"

That's what I mean by multifaceted. You're not following a line. You're exploring a space. The feature is the center, and you're walking around it in a circle, checking every side, looking for the crack that's only visible from one specific angle. Sometimes the crack is in the feature itself. Sometimes it's in a related feature that shares a component. Sometimes it's in the infrastructure — a Redis connection that times out, a Neo4j query that slows down, a FastAPI endpoint that returns a 500 when the payload is slightly different than expected. The crack could be anywhere in the system, and your job is to look everywhere.

Here's another example. DuckBuddy ships a new feature: users can now pin messages in chat rooms. In support, if a customer reports that a pinned message doesn't show a "pinned" badge, the test is: reproduce their steps, check for the badge, confirm the bug, validate the fix. Linear.

In QA, testing the pinned messages feature means:

  • Pin a message. Does the badge appear? (Functional)
  • Pin a message, then unpin it. Does the badge disappear? (Functional — the reverse path)
  • Pin a message, refresh the page. Is it still pinned? (Persistence — did it save to MongoDB)
  • Pin 10 messages in the same room. Do all 10 badges appear? Does the room scroll correctly? (Boundary — what happens at volume)
  • Pin a message, then delete the message. What happens to the pin? (Edge case — orphaned pin reference)
  • Pin a message in Room A. Does it appear as pinned in Room B? (Cross-context — is pinning scoped correctly)
  • Pin a message, then have another user unpin it. Does the unpin propagate to the first user's view in real time? (Concurrency — WebSocket sync)
  • Pin a message on desktop. Is it pinned when you open the room on mobile? (Cross-platform — does pinning sync across devices)
  • Pin a message in a room with 500 messages. Does the "jump to pinned message" button scroll to the right position? (Performance — scroll positioning under load)
  • Pin a message, then edit it. Does the pinned version show the original text or the edited text? (Edge case — what does "pinned" mean when the content changes)

One feature. Ten facets. And the facets matter because real users will hit every one of them. The customer who reported the bug in support hit one facet. The other 9,999 users of DuckBuddy will hit all the others. QA testing is the act of being every user at once — of walking around the gem and checking every facet before any user gets to it.


Why This Feels Different

Here's why the multifaceted approach is so satisfying, and why it feels fundamentally different from the linear approach of support testing.

When you test linearly, you're following a path someone else already walked. The customer walked it. They told you the steps. You walk the same steps. You either arrive at the same destination (the bug reproduces) or you don't (it doesn't). The path is known. The outcome is binary. It's confirmation work — important, necessary, but fundamentally a verification of something that's already been observed.

When you test multifacetedly, you're exploring a space that nobody has mapped yet. There is no path. There is no customer who already walked it and told you the steps. You're the first person to ask: "What happens when you pin a message and then edit it?" You're the first person to ask: "Does the file upload still work in DMs after the chat room fix?" You're the first person to walk around to that specific facet of the gem and hold it up to the light.

And when you find a crack — when the pinned message does break after editing, when the file upload in DMs does fail after the chat room fix — you've found something that no customer has reported yet, because no customer has gotten there yet. You found it first. You caught it before it left the building. And because you were testing multifacetedly — because you were looking at the whole space, not just one line — you found a crack that linear testing would have missed entirely.

That feeling — the feeling of standing at an angle nobody else has stood at, looking at a facet nobody else has checked, and finding the crack that would have reached a customer if you hadn't been there — that's the feeling that makes me love QA testing. It's not a checkbox. It's not a line. It's a discovery. Every test is a new angle. Every angle is a new possibility. And every crack you find is a problem a customer will never have to experience.


Bottom Line

Linear thinking has its place. In support, it's exactly what you need: reproduce the customer's exact steps, validate their specific issue, track it individually, close the ticket. The constraint is real — each issue must be tracked separately, each reproduction must match the customer's parameters, and the scope is deliberately narrow because the question being asked is narrow: "Is this specific thing broken for this specific user?"

QA testing lives in a different world entirely. The question isn't "is this specific thing broken?" The question is "is this feature solid — from every angle, in every context, under every condition I can think of — and did fixing it leave everything around it intact?" You're not following a line. You're mapping a space. You're walking around a gem, facet by facet, looking for cracks from angles that nobody else has checked. You're trying different combinations, testing related features, verifying that the file upload works on every page that has one, not just the page where the bug was reported.

The reason I love QA testing is the reason some people love research, or detective work, or exploration. It's the pleasure of multifaceted thinking — of holding one thing in your mind and examining it from twenty different perspectives, of seeing connections between features that share a component, of anticipating the edge case that no one has thought of yet, of being the person who walks around to the back of the gem and finds the crack that was hidden from every other angle.

Support testing tells you whether a specific path is broken. QA testing tells you whether the entire structure is sound. And the structure is always more complex, more interconnected, and more surprising than any single path would suggest. That's why there are twenty testing methods. That's why you test in context. That's why you don't just check the fix — you check everything the fix touches, and everything that touches those things, and everything that touches those things, until you're satisfied that the gem has no cracks from any angle you can reach.

That's QA testing. Not linear. Multifaceted. Not a line. A space. And exploring that space with methodically, creatively, with curiosity alongside an agent is the most satisfying work I know of currently!

Support asks: "Did the customer's exact steps reproduce the bug?" QA asks: "What else broke when we fixed it?" That difference — between linear and multifaceted thinking — is why I love this job.

Read more