Why API testing with Selenium comes up at all

Three reasons, and only one of them is good.

  • The suite already exists. There is a Selenium job in CI, people know how to run it, and adding API checks there is the path of least resistance. Understandable, and it is an organizational reason rather than a technical one.

  • The flow spans both. Submit a form, then confirm the record the API created is correct. This one is legitimate and is the case worth designing for.

  • Setup and teardown. Creating fixtures through the API because doing it through the interface is slow. Sensible, though it is plumbing rather than testing.

What it costs

Slow feedbackBrowser startup dominates a check that could have been a request. A suite that takes twenty minutes gets run less often, which is the real loss.
Muddled failuresWhen a combined test fails you have to work out whether the interface or the API broke. Separate suites give you that answer for free.
Coverage shaped by the UIYou end up covering the endpoints the interface happens to call, which is a fraction of the surface. Error codes and edge parameters never get exercised.

The division that works

Keep Selenium for what only a browser can answer: does the user-visible flow work. Cover the API at its own level, where a check is a request rather than a page load. Use the API from the Selenium suite only for setup and teardown, where speed is the point and no assertion is involved.

The one genuinely cross-cutting case, submit a form and verify what the backend stored, is worth writing deliberately rather than by accident. It is a small number of tests and they earn their cost.

What a standalone API layer needs to handle

Four things decide whether an API suite survives its first year, whichever tool you use: sessions that expire, values that only exist at runtime, calls that depend on each other, and records nobody cleans up. TestSprite names these Auto-Authentication, Dynamic Variables, Dependency Chains and Auto-Cleanup, and the API testing documentation covers the mechanics.

Getting these four right is what separates a suite that lasts from one that is deleted after two quarters, and it is much easier to do at the API level than bolted onto a browser suite.

The setup case, done properly

Using the API to create fixtures for a browser test is the one place these two genuinely belong together, and it is worth doing deliberately rather than by accident.

The rule that keeps it clean is that setup calls never assert. Their job is to put the system into a known state as fast as possible, and if one fails the test should error out rather than fail, because a failed fixture is an infrastructure problem and not a product defect. Conflating the two produces a suite where half the red is noise.

The second rule is that whatever setup created, teardown removes, tied to that test rather than matched by name. Browser suites accumulate data faster than anyone expects, and a list view that gets slower every week is usually a teardown that was never written.

Running both

Neither suite needs to know about the other. Selenium runs in your CI job as it does today, and API coverage runs alongside it.

If the pipeline belongs to another team, the GitHub App is the path of least resistance: it is a webhook, it changes nothing in your repository, and it fires when your build reports the new version live. If you want the check visible in the repo instead, a GitHub Actions step does that. See the CLI repository.

What TestSprite covers at the API level

TestSprite handles the standalone API layer so you do not have to bolt it onto a browser suite. API Discovery enumerates what the running service exposes, plan generation proposes cases across functional, schema, authorization, error-handling and boundary categories, and you refine them in plain language.

The four state problems come as product rather than as your infrastructure: Auto-Authentication keeps sessions alive, Dynamic Variables carry values between calls, Dependency Chains derive execution order, Auto-Cleanup removes what a run created. Those are the things that make an API suite hard to keep alive, and they are much easier to solve at the API level than inside a browser runner.

Your Selenium suite stays where it is, covering what only a browser can answer. Both run from the same pipeline.

Can Selenium send HTTP requests directly?

Through the language bindings, yes, because you are just writing code. The question is whether a browser session should be involved at all, and for a pure API check the answer is usually no.

Should we migrate our Selenium suite?

Not wholesale. A Selenium suite people trust is an asset. Add API coverage at its own level rather than moving anything.

How do we test a flow that spans both?

Write it as one test deliberately, keep the number small, and make the assertion specific enough that a failure tells you which side broke.

Is Playwright better for this?

It has a first-class request API, so the mechanics are nicer. The architectural argument is unchanged: browser checks and API checks answer different questions and are better kept separate.

What about authentication across both?

Share the credential source, not the session. Each layer should obtain its own session so a failure in one does not cascade into the other.

The short version

Use the browser for browser questions.

API testing with Selenium usually means coordinating two kinds of check rather than forcing one tool to do both. Keep Selenium for user-visible flows, cover the API at its own level, and write the genuinely cross-cutting tests on purpose.