Using Magento 2 Configuration Test Annotations

Here at SwiftOtter, we’ve been hard at work on several Magento 2 projects, and enjoy building out custom features for these sites. As a development team, we believe in the value of testing our code and are in the process of integrating more automated testing into our workflow. As such, we have been investing in learning the Magento 2 testing framework.

As you may know, the Magento 2 testing framework is broad, and introduces an new area of the platform for developers to master. Due to online documentation being rather scarce, I thought that it would be helpful to share a few of the things that I’ve been learning. Expect to see more posts over the next few weeks focused on tests in Magento 2.

Our main thrust has been on integration testing. Today I’d like to share one of the neat features of the integration test framework that I’ve discovered. As you may know, PHPUnit (the testing library that the Magento test framework is built on) supports a number of Javadoc-style annotations. Magento has leveraged that functionality and added several annotations to the test framework that are quite useful, particularly in integration tests. One of the easiest ones to start using is the @magentoConfigFixture annotation. This annotation allows you to set a temporary store config value for the duration of the test function. Let’s take a look at it.

Here’s an example from a core test, in Magento\Catalog\Model\Indexer\Product\Flat\Action\FullText:

/**
 * @magentoDbIsolation enabled
 * @magentoAppIsolation enabled
 * @magentoConfigFixture current_store catalog/frontend/flat_catalog_product 1
 * @magentoDataFixture Magento/Catalog/_files/product_simple.php
 */
 public function testReindexAll()
 {
    $this->assertTrue($this->_state->isFlatEnabled());
    $this->_processor->reindexAll();

    $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
        'Magento\Catalog\Model\CategoryFactory'
    );
    $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
        'Magento\Catalog\Block\Product\ListProduct'
    );
    ...

Notice the @magentoConfigFixture annotation in the comment at the top of the function? In this case, it specifies to set the value of catalog/frontend/flat_catalog_product to 1 for the current store, which would enable flat product tables. This is useful for testing features that depend on a certain configuration value, whether from default Magento itself or from a custom extension you are developing.

Let’s walk through an example of when we might use this. Say you’re developing a module that allows you to replace the shipping quote on the frontend with a custom message, because your store’s products are irregular in nature and the shipping cost is not always known. However, during holidays, you offer free shipping, as you absorb the cost of shipping due to a higher order volume. Therefore, if free shipping is enabled on your store, you don’t want output the message, as the customer doesn’t have to cover the costs of shipping. But, you definitely want the customer to know that you’re paying for their shipping! Let’s write a basic test function that ensures the custom message is what the block renders when free shipping is disabled.

/**
 * @magentoConfigFixture current_store carriers/freeshipping/active 0
 */

public function testTheBlockMessageIsCorrectWhenFreeShippingIsDisabled()
{
   $objectManager = Magento\TestFramework\ObjectManager::getInstance();
   $messageBlock = $objectManager->create('\Your\ShippingModule\Block\MessageBlock');
   $this->assertContains('your_shipping_message', $block->getMessage());
}

While this is a rather simple test, it illustrates how you could test custom functionality based on store config values. Notice also that we’re specifying which store to set the config value for; in this case, it’s the current store. However, you can also specify other stores by entering the store code followed by _store, like german_store.

Summary

In conclusion, the Magento 2 Integration testing framework’s @magentoConfigFixture annotations can be very helpful when testing how code will respond depending on different configuration settings. We no longer have to manually set values and then unset them after tests are complete - the framework will now handle that for us.

I’m really pleased with how Magento is investing in Integration and Unit testing, and I think it will push the community to adopt thorough testing of any code during development. I’ll be back in the next couple weeks with some more content on the test framework, but until then, happy testing!

Tyler Schade

Former Developer at SwiftOtter