[Плагин Maven] Автоматически генерировать тестовый код Mock

Spring Boot

primo-generator-mock-test

адрес проекта:GitHub.com/Чэнь Хаосянь…

представлять

Вы все еще изо всех сил пытаетесь написать много модульных тестов, вы все еще пытаетесь создать ценность класса-оболочки? Вот подключаемый модуль Maven, который автоматически генерирует фиктивный код модульного тестирования, который решает проблему, связанную с тем, что разработчики тратят много времени на модульное тестирование, и всесторонне оптимизирует эффективность тестирования разработчиков и время тестирования.

Обратите внимание, что этот подключаемый модуль в настоящее время не может выполнить все фиктивные тесты, поэтому вам не нужно изменять строку кода.На данный момент вам необходимо внести некоторые изменения на основе кода фиктивного теста, сгенерированного primo-generator-mock. -test, такие как покрытие ветвей и использование утверждений.

Цель этого плагина: понять, что разработчики больше не будут писать ни строчки кода фиктивного теста, primo-generator-mock-test поможет вам всего этого достичь
Видение: уменьшить нагрузку разработчиков на тестирование, сосредоточиться на развитии бизнеса и итерациях.

После моего личного использования, а также моего использования «толкать (цян) широко (туй)» в команде, со статистической точки зрения, это может сократить использование фиктивных тестов как минимум на 30-50% времени.
(Этот проект в настоящее время используется несколькими командами в нашей компании, что экономит много времени на модульное тестирование для членов команды, поэтому я поделюсь им здесь)

использовать

1. Сначала зависит от плагина:

Последняя версия

Последняя версия: 1.0.0

Простейшая конфигурация:


<plugin>
    <groupId>wiki.primo.generator</groupId>
    <artifactId>primo-generator-mock-test-maven-plugin</artifactId>
    <version>(版本号)</version>
    <configuration>
        <testPackageName>(待测试类的包名,0.1.0-SNAPSHOT+支持配置多个,英文分号进行隔开)</testPackageName>
    </configuration>
</plugin>

(Используйте самую простую конфигурацию, вы можете использовать ее, вам не нужно смотреть вниз, если вы чувствуете, что позже будет слишком много объяснений)

Пример:

<plugin> 
    <groupId>wiki.primo.generator</groupId>
    <artifactId>primo-generator-mock-test-maven-plugin</artifactId>
    <version>1.0.0</version> 
        <configuration>
            <testPackageName>wiki.primo.generator.primogeneratormocktestdemo.service.impl</testPackageName> 
        </configuration>
</plugin>

2. Сгенерируйте тестовый код

Запустите команду primo-generator-mock-test:test плагина maven в модуле проекта, который представил плагин

mvn primo-generator-mock-test:test

Запустите mvn primo-generator-mock-test:test напрямую, чтобы загрузить файлы шаблонов и создать тестовые классы.

Связанная конфигурация:<configPath></configPath>Заполните путь, относительный путь — это корневой путь текущего запущенного проекта. (Путь загрузки по умолчанию: /src/main/resources/test/template)
При первом запуске команды primo-generator-mock-test:test для запуска плагина вы можете загрузить файл конфигурации по соответствующему пути.

Имя файла конфигурации может быть установлено с помощью<configFileName>primo-generator-mock-test.ftl</configFileName>Задает имя файла конфигурации. (имя файла по умолчанию — primo-generator-mock-test.ftl)

3. Внедрите фиктивные зависимости

Плагин автоматической генерации тестового кода
Метод фиктивного тестового класса, генерируемый плагином, зависит от powermock&mockito.Рекомендуется напрямую ввести следующие зависимости (никакие зависимости не влияют на работу плагина)

<dependency>
    <groupId>wiki.primo.generator</groupId>
    <artifactId>primo-generator-mock-test-jar</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <scope>test</scope>
</dependency>

4. Связанные свойства конфигурации в конфигурации

Под модулем имени проекта подключаемого модуля запустите команду megatron:test подключаемого модуля, чтобы сгенерировать тестовые случаи в соответствующем тестовом пути.

Необходимый

  • <testPackageName>: требуется) Чтобы настроить имя пакета, который должен генерировать модульные тестовые случаи, не заполняйте имя пакета, в котором находится интерфейс, вам нужно реализовать имя пакета класса, он будет проходить все классы и методы в пакете и подпакеты (поддерживает настройку нескольких имен пакетов, английские точки с запятой разделяют разные имена пакетов).

