Review checklist for AI-generated tests
An AI assistant writes a Playwright test in a few seconds. The test compiles, runs, goes green… and sometimes checks very little. This 7-point checklist is for reviewing a generated test the way you would review a colleague's code, before merging it. Free, printable, no sign-up.
It complements our guide Playwright MCP: testing with AI, which shows how an assistant explores a page and then generates a test. For an overview, see AI in software testing.
The 7 points of the checklist
1. The assertion checks a business result
Why: AI readily checks what it has just done (a click happened, a page loaded), not what the business expects. A test without a real assertion passes even when the feature is broken.
Beforeawait page.getByRole('button', { name: 'Place order' }).click();
await expect(page).toHaveURL(/\/order/);
After
await page.getByRole('button', { name: 'Place order' }).click();
await expect(page.getByRole('heading', { name: 'Order confirmed' })).toBeVisible();
await expect(page.getByTestId('order-total')).toHaveText('49.90 €');
Question to ask: if the feature returned a wrong result, would this test fail?
2. Accessible locators, not fragile CSS
Why: a selector based on the HTML structure breaks at the first redesign. Locators by role, label or test id describe what the user sees and survive layout changes.
Beforeawait page.locator('div.form > div:nth-child(2) > input').fill('lea@example.com');
await page.locator('//button[contains(@class,"btn-primary")]').click();
After
await page.getByLabel('Email address').fill('lea@example.com');
await page.getByRole('button', { name: 'Sign in' }).click();
Question to ask: would the test break if a developer simply added a tag around the form?
3. Dedicated test data, recreated on every run
Why: during exploration, AI reuses whatever it finds on the page: an existing account, an order already created. The test then depends on a state that will change, and it fails at random or in a cascade.
Before// account found during exploration, shared by all tests
await page.getByLabel('Email address').fill('john.smith@example.com');
After
test.beforeEach(async ({ request }) => {
// account created through the API before each test, specific to this test
const res = await request.post('/api/test/users', {
data: { email: `test-${Date.now()}@example.com` },
});
expect(res.ok()).toBeTruthy();
});
Question to ask: would this test still pass if it ran on its own, or in parallel with the others?
4. Secrets stay out of the prompt and the code
Why: a password written in the prompt stays in the assistant's history; written in the code, it ends up in the Git repository. For exploration, Playwright MCP accepts a secrets file in dotenv format (the --secrets option); for tests, read environment variables.
await page.getByLabel('Password').fill('Password123!');
After
await page.getByLabel('Password').fill(process.env.TEST_USER_PASSWORD!);
Question to ask: what would a stranger see if they read this file, or the conversation history with the assistant?
5. Never on production
Why: an assistant that clicks on its own can submit a form, delete data or trigger a payment. Exploration and tests run on a test environment, with an isolated browser profile (the --isolated option of Playwright MCP) rather than a real session.
// playwright.config.ts
use: { baseURL: 'https://www.my-site.com' },
After
// playwright.config.ts
use: { baseURL: process.env.BASE_URL ?? 'http://localhost:3000' },
Question to ask: which URL did the assistant actually work on, and with which account?
6. Exploration limited to one journey
Why: every page snapshot and every tool description takes up the model's context. A vague instruction ("test the whole site") is expensive in tokens and produces superficial tests. A precise instruction, one journey at a time, gives better tests.
BeforeTest the application and write all the necessary tests.
After
Open http://localhost:3000/login. Describe the fields and the messages.
Try an incorrect password and report the exact message.
Do not open any other page and do not submit any other form.
Question to ask: did the instruction given to the assistant fit in one journey, with an expected result?
7. The test has failed at least once, on purpose
Why: a test that has never been seen failing proves nothing. Deliberately breaking the feature (or the assertion) once lets you check that it really detects a regression, then put everything back.
Before// generated test, run once, green: merged as is
After
// one-off check: we falsify the expected result…
await expect(page.getByTestId('order-total')).toHaveText('0.00 €');
// …the test must fail; then restore the correct value.
Question to ask: have I seen this test go red at least once, for the right reason?
The 5 defects to spot first
- Fragile selectors: CSS or XPath based on the page structure instead of
getByRole,getByLabelorgetByTestId. - Empty assertions: the test checks that an action took place, not its result.
- Fixed waits:
page.waitForTimeout(3000)instead of an assertion that retries, such asawait expect(locator).toBeVisible(). - Hard-coded data: accounts, identifiers and amounts copied from the exploration and shared between tests.
- Happy path only: no error case, empty field or boundary value.
How to use this checklist
- Print the PDF or keep this page open during the pull request review.
- Go through the 7 points for every generated test, not just the first one.
- An unticked point blocks the merge: fix the test, or note why the point does not apply.
- Add the checklist to your definition of "done" for any test written with an assistant.
To design the test cases themselves before automating them, start from a test acceptance book (FR): expected results written before execution, fixed data, clear statuses.
Frequently asked questions
Why review an AI-generated test if it passes?
Because a passing test is not necessarily a good test. An assistant often checks that an action took place rather than the result the business expects, and uses fragile selectors or shared data. The review makes sure the test really detects a regression.
Does this checklist work with Copilot, Claude Code or Cursor?
Yes. It applies to the test that was produced, not to the tool that wrote it: it works whichever assistant you use, and for hand-written tests too.
Are the examples specific to Playwright?
The code examples use Playwright and TypeScript, but the 7 points apply to Cypress, Selenium or any other tool: business result verified, robust locators, isolated data, protected secrets, test environment, precise instruction, test seen failing.
Can I use this checklist with my team or in a course?
Yes, it is free. You can print it and share it, citing the source: AutomationDataCamp, automationdatacamp.com/en/ai-test-review-checklist.
Learn to write the tests AI cannot design
To review a generated test, you need to know what a good test looks like. Start with our free Playwright mini-course (FR), then the certified Playwright training (FR): locators, assertions, test data, API tests, CI and AI applied to testing.
Complete guide to the tool: Playwright guide.
Checklist written by the ADC team with the help of AI; Playwright MCP options checked against its official documentation.