Пытаемся понять юнит-тесты на примере модуля transliterate_filenames

ivnish 29 ноября 2021 в 10:12
1

Многие программисты не понимают зачем нужны юнит-тесты. И это логично: сначала ты пишешь код, а потом вынужден снова писать код, который будет тестировать твой код. Давайте попытаемся понять зачем нам нужно юнит-тестирование на примере модуля transliterate_filenames.

Этот модуль был разработан в компании РаДон и выложен на drupal.org в свободный доступ. Я тоже к доработке этого модуля руку приложил и являюсь его мейнтейнером. Модуль добавляет необходимый в Drupal 8/9 функционал транслитерации и санитации имен файлов загружаемых на сайт.

Так при чем тут юнит-тестирование? В модуле есть сервис SanitizeName, который в свою очередь содержит функцию sanitizeFilename, которая и выполняет основной функционал модуля - транслитерирует и санитирует.

Создаем функцию providerSanitizeName, которая будет возвращать массив в виде "было - должно стать"

<?php
  
/**
   * Provides data for self::testSanitizeName().
   */
  
public function providerSanitizeName() {
    return [
      
// Transliterate Non-US-ASCII.
      
['ąęółżźćśń.pdf''aeolzzcsn.pdf'],
      
// Remove unknown unicodes.
      
[chr(0xF8) . chr(0x80) . chr(0x80) . '.txt''.txt'],
      
// Force lowercase.
      
['LOWERCASE.txt''lowercase.txt'],
      
// Replace whitespace.
      
['test whitespace.txt''test-whitespace.txt'],
      [
'test   whitespace.txt''test-whitespace.txt'],
      
// Remove multiple consecutive non-alphabetical characters.
      
['---___.txt''-_.txt'],
      [
'--  --.txt''-.txt'],
    ];
  }
?>

А затем указываем ее в функции testSanitizeName как dataProvider

<?php 
/**
   * Tests sanitize filename.
   *
   * @param string $filename
   *   The tested file name.
   * @param string $expected
   *   The expected name of sanitized file.
   *
   * @dataProvider providerSanitizeName
   */
  
public function testSanitizeName($filename$expected) {
    
$sanitize_filename = \Drupal::service('transliterate_filenames.sanitize_name');
    
$this->assertEquals($expected$sanitize_filename->sanitizeFilename($filename));
  }
?>

С полным текстом файла юнит-теста можно ознакомиться тут

Как это работает? При ручном запуске тестов или при добавлении кем-то патча на drupal.org система будет проверять значения из нашего массива "было - должно стать" и если что-то не сойдется, значит сломали функцию транслитерации и нужно еще более внимательно изучать что делает предлагаемый патч.

Вывод: юнит-тесты позволяют экономить время и не тестировать вручную каждый раз один и тот же функционал при внесении изменений в код.

Автор

ivnish Drupal FullStack Developer, модератор drupal.ru