Merge pull request #27301 from woocommerce/update/writing-e2e-tests-readme
Add guide for writing e2e tests in README
This commit is contained in:
commit
ad1e5a180f
|
@ -21,7 +21,11 @@ Automated end-to-end tests for WooCommerce.
|
|||
- [How to run an individual test](#how-to-run-an-individual-test)
|
||||
- [How to skip tests](#how-to-skip-tests)
|
||||
- [How to run tests using custom WordPress, PHP and MariaDB versions](#how-to-run-tests-using-custom-wordpress,-php-and-mariadb-versions)
|
||||
- [Writing tests](#writing-tests)
|
||||
- [Guide for writing e2e tests](#guide-for-writing-e2e-tests)
|
||||
- [Tools for writing tests](#tools-for-writing-tests)
|
||||
- [Creating test structure](#creating-test-structure)
|
||||
- [Writing the test](#writing-the-test)
|
||||
- [Best practices](#best-practices)
|
||||
- [Debugging tests](#debugging-tests)
|
||||
|
||||
## Pre-requisites
|
||||
|
@ -248,7 +252,9 @@ The full command to build the site will look as follows:
|
|||
TRAVIS_MARIADB_VERSION=10.5.3 TRAVIS_PHP_VERSION=7.4.5 WP_VERSION=5.4.1 npm run docker:up
|
||||
```
|
||||
|
||||
## Writing tests
|
||||
## Guide for writing e2e tests
|
||||
|
||||
### Tools for writing tests
|
||||
|
||||
We use the following tools to write e2e tests:
|
||||
|
||||
|
@ -256,12 +262,92 @@ We use the following tools to write e2e tests:
|
|||
- [jest-puppeteer](https://github.com/smooth-code/jest-puppeteer) – provides all required configuration to run tests using Puppeteer
|
||||
- [expect-puppeteer](https://github.com/smooth-code/jest-puppeteer/tree/master/packages/expect-puppeteer) – assertion library for Puppeteer
|
||||
|
||||
Tests are kept in `tests/e2e/specs` folder.
|
||||
In the WooCommerce Core repository the tests are kept in `tests/e2e/core-tests/specs/` folder. However, if you are writing tests in your own project using WooCommerce Core e2e packages, the tests should be located in `tests/e2e/specs/` folder.
|
||||
|
||||
The following packages are used to write tests:
|
||||
|
||||
- `@wordpress/e2e-test-utils` - End-To-End (E2E) test utils for WordPress. You can find the full list of utils [here](https://github.com/WordPress/gutenberg/tree/master/packages/e2e-test-utils);
|
||||
- `@automattic/puppeteer-utils` - Utilities and configuration for running puppeteer against WordPress. See details in the [package's repository](https://github.com/Automattic/puppeteer-utils).
|
||||
- `@automattic/puppeteer-utils` - utilities and configuration for running puppeteer against WordPress. See details in the [package's repository](https://github.com/Automattic/puppeteer-utils).
|
||||
- `@woocommerce/e2e-utils` - this package contains utilities to simplify writing e2e tests specific to WooCommmerce. See details in the [package's repository](https://github.com/woocommerce/woocommerce/tree/master/tests/e2e/utils).
|
||||
|
||||
### Creating test structure
|
||||
|
||||
It is a good practice to start working on the test by identifying what needs to be tested on the higher and lower levels. For example, if you are writing a test to verify that merchant can create virtual product, the overview of the test will be as follows:
|
||||
|
||||
- Merchant can create virtual product
|
||||
- Merchant can log in
|
||||
- Merchant can create virtual product
|
||||
- Merchant can verify that virtual product was created
|
||||
|
||||
Once you identify the structure of the test, you can move on to writing it.
|
||||
|
||||
### Writing the test
|
||||
|
||||
The structure of the test serves as a skeleton for the test itself. You can turn it into a test by using `describe()` and `it()` methods of Jest:
|
||||
|
||||
- [`describe()`](https://jestjs.io/docs/en/api#describename-fn) - creates a block that groups together several related tests;
|
||||
- [`it()`](https://jestjs.io/docs/en/api#testname-fn-timeout) - actual method that runs the test.
|
||||
|
||||
Based on our example, the test skeleton would look as follows:
|
||||
|
||||
```
|
||||
describe( 'Merchant can create virtual product', () => {
|
||||
it( 'merchant can log in', async () => {
|
||||
|
||||
} );
|
||||
|
||||
it( 'merchant can create virtual product', async () => {
|
||||
|
||||
} );
|
||||
|
||||
it( 'merchant can verify that virtual product was created', async () => {
|
||||
|
||||
} );
|
||||
} );
|
||||
```
|
||||
|
||||
Next, you can start filling up each section with relevant functions (test building blocks). Note, that we have the `@woocommerce/e2e-utils` package where many reusable helper functions can be found for writing tests. For example, `flows.js` of `@woocommerce/e2e-utils` package contains `StoreOwnerFlow` object that has `login` method. As a result, in the test it can be used as `await StoreOwnerFlow.login();` so the first `it()` section of the test will become:
|
||||
|
||||
```
|
||||
it( 'merchant can log in', async () => {
|
||||
await StoreOwnerFlow.login();
|
||||
} );
|
||||
```
|
||||
|
||||
Moving to the next section where we need to actually create a product. You will find that we have a reusable function such as `createSimpleProduct()` in the `components.js` of `@woocommerce/e2e-utils` package. However, note that this function should not be used for this test because the way simple product is being created in this function is by using WooCommerce REST API. Because this is not how the merchant would typically create a virtual product, we would need to test it by writing actual steps for creating a product in the test.
|
||||
|
||||
`createSimpleProduct()` should be used in tests where you need to test something else than creating a simple product. In other words, this function exists in order to quickly fill the site with test data required for running tests. For example, if you want to write a test that will verify that shopper can place a product to the cart on the site, you can use `createSimpleProduct()` to create a product to test the cart.
|
||||
|
||||
Because `createSimpleProduct()` can't be used in the case of our example test, we'd need to navigate to the page where the user would usually create a product. To do that, there is `openNewProduct()` function of the `StoreOwnerFlow` object that we already used above. As a result, that part of the test will look as follows:
|
||||
|
||||
```
|
||||
it( 'merchant can create virtual product', async () => {
|
||||
await StoreOwnerFlow.openNewProduct();
|
||||
} );
|
||||
```
|
||||
|
||||
You would then continue writing the test using utilities where possible.
|
||||
|
||||
Make sure to utilize the functions of the `@automattic/puppeteer-utils` package where possible. For example, if you need to wait for certain element to be ready to be clicked on and then click on it, you can use `waitAndClick()` function:
|
||||
|
||||
```
|
||||
await waitAndClick( page, '#selector' );
|
||||
```
|
||||
|
||||
### Best practices
|
||||
|
||||
- It is best to keep the tests inside `describe()` block granular as it helps to debug the test if it fails. When the test is done running, you will see the result along with the breakdown of how each of the test sections performed. If one of the tests within `describe()` block fails, it will be shown as follows:
|
||||
|
||||
```
|
||||
FAIL ../specs/front-end/front-end-my-account.test.js (9.219s)
|
||||
My account page
|
||||
✓ allows customer to login (2924ms)
|
||||
✓ allows customer to see orders (1083ms)
|
||||
x allows customer to see downloads (887ms)
|
||||
✓ allows customer to see addresses (1161ms)
|
||||
✓ allows customer to see account details (1066ms)
|
||||
```
|
||||
|
||||
In the example above, you can see that `allows customer to see downloads` part of the test failed and can start looking at it right away. Without steps the test goes through being detailed, it is more difficult to debug it.
|
||||
|
||||
## Debugging tests
|
||||
|
||||
|
|
Loading…
Reference in New Issue