Створення інтеграційних тестів для модулів Magento 2


27

Поки для моїх потреб у тестуванні Magento 2 я використовував PHP Unit як (більш-менш) тестовий прийом - результати тестування серверних та HTML-запитів, внесених до системи з встановленим моїм модулем (модулями). Мені б хотілося створити власні інтеграційні тести. Чи дозволяють інструменти тестування, що постачаються з Magento 2, розробникам сторонніх розробників створювати власні інтеграційні тести, які б використовували рамковий код тесту Magento? Або ми всі прокатуємо власний завантажувальний пристрій?

Це є

  1. Я розробник Magento
  2. Я хотів би створити тест на інтеграцію
  3. Я б мій тест на інтеграцію мав повне завантажувальне середовище Magento для завантаження (тобто менеджер об'єктів та / або введення залежності для використання)
  4. Я хотів би, щоб мій тест на інтеграцію продовжив Magento\TestFramework\TestCase\AbstractControllerтест, щоб у мене були ті самі помічники, що і тести Magento
  5. Я хотів би мати змогу запускати свої тести ізольовано від решти тестового набору (тобто не потрібно чекати 2 години, щоб виконати мої 15 секунд тестів)
  6. Я хотів би, щоб мої тести зберігалися окремо від тестів Магенто

На сайті розробників є кілька стартових статей про тестування, але вони здаються орієнтованими на виконання тестів, які постачаються з Magento, а не на створення та запуск власних тестів. Є старі зразкові модулі , але всі вони розширюють PHPUnit_Framework_TestCaseклас і, здається, є одиничними тестами (тобто код тестування, який не покладається на рамки Magento)

Чи передбачений Magento спосіб цього зробити?

Якщо ні, чи хтось прокрутив власну програму таким чином, щоб тест спільноти розробників Magento міг прийняти її як стандарт?

Відповіді:


20

Це працює для нас, але ми ще не розглядали можливість їх переміщення в окреме місце на адресу 6.)

1.) Розмістіть ваші інтеграційні тести під dev/tests/integration/testsuite/Vendor
2.) копіюйте dev/tests/integration/phpunit.dist.xml
в
dev/tests/integration/phpunit.xml

і замінити

        <directory suffix="Test.php">testsuite</directory>
        <directory suffix="Test.php">../../../update/dev/tests/integration/testsuite</directory>
        <exclude>testsuite/Magento/Test/Integrity</exclude>
        <exclude>testsuite/Magento/MemoryUsageTest.php</exclude>

з

        <directory suffix="Test.php">testsuite/Vendor</directory>

3.) запустіть його ../../../vendor/bin/phpunitабо за допомогою ../../../vendor/bin/phpunit path/to/testsпапки dev / test / integration

Зверніть увагу, що тести на інтеграцію займають більше 15 секунд, принаймні при першому запуску, оскільки він по суті встановлює Magento. Ви можете заощадити на наступних запусках, якщо використовуєте

<const name="TESTS_CLEANUP" value="disabled"/>

у вашому phpunit.xml


11

Я успішно розмістив свої інтеграційні тести в окремий каталог: src/My/Module/test/integration. Це також може бути будь-який інший каталог, як app/code/My/Module/Test.

Додайте їх в новий набір тестів для тестування інтеграції Magento: Копіювати dev/tests/integration/phpunit.xml.distв dev/tests/integration/phpunit.xmlі додати наступне в <testsuites>вузлі:

<testsuite name="My_Module">
    <directory suffix="Test.php">../../../src/My/Module/test</directory>
</testsuite>

Потім запустіть такі тести з dev/tests/integrationкаталогу:

../../../vendor/bin/phpunit --testsuite "My_Module"

За допомогою --testsuiteпараметра можна вибрати один тестовий набір за назвою, так що не всі тести інтеграції виконуються одразу

Оновлення: світильники

Для використання власних світильників було потрібно трохи вирішення, оскільки в Magento\TestFramework\Annotationбазовій каталогій кріплення визначено глобально. Але, на щастя, Magento дозволяє імена методів як світильників, тому такі дії:

/**
 * @magentoDataFixture loadFixture
 */
public function testSomething()
{
}

public static function loadFixture()
{
    include __DIR__ . '_files/something_fixture.php';
}

1
Чи не виникли б у вас проблеми під час використання @magentoDataFixture тут github.com/magento/magento2/blob/develop/dev/tests/integration/…, особливо при поєднанні спеціального кріплення з вашого модуля з основним?
Крістоф у Фомані

1
tbh, я ще не пробував цього, але це виглядає як проблема, так. Можливо, потрібно встановити шлях включення для роботи цих світильників.
Фабіан Шменглер

1
@ KristofatFooman Знайшов рішення для світильників, див. Оновлення
Фабіан Шменглер

Прекрасне рішення. Тут може бути пара недоліків. Перш за все, є помилка друку - __DIR__слід слідувати косою рискою ( /_files). По-друге, кріплення завантажується зсередини TestFramework так, що __DIR__фактично вказує на каталог TestFramework, а не на ваш власний модуль. ComponentRegistrarМожуть бути використані для цього:require $ObjectManager::getInstance()->get(ComponentRegistrar::class)->getPath('module', 'Foo_Bar').'/Test/Integration/_files/example.php';
Jisse Reitsma

