Principles of Writing Automated Tests

While working on test automation in different projects, I’ve learned that there are not enough static analyzers and code formatters for writing good tests. The team had to have an agreement on how the tests should be written.

Principles of Writing Automated Tests

1. No tests without assertions

test("Should open menu", async () => {
await page.locator('.button').click();
});
test("Should open menu", async () => {
await page.locator('.button').click();
const locator = await page.locator('.dropdown-menu');
await expect(locator).toBeVisible();
});

2. No assertions in before or after hooks

3. No actions without expectations

test("Should open menu", async () => {
await page.locator('.button').click();
await page.locator('.dropdown-menu').waitFor({ state: 'visible' });
});
test("Should open menu", async () => {
await page.locator('.button').click();
const locator = await page.locator('.dropdown-menu');
await expect(locator).toBeVisible();
});

4. No unconditional expectation

it('Should open menu', async () => {
const button = await $('.button');
await button.click();
await browser.pause(3000);
const menu = await $('.dropdown-menu');
await menu.isDisplayedInViewport();
});
it('Should open menu', async () => {
const button = await $('.button');
await button.click();
const menu = await $('.dropdown-menu');
await menu.waitForExist({timeout: 3000});
await menu.isDisplayedInViewport();
});

5. No commented test

// test("Should have a menu", async () => {
// const locator = await page.locator('.dropdown-menu');
// await expect(locator).toBeVisible();
// });
test.skip("Should have a menu", async () => {
const locator = await page.locator('.dropdown-menu');
await expect(locator).toBeVisible();
});

6. No hanging locators

test("Should do something", async () => {
await page.locator('.button');

7. One expect for each test step

8. Do not put await inside expect

test("Should have title on the button", async () => {
expect(await page.locator('.button')).toHaveText(/Menu/);
});
test("Should have title on the button", async () => {
const button = await page.locator('.button');
expect(button).toHaveText(/Menu/);
});

9. Do not reload the page, reopen it

test("Should have something after reload", async () => {
await page.reload();

});
test("Should have something after reload", async () => {
const uri = await page.url();
await page.goto(uri);

});

10. Do not check URLs through includes

test("Should have corresponding URL", async () => {
const uri = await page.url();
await expect(uri.includes('example')).toBeTruthy();
});
test("Should have corresponding URL", async () => {
const uri = await page.url();
await expect(uri).toHaveURL(/example/);
});
test("Should have corresponding URL", async () => {
const uri = await page.url();
await expect(uri).toEqual(expect.stringContaining('example'));
});

11. Avoid regexp in checks

12. Wrap clicks and expectations into a promise

await page.locator('.button').click();
const response = await page.waitForResponse('https://example.com/');
await expect(response.ok()).toBe(true);
const [response] = await Promise.all([
page.waitForResponse('https://example.com/'),
page.locator('.button').click(),
]);
await expect(response.ok()).toBe(true);

13. Do not use global variables for page object methods

const myPageObject = new MyPageObject(page);test('Should do something', async () => {
await myPageObject.doSomething();

});
test('Should have something', async () => {
await myPageObject.haveSomething();

});
test('Should do something', async () => {
const myPageObject = new MyPageObject(page);
await myPageObject.doSomething();

});
test('Should have something', async () => {
const myPageObject = new MyPageObject(page);
await myPageObject.haveSomething();

});

14. Do not scatter test cases

15. Do not mix different kind of tests

16. Use linters and formatters from the testing project

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Andrey Enin

Andrey Enin

199 Followers

Quality assurance engineer: I test complex web applications and APIs, and do automation testing.