•
Drizz raises $2.7M in seed funding •
•
Featured on Forbes
•
Drizz raises $2.7M in seed funding •
•
Featured on Forbes

Takeaways:
Microservices testing is hard because failure modes are different from monoliths. Code can be correct and system still breaks: a renamed API field, a timeout under load, a deploy that rolls out before its consumer updates. Traditional UI-down QA doesn't catch these fast enough.
Toby Clemson's microservice testing taxonomy on martinfowler.com breaks testing microservices into five layers. Each layer catches different defects at different speeds and costs. Stack them wrong and you either miss bugs or grind your pipeline to a halt.
Scope: single function or class within one service. No network, no database, no external calls.
Run time: milliseconds. You want thousands of these. They catch logic errors, edge cases, and regressions moment code changes. Every service should have its own unit test suite that runs on every commit.
Tools: JUnit (Java), pytest (Python), Jest (JavaScript), XCTest (Swift), JUnit5 with Kotest (Kotlin).
Scope: one service in isolation, with its dependencies mocked or stubbed. The test hits service's actual API, but everything downstream is faked.
This is where you validate that a single service behaves according to its specification:
Tools: Spring Boot Test with WireMock (Java), Testcontainers, SuperTest (Node.js), FastAPI TestClient (Python).
Scope: agreement between a consumer service and a provider service. When service A expects a response shaped like {price: number} and service B starts returning {unit_price: number}, a contract test breaks before anything reaches staging.
This is most underused layer in microservices testing. Teams skip it because it requires both sides (consumer and provider) to participate. But as Inbank engineering team documented, contract testing is what prevents majority of integration failures in a microservices architecture.
Pact is standard tool. It works by having consumer define what it expects (a "pact"), and provider verifies that it can fulfill that pact. When either side drifts, test fails before deploy.
Tools: Pact (multi-language), Spring Cloud Contract (Java/Spring), Specmatic.
Scope: how two or more services interact over real network calls, with real databases and real message queues. Slower and more expensive than contract tests, but they catch problems that mocks can't simulate:
Keep these focused. Test specific interactions, not entire workflows. "Does order service correctly publish an event to payment queue and receive confirmation callback?" is a good integration test. "Does entire checkout flow work across seven services?" is an E2E test disguised as an integration test.
Tools: Testcontainers (spin up real Postgres, Redis, Kafka in Docker), Docker Compose, WireMock for external dependencies.
Scope: whole system, from client UI through gateway and into backend services. These are slowest and most fragile tests in your suite, and they should be smallest layer.
The 5-10% rule is a good guide. If your suite has 1,000 tests, no more than 50-100 should be E2E. Reserve them for flows that directly affect revenue or access:
Everything else should be covered by layers below.
E2E tests are expensive because they depend on every service being up and healthy in test environment. One slow service or one flaky dependency and entire suite turns red. That fragility is why you want minimum viable set of E2E tests, not comprehensive coverage at this layer.
All five layers above focus on backend. But if your product is a mobile app, there's a layer that sits on top: client-side experience on a real device.
Backend E2E tests confirm that APIs return correct data. They don't confirm that:
Mobile E2E testing is a separate concern from backend E2E testing. Mixing them creates a test that's slow, flaky, and hard to debug because failures could originate anywhere in stack. The better approach:
For teams with automated regression testing suites that span both backend and mobile, separating these layers cuts debug time in half. When a mobile test fails, you already know backend is healthy because that layer has its own tests.
Drizz sits at mobile E2E layer. It tests what user sees and does on a real Android or iOS device, without depending on backend test infrastructure beyond a stable API environment.
A test for a microservices-backed checkout flow:
Tap on "Add to Cart"
Scroll down until "Proceed to Checkout"
Validate cart total matches product price
Type "4111111111111111" in "Card Number"
Tap on "Place Order"
Validate "Order Confirmed" is visible
Validate order ID starts with "ORD-"
Each validation confirms that backend services returned correct data and mobile client rendered it properly:
If payment service changes its response format and mobile app shows a blank confirmation screen, this test catches it.
Drizz uses Vision AI to find elements on screen, so these tests don't break when developers refactor UI layout. The payment form can move, button can change color, font can change size. As long as words "Place Order" are visible, Drizz taps them.
For microservices teams deploying multiple times per day, Drizz Cloud runs test plans in parallel across real devices. A 50-test mobile regression suite can execute across five device configurations simultaneously, giving results in minutes instead of hours. That speed matters when services deploy independently and any deploy could affect mobile experience.
The weight should sit at bottom. Every layer you push a test down saves execution time and makes failures easier to isolate. When a contract test catches a schema drift in 2 seconds, that's a bug your E2E suite never needs to spend 5 minutes finding.
Use a layered approach: unit, component, contract, integration, and E2E. Weight most tests toward faster, cheaper layers.
Pact for contracts, Testcontainers for integration, WireMock for service stubs, JUnit/pytest/Jest for units, Drizz for mobile E2E.
They depend on every service being up and healthy. One slow or broken dependency fails entire suite, creating noise.
Consumer-defined expectations verified against provider. Catches schema drift between services before deploy, without running full stack.
Yes. Separating them makes failures easier to debug and prevents mobile tests from breaking due to backend environment instability.
Five to ten percent of total tests. Reserve E2E for revenue-critical flows and push everything else to lower layers.