Модель тестування джерел блоку


10

У моєму спеціальному розширенні є кілька моделей, які служать лише заповненню мети у деяких виділених та / або мультиселекторах у формі додавання / редагування моїх сутностей.
Отже, це те, що Магенто називає "вихідними моделями".
Зазначені значення завжди однакові, а методи повертають одне і те ж.
Як я повинен перевірити їх? Або ще краще, я повинен написати для них одиничні тести?
Ось приклад.
Наступний клас використовується для форми додавання / редагування для поля, що називається, typeі для стовпчика сітки того ж поля.

<?php
namespace Sample\News\Model\Author\Source;

use Magento\Framework\Option\ArrayInterface;

class Type implements ArrayInterface
{
    const COLLABORATOR = 1;
    const EMPLOYEE = 2;

    /**
     * Get options
     *
     * @return array
     */
    public function toOptionArray()
    {
        $_options = [
            [
                'value' => '',
                'label' => ''
            ],
            [
                'value' => self::COLLABORATOR,
                'label' => __('Collaborator')
            ],
            [
                'value' => self::EMPLOYEE,
                'label' => __('Employee')
            ],
        ];
        return $_options;
    }

    /**
     * get options as key value pair
     *
     * @return array
     */
    public function getOptions()
    {
        $_tmpOptions = $this->toOptionArray();
        $_options = [];
        foreach ($_tmpOptions as $option) {
            $_options[$option['value']] = $option['label'];
        }
        return $_options;
    }
}

Відповіді:


15

Це чудова нитка, і мені дуже подобаються відповіді від @KAndy та @fschmengler.
Я хотів би додати кілька додаткових думок, які мені здаються цінними, задаючи питання, наприклад, "Чи слід перевірити Х?" або "Як слід протестувати X?".

Що може піти не так?

  • Я міг зробити німий друк (трапляється постійно).
    Це зазвичай не виправдовує написання тесту.
  • Чи скопіюю потрібний мені код з ядра чи іншого модуля, а потім відрегулюю його під мої потреби?
    Я вважаю це насправді дуже небезпечною справою, яка часто залишає непомітні помилки. У цьому випадку я віддаю перевагу написанню тесту, якщо він не надто дорогий. Створення конфігурації моделей джерел насправді зробить їх більш ризикованими ІМО.
  • Чи може виникнути конфлікт з іншим модулем?
    Це майже стосується лише коду конфігурації. У такому випадку мені подобається пройти інтеграційний тест, який підкаже мені, коли це станеться.
  • Чи міг Magento змінити API у майбутньому випуску?
    В цьому випадку малоймовірно, оскільки ваш код залежить лише від інтерфейсу. Але чим більш конкретні класи задіяні, або якщо мій код поширює основний клас, це стає більше потенційним ризиком.
  • Нова версія PHP може зламати мій код. Або, можливо, я хочу підтримувати PHP 5.6 на довгі роки.
    Знову ж таки, дуже малоймовірно, але в деяких випадках я хочу, щоб тест попередив мене, чи варто в майбутньому змінити код, щоб використовувати несумісний синтаксис.

Наскільки дорого коштувати тестування коду?

Це має два аспекти:

  • Кількість зусиль і часу, необхідних для написання тесту
  • Кількість зусиль і часу, необхідних для тестування фрагмента коду, який я збираюся написати вручну.

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

У вашому випадку написання тесту є дешевим дешевим. Це не займе багато часу або зусиль. @KAndy має рацію, що весь код потрібно підтримувати, але знову ж таки, не всі тести потрібно зберігати.
Це може бути приклад, коли я б писав одиничний тест, просто щоб перевірити, чи не помиляюся я, а потім видаляю його, коли клас закінчується. Якщо тест не дає довгострокового значення, я думаю, що їх видалення має сенс.

Це питання також важливе з точки зору вибору типу тесту для написання: одиниці чи інтеграції, наприклад.

Наскільки цінний фрагмент коду, який я пишу?

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

Чи потрібно буде код змінити?

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

Чи потрібна документація?

Наскільки важко використовувати код? У вашому прикладі це банально, але в деяких більш складних випадках тест чудово підходить для цілей документації для інших розробників (або для мене за кілька місяців).

Дослідження та навчання

Якщо я працюю над яким-небудь кодом і не знаю, як його перевірити, мені здається дуже цінним написати тест. Процес майже завжди дає глибше розуміння того, з чим я маю справу.
Особливо це стосується розробників, які все ще вважають себе тестуванням навчання.
Це також є прикладом, коли може бути сенс видалити тест після цього, оскільки головне значення, яке він надав, - це навчання.

Дисципліна та стрес