10

Я трохи пограв з інтеграційними тестами, і ось що я знайшов досі.

В основному я дотримувався подібних кроків до того, що сказав Fooman, з деякими відмінностями, щоб зробити тест на інтеграцію частиною мого модуля.

Це наступні кроки:

1- Розмістіть ваші інтеграційні тести під app/code/Vendor/CustomModule/Test/Integration

2- Копіювати dev/tests/integration/phpunit.dist.xmlвdev/tests/integration/phpunit.xml

і замінити

<testsuite name="Magento Integration Tests">
    <directory suffix="Test.php">testsuite</directory>
    <directory suffix="Test.php">../../../update/dev/tests/integration/testsuite</directory>
    <exclude>testsuite/Magento/Test/Integrity</exclude>
    <exclude>testsuite/Magento/MemoryUsageTest.php</exclude>
</testsuite>

з

<testsuite name="Magento Integration Tests">
    <directory suffix="Test.php">../../../app/code/Vendor/CustomModule/Test/Integration</directory>
</testsuite>

3- Потім я запускаю його за допомогою інструмента CLI bin/magento dev:test:run integration

Ви повинні мати на увазі, що Fooman говорить про "TESTS_CLEANUP" та час, який потрібно для встановлення тестів інтеграції, якщо у вас є можливість очищення.

Тут я додаю функціональний приклад для подальшого ознайомлення. Ви побачите, як ви можете отримати доступ до диспетчера об'єктів і генерувати екземпляр класів Magento, а також використовувати світильники Magento.

додаток / код / ​​Постачальник / CustomModule / Контролер / Замовлення / Info.php

namespace Vendor\CustomModule\Controller\Order;

use Magento\Framework\Controller\ResultFactory;

class Info
    extends \Magento\Framework\App\Action\Action
{
    /**
     * @param \Magento\Framework\App\Action\Context $context
     * @param \Magento\Sales\Api\OrderRepositoryInterface $orderRepository
     */
    public function __construct(
        \Magento\Framework\App\Action\Context $context,
        \Magento\Sales\Api\OrderRepositoryInterface $orderRepository
    )
    {
        $this->orderRepository = $orderRepository;
        parent::__construct($context);
    }

    /**
     * Return Json OrderInfo
     *
     * @return \Magento\Framework\Controller\Result\Json $this
     */
    public function execute()
    {
        $orderId = $this->getRequest()->getParam('id');
        $order = $this->orderRepository->get($orderId);
        $orderInfo = [
            'total' => $order->getBaseGrandTotal()
        ];

        /** @var \Magento\Framework\Controller\Result\Json $result */
        $result = $this->resultFactory->create(ResultFactory::TYPE_JSON);
        return $result->setData($orderInfo);
    }

}

app / code / Постачальник / CustomModule / тощо / frontend / routes.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route id="vendor_custommodule" frontName="vendor_custommodule">
            <module name="Vendor_CustomModule"/>
        </route>
    </router>
</config>

app / code / Постачальник / CustomModule / тощо / module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_CustomModule" setup_version="1.0.0">
        <sequence>
            <module name="Magento_Sales" />
        </sequence>
    </module>
</config>

додаток / код / ​​Постачальник / CustomModule / Тест / Інтеграція / Контролер / Замовлення / InfoTest.php

namespace Vendor\CustomModule\Controller\Order;

use Magento\TestFramework\TestCase\AbstractController;

class InfoTest extends AbstractController
{
    public function getOrderInfoActionDataProvider()
    {
        return [
            'order with one simple item' => [
                'incrementId' => '100000001',
                'contentType' => 'application/json',
                'orderTotal' => 100
            ]
        ];
    }

    /**
     * @dataProvider getOrderInfoActionDataProvider
     * @magentoDataFixture Magento/Sales/_files/order.php
     */
    public function testOrderInfoAction($incrementId, $expectedContentType, $expectedOrderTotal)
    {
        /** @var $objectManager \Magento\TestFramework\ObjectManager */
        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();

        /** @var \Magento\Sales\Model\OrderFactory $orderFactory */
        $orderFactory = $objectManager->get('Magento\Sales\Model\OrderFactory');
        $order = $orderFactory->create();
        $order->loadByIncrementId($incrementId);

        $this->dispatch("vendor_custommodule/order/info/id/{$order->getId()}");

        $contentType = $this->getResponse()->getHeader('Content-Type');
        $this->assertEquals($expectedContentType, $contentType->getFieldValue());

        $responseJson = $this->getResponse()->getBody();
        $responseArray = json_decode($responseJson, true);
        $this->assertEquals($expectedOrderTotal, $responseArray['total']);
    }
}

додаток / код / ​​Постачальник / CustomModule / registration.php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Vendor_CustomModule',
    __DIR__
);

Зверніть увагу, що ваше власне рішення добре, і воно працює, доки ви використовуєте кріплення основ Magento. Якщо ви хочете використовувати власні світильники, ви натрапите на проблеми, про які йшлося раніше.
Jisse Reitsma
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.