I'm always excited to take on new projects and collaborate with innovative minds.

Website

Nsour

Address

Russia, Smolensk

Social Links

Web Development

Unit Testing vs Manual Testing vs External Automation — What I Learned Building SmartCardJo

When your system handles money, “it works” isn’t enough. In this article, I break down the three layers of testing — manual, unit, and external — that I use to keep SmartCardJo’s APIs stable and secure. Real lessons from real production code, and why every serious developer needs testing discipline before writing a single line of business logic.

Every serious developer eventually reaches a point where “it works” isn’t good enough.
When your code handles money, orders, or thousands of users — you stop hoping it works and start proving it does.

That’s where testing becomes the backbone of your architecture.


🧪 1. Manual Testing — The Beginner’s Comfort Zone

Manual testing is how everyone starts:

  • You run your routes in Postman.

  • You click through your app after every change.

  • You say “yeah, it seems fine.”

And it works… until it doesn’t.

Manual testing is slow, inconsistent, and emotional — you test what you remember, not what’s critical.
When you change code in 10 different files, manual testing misses the one scenario that actually breaks production.

That’s how bugs survive.


🧱 2. Unit Testing — The Developer’s Shield

In Laravel, PHP, and any modern framework, unit testing means writing small, isolated tests that confirm each piece of logic works exactly as expected.

Example:

 
public function test_user_cannot_login_with_invalid_signature() {    $response = $this->postJson('/external-buyers-api/login-external-buyer', [        'email' => 'fake@smartcardjo.com',        'timestamp' => time(),        'signature' => 'invalid'    ]);    $response->assertStatus(401)             ->assertJson(['message' => 'Invalid signature']); }

This one test confirms that your signature verification logic never allows unauthorized access — not today, not after refactoring, not ever.

Why Unit Tests Matter

  • ✅ They catch logical regressions before they hit production.

  • ✅ They run instantly, even on CI/CD pipelines.

  • ✅ They guarantee consistent behavior across environments.

  • ✅ They make refactoring safe instead of terrifying.

For me, SmartCardJo’s API logic — timestamps, signatures, and security — all belong here.
This is where PHPUnit shines.


⚡ 3. When Unit Tests Aren’t Enough

Here’s the catch — unit tests stop at the framework boundary.

They’re perfect for:

  • Validating your controllers, models, services.

  • Confirming middleware logic.

  • Checking calculations and rules.

But they don’t cover real network behavior.
Things like:

  • SSL/TLS issues

  • Server routing

  • Load balancer redirects

  • Real external latency

That’s where external testing tools like Python scripts, Postman collections, or integration CI jobs step in.


🧠 4. External Testing — The Production Watchdog

For external APIs, you sometimes need a test outside your application — something that behaves like a real client.

That’s where I used a small Python requests-based tester — not to replace PHPUnit, but to simulate how third-party systems will use our API in the real world.

It validates:

  • Timestamp/signature integrity

  • Header-based authentication

  • Real HTTPS responses

  • End-to-end flow through load balancer and Nginx

It’s like a “health probe” for your live API.
If a developer accidentally changes a route prefix, adds middleware, or misconfigures SSL — unit tests won’t notice, but your Python test will.


🧩 5. The Balance Between the Three

TypePurposeBest ForEnvironment
Manual TestingQuick visual checksUI, small fixesLocal/dev
Unit TestingLogic verificationControllers, models, security rulesCI/CD & local
External TestingReal-world validationProduction APIs, uptime, integrationsStaging/production

They complement each other.
You don’t pick one — you build all three layers and assign each the right job.


🔐 6. How I Do It on SmartCardJo

  • PHPUnit handles all internal logic: user creation, authentication, wallet deduction, transaction logging.

  • Manual testing validates new UI workflows or quick changes in admin panel.

  • Python external tests verify that external buyers (third-party clients) can securely connect, authenticate, and query data — without touching live wallet data.

The result: a fully covered, production-safe ecosystem that catches bugs before users do.


💬 Final Thought

Testing isn’t about writing “extra code.”
It’s about writing proof — proof that your system behaves the way you promised.

If you’re serious about stability, you need:

  • Unit tests to protect logic.

  • External automation to protect behavior.

  • Discipline to actually run them.

I learned this the hard way.
Now, I don’t ship without tests — not because I’m paranoid, but because I love sleeping through the night.


 

4 min read
Nov 11, 2025
By Wared Nsour
Share

Leave a comment

Your email address will not be published. Required fields are marked *

Related posts

Dec 08, 2025 • 3 min read
The Night Flutter and CocoaPods Declared War: How One iOS Build Broke 40+ Plugins — And How I Finally Fixed It

A real-world debugging story of how a Flutter iOS build suddenly colla...

Your experience on this site will be improved by allowing cookies. Cookie Policy