TddWizard Fixture library
![Software License][ico-license]
![Coverage Status][ico-scrutinizer]
, (*1)
Magento 2 Fixtures by Fabian Schmengler, (*2)
🧙🏻♂ https://tddwizard.com/, (*3)
What is it?
An alternative to the procedural script based fixtures in Magento 2 integration tests., (*4)
It aims to be:, (*5)
- extensible
- expressive
- easy to use
Installation
Install it into your Magento 2 project with composer:, (*6)
composer require --dev tddwizard/magento2-fixtures
Requirements
- Magento 2.3 or Magento 2.4
- PHP 7.3 or 7.4 (7.1 and 7.2 is allowed via composer for full Magento 2.3 compatibility but not tested anymore)
Usage examples:
Customer
If you need a customer without specific data, this is all:, (*7)
protected function setUp(): void
{
$this->customerFixture = new CustomerFixture(
CustomerBuilder::aCustomer()->build()
);
}
protected function tearDown(): void
{
$this->customerFixture->rollback();
}
It uses default sample data and a random email address. If you need the ID or email address in the tests, the CustomerFixture
gives you access:, (*8)
$this->customerFixture->getId();
$this->customerFixture->getEmail();
You can configure the builder with attributes:, (*9)
CustomerBuilder::aCustomer()
->withEmail('test@example.com')
->withCustomAttributes(
[
'my_custom_attribute' => 42
]
)
->build()
You can add addresses to the customer:, (*10)
CustomerBuilder::aCustomer()
->withAddresses(
AddressBuilder::anAddress()->asDefaultBilling(),
AddressBuilder::anAddress()->asDefaultShipping(),
AddressBuilder::anAddress()
)
->build()
Or just one:, (*11)
CustomerBuilder::aCustomer()
->withAddresses(
AddressBuilder::anAddress()->asDefaultBilling()->asDefaultShipping()
)
->build()
The CustomerFixture
also has a shortcut to create a customer session:, (*12)
$this->customerFixture->login();
Addresses
Similar to the customer builder you can also configure the address builder with custom attributes:, (*13)
AddressBuilder::anAddress()
->withCountryId('DE')
->withCity('Aachen')
->withPostcode('52078')
->withCustomAttributes(
[
'my_custom_attribute' => 42
]
)
->asDefaultShipping()
Product
Product fixtures work similar as customer fixtures:, (*14)
protected function setUp(): void
{
$this->productFixture = new ProductFixture(
ProductBuilder::aSimpleProduct()
->withPrice(10)
->withCustomAttributes(
[
'my_custom_attribute' => 42
]
)
->build()
);
}
protected function tearDown(): void
{
$this->productFixture->rollback();
}
The SKU is randomly generated and can be accessed through ProductFixture
, just as the ID:, (*15)
$this->productFixture->getSku();
$this->productFixture->getId();
Cart/Checkout
To create a quote, use the CartBuilder
together with product fixtures:, (*16)
$cart = CartBuilder::forCurrentSession()
->withSimpleProduct(
$productFixture1->getSku()
)
->withSimpleProduct(
$productFixture2->getSku(), 10 // optional qty parameter
)
->build()
$quote = $cart->getQuote();
Checkout is supported for logged in customers. To create an order, you can simulate the checkout as follows, given a customer fixture with default shipping and billing addresses and a product fixture:, (*17)
$customerFixture = new CustomerFixture(CustomerBuilder::aCustomer()->withAddresses(
AddressBuilder::anAddress()->asDefaultBilling(),
AddressBuilder::anAddress()->asDefaultShipping()
)->build());
$customerFixture->login();
$checkout = CustomerCheckout::fromCart(
CartBuilder::forCurrentSession()
->withProductRequest(ProductBuilder::aVirtualProduct()->build()->getSku())
->build()
);
$order = $checkout->placeOrder();
It will try to select the default addresses and the first available shipping and payment methods., (*18)
You can also select them explicitly:, (*19)
$order = $checkout
->withShippingMethodCode('freeshipping_freeshipping')
->withPaymentMethodCode('checkmo')
->withCustomerBillingAddressId($this->customerFixture->getOtherAddressId())
->withCustomerShippingAddressId($this->customerFixture->getOtherAddressId())
->placeOrder();
Order
The OrderBuilder
is a shortcut for checkout simulation., (*20)
$order = OrderBuilder::anOrder()->build();
Logged-in customer, products, and cart item quantities will be
generated internally unless more control is desired:, (*21)
$order = OrderBuilder::anOrder()
->withProducts(
// prepare catalog product fixtures
ProductBuilder::aSimpleProduct()->withSku('foo'),
ProductBuilder::aSimpleProduct()->withSku('bar')
)->withCart(
// define cart item quantities
CartBuilder::forCurrentSession()->withSimpleProduct('foo', 2)->withSimpleProduct('bar', 3)
)->build();
Shipment
Orders can be fully or partially shipped, optionally with tracks., (*22)
$order = OrderBuilder::anOrder()->build();
// ship everything
$shipment = ShipmentBuilder::forOrder($order)->build();
// ship only given order items, add tracks
$shipment = ShipmentBuilder::forOrder($order)
->withItem($fooItemId, $fooQtyToShip)
->withItem($barItemId, $barQtyToShip)
->withTrackingNumbers('123-FOO', '456-BAR')
->build();
Invoice
Orders can be fully or partially invoiced., (*23)
$order = OrderBuilder::anOrder()->build();
// invoice everything
$invoice = InvoiceBuilder::forOrder($order)->build();
// invoice only given order items
$invoice = InvoiceBuilder::forOrder($order)
->withItem($fooItemId, $fooQtyToInvoice)
->withItem($barItemId, $barQtyToInvoice)
->build();
Credit Memo
Credit memos can be created for either all or some of the items ordered.
An invoice to refund will be created internally., (*24)
$order = OrderBuilder::anOrder()->build();
// refund everything
$creditmemo = CreditmemoBuilder::forOrder($order)->build();
// refund only given order items
$creditmemo = CreditmemoBuilder::forOrder($order)
->withItem($fooItemId, $fooQtyToRefund)
->withItem($barItemId, $barQtyToRefund)
->build();
Fixture pools
To manage multiple fixtures, fixture pools have been introduced for all entities:, (*25)
Usage demonstrated with the ProductFixturePool
:, (*26)
protected function setUp()
{
$this->productFixtures = new ProductFixturePool;
}
protected function tearDown()
{
$this->productFixtures->rollback();
}
public function testSomethingWithMultipleProducts()
{
$this->productFixtures->add(ProductBuilder::aSimpleProduct()->build());
$this->productFixtures->add(ProductBuilder::aSimpleProduct()->build(), 'foo');
$this->productFixtures->add(ProductBuilder::aSimpleProduct()->build());
$this->productFixtures->get(); // returns ProductFixture object for last added product
$this->productFixtures->get('foo'); // returns ProductFixture object for product added with specific key 'foo'
$this->productFixtures->get(0); // returns ProductFixture object for first product added without specific key (numeric array index)
}
Config Fixtures
With the config fixture you can set a configuration value globally, i.e. it will ensure that it is not only set in the default scope but also in all store scopes:, (*27)
ConfigFixture::setGlobal('general/store_information/name', 'Ye Olde Wizard Shop');
It uses MutableScopeConfigInterface
, so the configuration is not persisted in the database. Use @magentoAppIsolation enabled
in your test to make sure that changes are reverted in subsequent tests., (*28)
You can also set configuration values explicitly for stores with ConfigFixture::setForStore()
, (*29)
Credits
License
The MIT License (MIT). Please see License File for more information., (*30)