Hello everyone!
I always looked skeptically at test automation frameworks with a dual purpose - UI & API test coverage. Usually, you will run different layers of tests in different test runs (or event projects), as each of them probably has its own
Recently, I took a look at what Playwright has to offer in terms of API testing and compared it with my Cypress experience, so here’s what I’ve got to share with y’all…
Cypress made API testing possible a while ago. You can find an article on the learn portal about how great this tool is in terms of API testing with examples.
In order to run tests, you need to install your project dependencies, correct? Well, Cypress comes with an electron browser, and it might be quite redundant (and time-consuming) to install if you want to run API tests exclusively (let’s say, you’ve got separate jobs in CI for UI & API test runs, which is usually the case).
Doesn’t look good, huh? ☝️
Also, when you run API tests - it launches a browser anyway.
A simple API test with Cypress would look like this:
it('Sign in with valid credentials', () => {
cy.request('POST', '/auth', {
login: Cypress.env('username'),
password: Cypress.env('password'),
}).should(response => {
expect(response.body.token).to.be.a('string')
expect(response.status).to.eq(200)
})
})
Looks pretty simple and straightforward, huh? It’s important to say here that it’s a common Cypress syntax - i.e. chaining stuff, instead of writing every output into variable (even though it’s possible with some tweaks).
Just like Cypress, Playwright is a test automation framework - you can use just a browser automation tool exclusively, or the whole framework (test runner, assertion library, browser automation tool, HTTP client, reporter, etc).
The difference here is that Playwright doesn’t come with any browsers out of the box - you have to install them with a separate command (if you want to).
It makes a huge difference here, as in terms of running API tests exclusively, it won’t run any browser or any other desktop app and save some run time & resources on your machine.
A simple API test with Playwright would look like this:
import {test, expect} from '@playwright/test'
test('Sign in with valid credentials', async ({request}) => {
const response = await request.post('/auth', {
data: {
login: process.env.USERNAME,
password: process.env.PASSWORD,
},
})
expect(response.status()).toEqual(200)
expect(await response.json()).toEqual({
token: expect.any(String),
})
})
I’d like to highlight a Jest-like syntax of asserting objects:
expect(await response.json()).toEqual({
token: expect.any(String),
})
This syntax allows you to verify the whole structure of the object with just a single expect
call ☝️
API tests are supposed to be small & lightweight as they don’t require too much to run.
Let’s sum up the material above…
✅ Playwright wins with 13x faster clean installation out of a box.
ℹ️ You can reduce Cypress installation time in CI if use an image with pre-installed dependencies or cache them in your CI storage.
✅ Playwright wins as it doesn’t require a browser to run API tests, so it goes straight to the point.
ℹ️ There’s no way to “not to run” the browser in API tests, as it’s part of the framework’s logic.
Can’t pick a winner here, as there’s no objective advantage for neither Cypress nor Playwright.
They both got pretty straightforward syntax with slight differences. I’d say it’s the tester’s decision to pick what they like here.
I can definitely say that it’s safe enough to use Playwright for API test automation due to its performance. It’d be a fair solution if you’ve already got UI tests with this framework.
My advice for those who use Cypress for UI tests and want to cover the API layer - better use something else (Jest + Axios, you can see an example there).