Индивидуальные классы могут быть настроены. Например: wiki.primo.generator.primogeneratormocktestdemo.service.impl.UserServiceImpl.java Обратите внимание, что настройка одного класса должна заканчиваться на .java.

Неподдерживаемые классы:

  • интерфейс
  • перечислить
  • абстрактный класс
  • частный класс

необязательный

Примечание: пакеты jar до версии 1.0.0 не загружаются в центральный репозиторий.

1.0.0
  • <jsonConfigPath>: путь к файлу конфигурации json, defaultValue = "/src/main/resources/test/template/"
  • <jsonConfigFileName>: имя файла конфигурации json, defaultValue = "primo-generator-mock-test.json"
  • <isDownloadTemplateFile>: следует ли загружать файл конфигурации шаблона на локальный сервер, значение по умолчанию — true.
  • <isDownloadJsonFile>: следует ли загружать файл конфигурации json на локальный сервер, значение по умолчанию — true.
0.1.1-SNAPSHOT
  • <configPath>: путь для загрузки файла конфигурации

  • <author>: имя автора

  • <configFileName>: имя загруженного файла конфигурации

  • <isGetChildPackage>: настроить, будет ли пакет testPackageName рекурсивно получать классы в подпакетах (по умолчанию true).

  • <isMockThisOtherMethod>: Настройте, следует ли имитировать родительский класс и нетестовые методы своего собственного тестового класса (по умолчанию true), вызов метода родительского класса/этого класса должен использовать это для вызова, текущая версия не поддерживает фиктивные

  • <isSetBasicTypesRandomValue>: настроить, чтобы значение базового типа генерировалось случайным образом (по умолчанию false).

  • <setStringRandomRange>: Настройте количество цифр для случайного значения строки (например: «10», что означает 10 случайных буквенно-цифровых символов).

  • <setIntRandomRange>: настроить диапазон случайных значений типа int/Integer (например: «0,1000», что означает значение int в диапазоне [0,1000), фиксированное значение можно настроить как «0», тогда значение int фиксируется на 0)

  • <setLongRandomRange>: настроить диапазон случайных значений типа long/Long (правила настройки аналогичны setIntRandomRange)

  • <setBooleanRandomRange>: настроить диапазон случайных значений логического/логического типа (например: если настроено как "true"/"false", это означает фиксированное значение, а любое другое значение означает, что true и false являются случайными)

Функция версии

0.2.1-SNAPSHOT

  • fix - исправить ошибку, из-за которой тестовый код не мог быть сгенерирован под windows

0.2.0-SNAPSHOT

  • Поддержка конфигурации json, построение значения параметра через json
    • Поддерживается только назначение параметров фактического метода, а назначение параметров макета временно не поддерживается.
    • На этот раз для конфигурации поддерживается только значение пользовательского типа.

Ниже приводится описание свойств в конфигурации json:

{
"isOpen": "是否开启json配置-默认false",
"list":
  [
    {
      "scope":"作用域:全局(global)、包(package)、类(class)、方法(method) - 默认全局",
      "scopeValue": "作用域的值,global则无需配置该值,package则为包名,class则为类名,method则为方法名", 
      "fullyType": "类型的全限定名称",
      "value":{
        "若type=base,则该值固定为value":"值",
        "若type=custom,自定义类型,value下的key为fastjson序列化的属性名称":"值"
      }
    }
  ]
}
  • удалить устаревшую конфигурацию
  • fix - Исправлена ​​ошибка, из-за которой файл конфигурации не мог быть загружен при изменении configFileName.

инструкции по настройке json

  • Вы можете настроить значение параметра типа параметра, настроив json
  • Область действия: глобальная, пакет, класс, метод

Приоритет конфигурации значения параметра: Настройка через необязательные атрибуты плагина

0.1.1-SNAPSHOT

  • testPackageName настраивает несколько пакетов, поддерживает разрывы строк между точками с запятой и пробелами
  • testPackageName может настроить один класс реализации. Например: wiki.primo.generator.primogeneratormocktestdemo.service.impl.UserServiceImpl.java Обратите внимание, что настройка одного класса должна заканчиваться на .java.
  • Внешним зависимостям нужно только импортировать primo-generator-mock-test-jar.

