Интеграционный тест Magento 2 в контексте администратора


Я пишу интеграционный тест для Magento 2, где мне нужно эмулировать административную область.

Для этого я использую аннотацию @magentoAppArea:

/**
 * @magentoAppArea adminhtml
 */

Однако некоторые вещи работали не так, как ожидалось, и я обнаружил, что текущий идентификатор магазина установлен на "1" (магазин по умолчанию) вместо "0" (магазин администратора)

Вот минимальный пример неудачного теста:

/**
 * @magentoAppArea adminhtml
 */
public function testAdminarea()
{
    $storeManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()
        ->get(\Magento\Store\Model\StoreManagerInterface::class);
    $this->assertEquals(0, $storeManager->getStore()->getId());
}

Как правильно настроить этот тест?


Что я нашел во время отладки:

  1. Magento\TestFramework\Application::loadArea('adminhtml') срабатывает правильно.

  2. Идентификатор магазина сначала инициализируется в Magento\Store\Model\StoreResolver::getStoresData():

    $cacheKey = 'resolved_stores_' . md5($this->runMode . $this->scopeCode);
    $cacheData = $this->cache->load($cacheKey);
    

    Где $this->runMode - "веб-сайт", а $this->scopeCode - "ноль".

Author: Fabian Schmengler, 2016-06-16

2 answers

Я думаю, что предположение о том, что хранилище администратора всегда активно в области adminhtml, может больше не соответствовать действительности в Magento 2.
Я нигде не нашел константы с нулевым идентификатором хранилища администратора. Вероятно, это также больше не следует считать таковым.

Состояние приложения и область действия устанавливаются в adminhtml прослушивателем теста аннотаций, что, вероятно, достаточно для запуска полного поведения серверной части.
Хотя я не уверен. Что вы хотите на самом деле тест?

/**
 * @magentoAppArea adminhtml
 */
public function testBackendScopeIsSet()
{
    /** @var ObjectManager $objectManager */
    $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();

    /** @var \Magento\TestFramework\App\State $state */
    $state = $objectManager->get(\Magento\TestFramework\App\State::class);
    $this->assertSame(Area::AREA_ADMINHTML, $state->getAreaCode());

    /** @var \Magento\Framework\Config\Scope $scope */
    $scope = $objectManager->get(\Magento\Framework\Config\Scope::class);
    $this->assertSame(Area::AREA_ADMINHTML, $scope->getCurrentScope());
}

Если для вашего теста требуется, чтобы хранилище администратора было активным, вам также потребуется настроить его вручную в разделе "Упорядочить" теста:

    /** @var StoreManagerInterface $storeManager */
    $storeManager = $objectManager->get(StoreManagerInterface::class);
    $storeManager->setCurrentStore(Store::ADMIN_CODE);

    $this->assertEquals(0, $storeManager->getStore()->getId());
 2
Author: Vinai, 2016-06-16 20:55:34

Я почти уверен, что это должно работать без чего-либо еще.

В основном аннотация @magentoAppArea определяется в разделе /dev/tests/integration/framework/Magento/TestFramework/Annotation/AppArea.php, поэтому, если я не уверен, будет ли аннотация работать, если тестовый класс находится под app/code/Vendor/Module/TestFolder

Что делает этот класс, так это повторно инициализирует, а затем загружает указанную вами область:

public function startTest(\PHPUnit_Framework_TestCase $test)
{
    $area = $this->_getTestAppArea($test->getAnnotations());
    if ($this->_application->getArea() !== $area) {
        $this->_application->reinitialize();

        if ($this->_application->getArea() !== $area) {
            $this->_application->loadArea($area);
        }
    }
}

Метод loadArea определен в разделе /dev/tests/integration/framework/Magento/TestFramework/Application.php и выполняет следующие действия:

  • изменить область действия
  • перенастроить OM в зависимости от области конфигурация
  • Загрузить область

    public function loadArea($areaCode)
    {
        $this->_appArea = $areaCode;
        $scope = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\Config\Scope');
        $scope->setCurrentScope($areaCode);
        \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->configure(
            \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
                'Magento\Framework\App\ObjectManager\ConfigLoader'
            )->load(
                $areaCode
            )
        );
        $app = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Framework\App\AreaList');
        if ($areaCode == \Magento\TestFramework\Application::DEFAULT_APP_AREA) {
            $app->getArea($areaCode)->load(\Magento\Framework\App\Area::PART_CONFIG);
        } else {
            \Magento\TestFramework\Helper\Bootstrap::getInstance()->loadArea($areaCode);
        }
    }
    

Возможно, именно здесь вам следует начать отладку.

 0
Author: Raphael at Digital Pianism, 2016-06-16 15:36:03