|
1 | | -# wp-browser-woocommerce |
| 1 | +# wp-browser-woocommerce |
| 2 | +This library simplifies testing of WooCommerce themes and plugins with [wp-browser](https://github.com/lucatume/wp-browser). Several [Unit Test Factories](https://make.wordpress.org/core/handbook/testing/automated-testing/writing-phpunit-tests/#fixtures-and-factories) are added that allow you to quickly create WooCommerce products and orders within an integration test. |
| 3 | + |
| 4 | +## Getting started |
| 5 | +Before getting started with `wp-browser-woocommerce`, make sure you read the excellent [documentation for wp-browser](https://wpbrowser.wptestkit.dev/) first. |
| 6 | +### Installation |
| 7 | +To install `wp-browser-woocommerce` you use [composer](https://getcomposer.org/). The library is published on [packagist](https://packagist.org/packages/level-level/wp-browser-woocommerce). |
| 8 | + |
| 9 | +```shell |
| 10 | +composer require --dev level-level/wp-browser-woocommerce |
| 11 | +``` |
| 12 | + |
| 13 | +### Your first WooCommerce test |
| 14 | + |
| 15 | +Tests written with `wp-browser-woocommerce` are a lot like regular `wp-browser` integration tests. By extending from `\LevelLevel\WPBrowserWooCommerce\WCTestCase` instead of the regular `\WPTestCase`, you will get access to WooCommerce unit test factories. |
| 16 | + |
| 17 | +```php |
| 18 | +<?php // ./tests/wpunit/ExampleTest.php |
| 19 | + |
| 20 | +use LevelLevel\WPBrowserWooCommerce\WCTestCase; |
| 21 | + |
| 22 | +class ExampleTest extends WCTestCase{ |
| 23 | + public function test_something(){ |
| 24 | + // Create a WooCommerce product. |
| 25 | + $product = $this->factory()->product->create_and_get( |
| 26 | + array( |
| 27 | + 'name' => 'test', |
| 28 | + 'regular_price' => '12.12', |
| 29 | + ) |
| 30 | + ); |
| 31 | + |
| 32 | + // Create a WooCommerce order with two products. |
| 33 | + $order = $this->factory()->order->create_and_get( |
| 34 | + array( |
| 35 | + 'payment_method' => 'bacs', |
| 36 | + 'payment_method_title' => 'BACS', |
| 37 | + 'set_paid' => true, |
| 38 | + 'line_items' => array( |
| 39 | + array( |
| 40 | + 'product_id' => $product->get_id(), |
| 41 | + 'quantity' => 2, |
| 42 | + ), |
| 43 | + ), |
| 44 | + ) |
| 45 | + ); |
| 46 | + |
| 47 | + // Make sure the order total price is correct. |
| 48 | + $this->assertEquals( 24.24, $order->get_total() ); |
| 49 | + } |
| 50 | +} |
| 51 | +``` |
| 52 | + |
| 53 | +## Factories |
| 54 | +The factories provide methods to allow for quick object creation. The factories are access with the `$this->factory()` method on a testcase. |
| 55 | + |
| 56 | +In the background, the factories use [the WooCommerce REST API](https://woocommerce.github.io/woocommerce-rest-api-docs/#introduction) methods to create and retrieve objects. These are not actual `GET`/`POST` requests, but rather internal calls to the methods that would process the regular requests to the API. |
| 57 | + |
| 58 | +All factories extend from the WordPress default [WP_UnitTest_Factory_For_Thing](https://github.com/WordPress/wordpress-develop/blob/master/tests/phpunit/includes/factory/class-wp-unittest-factory-for-thing.php). All methods that are specified on this base class are available on the factories you will use in WooCommerce tests. |
| 59 | + |
| 60 | +In this documentation you will only find the most used ones, refer to the base class or WordPress documentation for others. |
| 61 | + |
| 62 | +### Orders |
| 63 | +You can access the order factory by using `$this->factory()->order` within a WooCommerce integration test. |
| 64 | + |
| 65 | +The main method you'll use is `create_and_get( $args )`. The input you can give to an order are the same as you can give to the order creation API endpoint. |
| 66 | + |
| 67 | +`create_and_get($args)` returns the result of `wc_get_order()` for the created object. |
| 68 | + |
| 69 | +See https://woocommerce.github.io/woocommerce-rest-api-docs/#create-an-order |
| 70 | + |
| 71 | +Example: |
| 72 | +```php |
| 73 | +$order = $this->factory()->order->create_and_get( |
| 74 | + array( |
| 75 | + 'payment_method' => 'bacs', |
| 76 | + 'payment_method_title' => 'BACS', |
| 77 | + 'set_paid' => true, |
| 78 | + 'billing' => array( |
| 79 | + 'first_name' => 'John', |
| 80 | + 'last_name' => 'Doe', |
| 81 | + 'address_1' => 'Market', |
| 82 | + 'house_number' => '1', |
| 83 | + 'address_2' => '', |
| 84 | + 'city' => 'Rotterdam', |
| 85 | + 'postcode' => '3456AB', |
| 86 | + 'country' => 'NL', |
| 87 | + 'email' => 'john.doe@example.com', |
| 88 | + ), |
| 89 | + 'shipping' => array( |
| 90 | + 'first_name' => 'John', |
| 91 | + 'last_name' => 'Doe', |
| 92 | + 'address_1' => 'Memory Lane', |
| 93 | + 'house_number' => '1', |
| 94 | + 'address_2' => '', |
| 95 | + 'city' => 'Rotterdam', |
| 96 | + 'postcode' => '3456AB', |
| 97 | + 'country' => 'NL', |
| 98 | + ), |
| 99 | + 'line_items' => array( |
| 100 | + array( |
| 101 | + 'product_id' => 1, |
| 102 | + 'quantity' => 1, |
| 103 | + 'meta_data' => array( |
| 104 | + array( |
| 105 | + 'key' => 'made_by', |
| 106 | + 'value' => 'Level Level', |
| 107 | + ), |
| 108 | + array( |
| 109 | + 'key' => 'with_love', |
| 110 | + 'value' => 'obviously' |
| 111 | + ), |
| 112 | + ), |
| 113 | + ), |
| 114 | + ), |
| 115 | + 'shipping_lines': array( |
| 116 | + array( |
| 117 | + 'method_id': 'flat_rate', |
| 118 | + 'method_title': 'Flat Rate', |
| 119 | + 'total': '10.00' |
| 120 | + ) |
| 121 | + ) |
| 122 | + ) |
| 123 | +); |
| 124 | +``` |
| 125 | + |
| 126 | +### Products |
| 127 | + |
| 128 | +You can access the order factory by using `$this->factory()->product` within a WooCommerce integration test. |
| 129 | + |
| 130 | +The main method you'll use is `create_and_get( $args )`. The input you can give to an order are the same as you can give to the product creation API endpoint. |
| 131 | + |
| 132 | +`create_and_get($args)` returns the result of `wc_get_product()` for the created object. |
| 133 | + |
| 134 | +See https://woocommerce.github.io/woocommerce-rest-api-docs/#create-a-product |
| 135 | + |
| 136 | +Example: |
| 137 | + |
| 138 | +```php |
| 139 | +$this->factory()->product->create_and_get( |
| 140 | + array( |
| 141 | + 'name' => 'test', |
| 142 | + 'regular_price' => '103.11', |
| 143 | + 'weight' => '14', |
| 144 | + 'dimensions' => array( |
| 145 | + 'height' => '1', |
| 146 | + ), |
| 147 | + 'reviews_allowed' => false, |
| 148 | + 'manage_stock' => true, |
| 149 | + 'stock_status' => 'onbackorder', |
| 150 | + 'backorders' => 'yes', |
| 151 | + 'meta_data' => array( |
| 152 | + array( |
| 153 | + 'key' => 'made_in', |
| 154 | + 'value' => 'Rotterdam', |
| 155 | + ), |
| 156 | + ), |
| 157 | + ) |
| 158 | +); |
| 159 | +``` |
| 160 | + |
| 161 | +## Testcases |
| 162 | +For most testcases you will want to use `\LevelLevel\WPBrowserWooCommerce\WCTestCase` |
| 163 | + |
| 164 | +### Ajax calls |
| 165 | +For ajax calls, the regular [\WPAjaxTestCase](https://wpbrowser.wptestkit.dev/commands#generate-wpajax) would be replaced with `\LevelLevel\WPBrowserWooCommerce\WCAjaxTestCase` |
| 166 | + |
| 167 | +Example: |
| 168 | + |
| 169 | +```php |
| 170 | +public function test_can_add_sample_to_cart() { |
| 171 | + WC_AJAX::init(); |
| 172 | + |
| 173 | + $product = $this->factory()->product->create_and_get( |
| 174 | + array( |
| 175 | + 'name' => 'test', |
| 176 | + 'regular_price' => '12.12', |
| 177 | + ) |
| 178 | + ); |
| 179 | + |
| 180 | + // ... testing logic ... |
| 181 | + |
| 182 | + try { |
| 183 | + $this->_handleAjax( 'woocommerce_add_to_cart' ); |
| 184 | + } catch ( WPAjaxDieContinueException $e ) { |
| 185 | + ob_end_flush(); |
| 186 | + } |
| 187 | + $this->assertEmpty( wc_get_notices( 'error' ), 'There should be no error notices after making this ajax call.' ); |
| 188 | +} |
| 189 | +``` |
| 190 | + |
| 191 | +## Development |
| 192 | +`wp-browser-woocommerce` is actively being used at [Level Level](https://level-level.com/). The library will get new features as we need them for client projects. |
| 193 | + |
| 194 | +### Roadmap |
| 195 | + |
| 196 | +The main focus is on implementing more factories for other WooCommerce objects such as **coupons**, **customers**, **refunds** and **shipping methods**. |
| 197 | + |
| 198 | +After this, focus might shift to popular extensions for WooCommerce, such as Subscriptions or Bookings. |
| 199 | + |
| 200 | +### Contributing |
| 201 | +Feel free to open issues or create pull requests if you feel something is missing or working incorrectly. |
0 commit comments