0.1.0-SNAPSHOT

  • Решите проблему, что количество параметров одинаково, сообщается о фиктивной ошибке перегруженного метода, а код аннотируется.
  • Решить проблему изменения имени параметра фиктивного метода
  • Загружая классы во внутреннем загрузчике в память, больше не нужно вручную зависеть от требуемых классов в плагине, то есть больше не нужно настраивать сторонние зависимости
  • Его можно запускать без сети. Он использовался для загрузки файлов через сетевые потоки. Эта версия была модифицирована для чтения из пакетов jar.
  • Добавить настраиваемый каталог тестового класса

0.0.1

Новые/оптимизированные функции

  1. Поддержка общедоступных нестатических методов во всех классах пакета для создания тестовых методов.
  2. Поддерживает конфигурацию фиктивного пакета и удаляет все методы класса в фиктивном пакете.
  3. Поддерживает автоматическое назначение базовых типов и типов-оболочек
  4. Добавлена ​​поддержка параметров перечисления
  5. Типы параметров, которые необходимо пропустить, можно настроить, а имя пакета можно настроить напрямую, а построение всех классов в пакете будет пропущено (используется для пропуска построения интерфейса, напрямую присваивать значение null)
  6. Оптимизируйте полное имя как короткое, используйте импорт для импорта пакета, если в имени есть повторяющиеся классы, используйте полное имя.
  7. Поддержка конфигурации, чтобы выбрать, следует ли автоматически издеваться над родительским классом и его собственным нетестовым методом — по умолчанию true
  8. Поддержка настройки случайной настройки базового типа объекта / использование значения по умолчанию null
    А. Длина случайной строки: 10 цифр и букв, сгенерированных с использованием UUID JDK для обеспечения уникальности.
    б. случайное целое число: [0,1000)
    C. Случайный байт: [0,1)
    г. Случайный короткий: [0,127)
    е. случайный двойной: [0,00,10000,00)
    е. случайное число с плавающей запятой: [0,00f, 10000,00f)
    г. Случайный длинный: [0L, 100000L)
    г. Случайный символ: цифра/буква
  9. Каждый тестовый класс использует унифицированную аннотацию перед для фиктивного метода.(Учитывая макет каждой ветки позже, если вы согласитесь на макет, это приведет к тому, что ветка не будет полностью покрыта)
  10. Класс с фиктивной аннотацией использует полное имя, оптимизирует его как аббревиатуру, импортирует класс, повторяет аббревиатуру класса, первый класс использует аббревиатуру, а следующие классы используют полное имя.
  11. Больше не поддерживается настройка классов под другими пакетами для мокинга, мокируются все методы нетестовых классов, а также мокируются приватные методы тестовых классов.
  12. Тестовые классы сгенерированы, покрытия нет
  13. Поддерживает загрузку и создание сторонних классов пакетов.
  14. Для некоторых свойств без сеттера также выполняется установка значения; ожидание: для значения свойства без сеттера установка значения не выполняется
  15. Поддерживает настройку диапазона случайных значений типов string, int, long и boolean.
  16. Поддерживает настройку метода set, который генерирует атрибуты родительского класса для установки значения, значение по умолчанию — true, а сгенерированный метод set содержит атрибуты родительского класса (обратите внимание, что если родительский класс отсутствует в текущем проекте, вам необходимо ввести зависимости пакета в плагине)
  17. Добавлен метод в тестовый класс для поддержки дополнительного создания фиктивных тестовых методов.
  18. Поддержка одновременной генерации тестовых классов в разных пакетах
  19. Исходный файл конфигурации загрузки больше не требуется, запустите генерацию напрямую, автоматически определите, следует ли загружать, загрузите файл конфигурации перед его созданием без загрузки