Прилипання до циклу червоного зеленого рефактора допомагає мені швидко йти. Особливо це стосується тиску. Тож навіть якщо якийсь фрагмент коду насправді не є тестовим, я все одно можу дотримуватися TDD, особливо якщо код є тривіальним для тестування.
Це тримає мене в потоці і настороженості.

Що і як протестувати?

Також врахуйте, що ви можете написати тест із дуже різною деталізацією.

  • Тестування точного поверненого значення.
    Це буде дуже жорсткий тест, який доведеться підлаштовувати під кожну зміну. Ви хочете, щоб тест зламався, наприклад, якщо порядок елементів у масиві повернення змінюється?
  • Тестування структури повернутого значення.
    Для вихідної моделі це може бути перевірка кожного підмасиву як двох записів, один з a labelі один з valueключем.
  • Перевірка інструментів класу ArrayInterface.
  • Тестування класу передбачає, getOptions()навіть якщо цей метод не є частиною реалізованого інтерфейсу.

Кожну можливу річ, яку можна перевірити, врахуйте цінність, ремонтопридатність та вартість.

Підсумок

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


2
Чудова відповідь! Я хочу підкреслити частину "видалити тести, коли вони вже не надають значення" - іноді старі тести, які допомагали під час початкового розробника, просто перешкоджають довготривалому.
Фабіан Шменглер

1
Ви щойно відповіли на 2 інші питання, в яких я сумнівався. дякую
Маріус

6

На мою думку, немає загальної відповіді на "написання одиничних тестів для вихідних моделей, так чи ні"

Я писав одиничні тести для моделей джерел, але це були динамічні моделі джерела, які отримували зовнішні дані, і це має повний сенс.

Для джерельних моделей, які є не що інше, як прославлені масиви (як у вашому прикладі), я б не переймався написанням одиничних тестів. Але якимось чином потрібно переконатися, що ви не помилилися. Є кілька варіантів:

  1. одиничне випробування
  2. інтеграційний тест
  3. вручну подивіться на конфігурацію

Ви слідкуєте за TDD? Потім виберіть між (1) і (2) або обома. В іншому випадку виберіть між (2) та (3).


Якщо ви використовуєте вихідні моделі для параметрів конфігурації системи, тест інтеграції (один тест для всіх ваших параметрів конфігурації) може рендерувати розділ конфігурації та перевірити наявність <select>елементів і містять очікувані значення. Пам’ятайте, що мова йде не про тестування одного конкретного класу, а про те, щоб все було зв’язано правильно.


І як сказав @KAndy, в ідеалі вам не знадобиться стільки котлових плит, просто розгорніть базовий клас, який вже перевірений на блок, і замініть властивість або визначте значення у зовнішній конфігурації.

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


З таким базовим класом ваша вихідна модель може виглядати так:

class Type extends ArraySource
{
    const COLLABORATOR = 1;
    const EMPLOYEE = 2;
    protected $elements = [
        self::COLLABORATOR => 'Collaborator',
        self::EMPLOYEE     => 'Employee',
    ];
    protected $withEmpty = true;
    protected $translate = true;
}

Дякуємо за підтвердження. Я спробую перетворити свої прославлені масиви в список настроюваних параметрів, але чи те ж саме стосується моделей, які матимуть саме N варіантів? Наче модель "статусу" джерела.
Маріус

Я не бачу, як джерельна модель "статусу" нічим не відрізнятиметься від прикладу "типу автора"
Fabian Schmengler

тому що я можу використовувати значення 0 і 1 (як константи класу) на передній панелі, щоб фільтрувати, наприклад, включені об'єкти. Я маю на увазі в цьому випадку значення опцій мають логіку. вони не просто key=>valueпари.
Маріус

Але ця логіка не є частиною вихідної моделі, правда? Це означає, що це тут не має значення. Константи ви все ще будете використовувати в інших місцях. Я додав приклад, як я буду використовувати таку реалізацію.
Фабіан Шменглер

5

Як я повинен перевірити їх?

Я думаю, не слід.

Додайте код до системи збільшення витрат на підтримку та обслуговування, але процес тестування повинен бути LEAN .

Більше цього коду не повинно існувати. Я вважаю, що в Magento повинен бути один загальний декларативний спосіб визначення наборів варіантів для використання в різних місцях. І ваше небажання писати тести для цього класу показують мені запах поганого коду


1
Дякую. Отже, ви говорите, що ці параметри не повинні бути жорстко закодованими, а походять із конфігураційного файлу (наприклад, di.xml). Я можу зробити це. Але те ж саме стосується моделей джерел статусу? Я маю на увазі, якщо я маю той самий клас, що і вище, але лише з увімкненим статусом та вимкненим (1,0), чи повинен я використовувати той же підхід конфігурації? Якщо так, я хочу сказати, що це виглядає як надмірна інженерія для мене.
Маріус
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.