DEV Community

Cover image for I followed Keploy's quickstart as a first-time user. Here's where it broke.
VidhiDixit2000
VidhiDixit2000

Posted on

I followed Keploy's quickstart as a first-time user. Here's where it broke.

A couple of months ago I came across a product called Keploy on LinkedIn. I went to their site to read about it, and the pitch stopped me: it writes your integration tests for you by watching your app run.
I went like --

impressive image gif

And it did that by Not generating them from your code. Watching actual traffic. You run your app, use it normally, and Keploy records what came in and what went out. Later it replays those requests against your app and checks it still responds the same way.

I wanted to see whether that held up,
curious/mischevious image gif
so I ran one of their Go quickstarts end to end on Windows through WSL. This is what it was like.

How it works

Integration tests usually mean keeping a database alive, writing mocks by hand, and updating those mocks every time a schema changes. It's a lot of upkeep for tests that mostly verify things you already know work.

Keploy's approach is to record once and replay forever. It supports several languages — I used one of their Go quickstarts because that's what I wanted to try.

When you start a recording, Keploy moves your app to another port and takes the original one for itself, so every request passes through it. At the same time, an eBPF probe watches the syscalls your app makes to the database.

hide and seek image gif

RECORD
  your curl  ->  Keploy (:8082)  ->  app (:35555)  ->  Postgres
                      |                                   |
                  test case                             mock

REPLAY
  Keploy  ->  replays recorded request  ->  app  -X-  Postgres
                                             |
                                     answered from mocks
Enter fullscreen mode Exit fullscreen mode

So one recording run captures two things: the HTTP exchange becomes a test case, and the database exchange becomes a mock.

On replay, your app starts and runs for real — your router matches the path, your handler executes, your code does its work. Only the database calls are faked, answered from the recording. Postgres never gets touched.

Because the probe sits outside your code rather than inside it, you don't import a library or change a line of your app. That's also why Keploy needs sudo, and why it only runs on Linux — hence WSL on Windows.

What I built

Their quickstart docs offer several Go samples. I picked Echo + Postgres — a URL shortener.

The setup is: install the CLI, start Postgres in Docker, build the app, and run it under keploy record. Then you just use the API. I made two curl calls — a POST creating a short URL, and a GET following it. Both became test cases, written to keploy/test-set-1/, with the Postgres exchanges saved alongside them as mocks.

A few small things didn't match as I went. The docs site, its screenshots, and the binary I installed were on three different versions. The README pointed at a line number that had moved — and the quickstart pointed at a different wrong one. A flag the docs use had been removed. The quickstart skips a login step that everything after it depends on, so the first failure is a 401 timeout that never mentions authentication. None of these are dramatic on their own, but following instructions literally means hitting each one and stopping to work out why.

Then I hit a real one.
sad and shocked gif

What I'd fixed first, and what actually broke

I ran the test command straight from the docs. Keploy started my app, and then the run died.

The errors talked about the app being unreachable and the database connection failing. So I went looking at Postgres, at ports, at the binary — all of it fine.

The real cause was a folder I'd never opened. The sample repo ships with a test-set-0 already committed, recorded by someone else a long time ago. My own recording had created test-set-1. Without naming a test set, Keploy picked up both and started with theirs.

Its mocks were in an older format that the current version can't read — eighteen failed to unmarshal errors. With no mocks loaded, nothing answered my app's startup database ping, so the app exited. And with the app gone, the whole run collapsed. My two tests were never reached, let alone run.

--test-sets test-set-1
Enter fullscreen mode Exit fullscreen mode

One flag, and it skips theirs entirely.

Then a smaller oddity: with that flag everything passed, but the summary still reported "across 2 test-set(s)" and threw a red error about a missing report for test-set-0 — a set that never ran. The filter controls which tests execute, but not what gets counted.

What convinced me

here you go image gif

COMPLETE TESTRUN SUMMARY.
      Total tests: 2
      Total test passed: 2
      Total test failed: 0
      Total time taken: "10.09 s"
Enter fullscreen mode Exit fullscreen mode

And higher up in the log:

{"testsRan": 2, "mocksConsumed": 4}
Enter fullscreen mode Exit fullscreen mode

Four mocks consumed. My app pinged the database, created its table, and ran both queries — and Postgres answered none of it. Every one of those calls came from the recording.

That's the whole idea in a single line. Real code running, real database work happening, no database.

Where it fits

Keploy is most useful when you already have a working service and want regression coverage without maintaining a pile of database mocks by hand. The recorded traffic gives you a practical starting point — but it doesn't replace deliberately testing paths you haven't exercised. If you never send a request through a particular part of your app, Keploy can't record a test for it.

here you go image gif
I wrote up the full walkthrough here — every version mismatch and workaround, in the order you'll hit them. If you're going down the same path, it should save you some time.

Top comments (0)