Планирование других функций

  • Файл конфигурации можно настроить так, чтобы он не загружался на локальный сервер, загрузка по умолчанию
  • Поддержка настройки уровня журнала, которая удобна для пользователей для отладки
  • Поддержка if-else для создания нескольких фиктивных методов ветвления
  • Значение параметра метода поддерживает файл json для конфигурации.
  • Проверьте процент покрытия метода класса реализации кода и уведомите группу DingTalk.
  • Поддержка простого задания построения набора
  • Поддерживает настройку макетов статического метода и требует настройки полного имени статического класса (статические методы не рекомендуются для имитации)
  • Приватный метод в тестовом классе мокится, а приватный метод специально открывается для генерации мок-теста, по умолчанию не поддерживается и требует настройки (приватный метод не рекомендуется для мокинга)
  • В одном и том же тестовом методе есть повторяющиеся имена фиктивных методов (количество параметров разное), которые невозможно различить. Имитируется только первый метод, и будет дублироваться генерация фиктивного кода; Ожидание: поддержка фиктивных методов с одинаковыми имя
  • Невозможно поддерживать методы с одинаковыми именами (одинаковое количество параметров, разные типы параметров), сгенерированная ссылка на фиктивный метод будет неоднозначной; ожидаем: ссылка на фиктивный метод ясна (решается путем сопоставления типа параметра)
  • Построение вложенных пользовательских параметров не поддерживается; ожидается: поддерживается построение многоуровневых параметров.
  • Конструкции наборов не поддерживаются; ожидаем: конструкции наборов поддерживаются
  • Возвращаемое значение фиктивного метода не поддерживает настройку, а форма должна возвращать значение null; ожидание: поддержка пользовательского/сгенерированного значения фиктивного возвращаемого значения.
  • Не поддерживает макеты пользовательского диспетчера транзакций Spring DataSourceTransactionManager; ожидается: макеты, поддерживающие пользовательские транзакции
  • Поддержка назначения многоуровневого построения параметров
  • Макеты, поддерживающие перегруженные методы
  • Поддержка конфигурации утверждений
  • YML-файл конфигурации для значений параметров
  • Сгенерированный тестовый метод может настроить, следует ли компилировать и сообщать об ошибках, заставляя разработчиков активно выполнять модульное тестирование.

Уведомление

Настройте фиктивный статический метод: @RunWith(MockitoJUnitRunner.class) используется по умолчанию.Если настроен фиктивный статический метод, будет использоваться @RunWith(PowerMockRunner.class).

Используя классы PowerMockRunner и MockitoJUnitRunner, ни один из них не может поддерживать автоматически внедряемые макеты (такие как универсальный baseMapper в универсальном родительском классе уровня службы в mybatis) свойств в родительском классе (класс реализации службы также внедряется с этот класс). Это связано с тем, что класс Mock будет рассматривать эти два класса как разные экземпляры и будет имитировать только базовый класс, который вы внедряете в класс реализации службы, но не может внедрять преобразователь в родительский класс класса реализации службы.
Например: класс реализации службы


public class WorkFlowServiceImpl extends ServiceImpl<WorkFlowMapper, WorkFlowEntity> implements IWorkFlowService {
    @Autowired
    private WorkFlowMapper workFlowMapper;
    //...
}

Родительский класс ServiceImpl:

public class ServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
    @Autowired
    protected M baseMapper;
    //...
}

При использовании в WorkFlowServiceImpl:

baseMapper.deleteById("1");

В пробном тестовом классе:


@RunWith(PowerMockRunner.class)
@PowerMockIgnore("javax.management.*")
@PrepareForTest({BeanConvertUtil.class, FieldBaseDto.class})
public class WorkFlowServiceImplTest {
    @InjectMocks
    private WorkFlowServiceImpl workFlowServiceImpl;
    @Mock
    private WorkFlowMapper workFlowMapper;
    //...
}

Экземпляр baseMapper нельзя имитировать, потому что baseMapper и workFlowMapper не являются одним и тем же экземпляром! Здесь мы можем только смоделировать workFlowMapper.

В настоящее время baseMapper можно снова внедрить в класс реализации сервисного уровня, а макет также можно выполнить с помощью PowerMockRunner.class.

Классу реализации уровня службы не рекомендуется использовать родительский класс службы универсального базового класса для вызова универсального преобразователя для работы со слоем базы данных! Вы можете ввести Mapper, а затем позвонить.

Используйте опыт

Существует 199 тестовых методов, охватывающих в общей сложности проверенные методы 309. После использования primo-generator-mock-test для генерации на фиктивную оптимизацию ушло всего более 3 часов (оптимизирован был только метод запуска отчетов об ошибках, и нет идеального был проведен тест ветвей).

По моему предыдущему опыту, если все написать самому и все пойдет хорошо, mock test 199 методов займет как минимум в несколько раз больше времени.
(Этот тестовый проект представляет собой проект, использующий mybatis-plus. Многие классы реализации сервисного уровня напрямую используют метод родительского класса, что делает макет очень хлопотным и задерживает некоторое время. Другие проекты сэкономят больше времени.)

Тестовый класс:

测试类

метод тестирования:

测试方法

Данные о покрытии сотовой связи:

总覆盖率


单元覆盖数据