Я использую Laravel 5.3 и, к сожалению, когда вы запускаете gulp tdd
, изменение на 1 файл запускает весь набор тестов, который теперь занимает почти 2 минуты. Что касается этого сообщения , я начал использовать Grunt для запуска определенных тестов при изменении определенных файлов. Пример файла Grunt ниже:
Gruntfile.js:
var phpunit = 'vendor/bin/phpunit '; grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), watch: { HomeSrc: { files: [ 'app/Http/**/HomeController.php', 'resources/views/home/**/*.php' ], tasks: ['HomeTests'] }, shell: { HomeTests: { command: phpunit + 'tests/Home' }, } });
Однако теперь мой Gruntfile становится довольно длинным, и я хотел бы запускать определенные тестовые файлы, когда они меняются.
Вопросов
Пример: при изменении tests/Home/IndexTest.php
автоматически запускаются vendor/bin/phpunit tests/Home/IndexTest.php
Хорошо, чтобы справиться с этим, вам нужно поймать совпадающее имя файла и динамически установить переменную для использования в качестве тестового файла. Это должно охватывать все базовые сопоставления, в которых имя тестового класса совпадает с именем файла, в котором оно находится, и поддерживает пространства имен, поэтому фильтр не будет загружать не все тестовые файлы с тем же именем класса.
Пример:
grunt.initConfig({ // .. snipped .. unitTestFile: 'to_be_replaced', watch: { php: { files: ["tests/**/*.php"], tasks: ["shell:unitTest"], options: { spawn: false } } }, shell: { unitTest: { command: "phpunit --filter <%= unitTestFile %>" } } grunt.loadNpmTasks('grunt-shell'); grunt.event.on('watch', function (action, filepath) { if (grunt.file.isMatch(grunt.config('watch.php.files'), filepath)) { var testFile = filepath.replace(/\\/g, '\\\\'); grunt.config('unitTestFile', testFile.replace(/.php/, '')); } }); };
Таким образом, файл с именем tests\unit\ApplicationTest.php
и в пространстве имен tests\unit
если он изменен, теперь будет запускаться в качестве теста. В результате команда:
phpunit --filter tests\\unit\\ApplicationTest // only runs in this namespace
Использование командной строки
перейдите в папку проекта, затем запустите соответствующую команду
Запуск всех файлов тестовых классов
phpunit
Запуск определенного файла тестового класса
phpunit ./tests/ExampleTest.php
или
Запуск определенного тестового примера из командной строки файла под командой
phpunit --filter testBasicExample ./tests/ExampleTest.php
Вы можете рассмотреть следующее решение:
.json
который включает в себя массив файлов / путей, которые вы собираетесь смотреть и в конечном итоге выполняете как единичный тест. watch
и для shell
. (Оба вышеописанных момента, безусловно, помогут уменьшить количество строк кода.)
Следующий пример демонстрирует это:
Предположим, у нас есть файл с именем test-mappings.json
с каждым пути к файлу (в соответствии с точкой 1), указанным как указано и сохраненным в корневом каталоге проектов вместе с Gruntfile.js
[{ "file": "tests/testA.php" },{ "file": "tests/testB.php" },{ "file": "tests/testC.php" },{ "file": "tests/testD.php" }]
Используйте Gruntfile.js
настроенный следующим образом:
module.exports = function(grunt) { 'use strict'; var mapping = grunt.file.readJSON('test-mappings.json'), watch = {}, shell = {}; // Dynamically create the targets for 'watch' and 'shell' tasks. mapping.forEach(function(config, index) { watch[index] = { files: [config.file], tasks: [index] }; shell[index] = { command: 'vendor/bin/phpunit ' + config.file }; // Register the shell target grunt.registerTask(index, ['shell:' + index ]); }); grunt.initConfig({ watch: watch, shell: shell }); // Handy for dev - logs generated targets //grunt.log.writeln(JSON.stringify(grunt.config(), null, 2)); require('load-grunt-tasks')(grunt); grunt.registerTask('default', [ 'watch' ]); };
Обратите внимание на каждую цель как для watch
и для shell
Задачи динамически генерируются и настраиваются в соответствии с списком файлов, указанным в test-mappings.json
.
Чтобы увидеть конфигурацию автоматически сгенерированных целей, вы можете просто раскомментировать строку, читающую grunt.log.writeln...
перед запуском $ grunt
, и она будет напечатана на консоли.
$ grunt
через CLI. test-mappings.json
и сохраните его. watch
затем выполнит соответствующую команду shell
. В настоящее время файлы перечислены во внешнем .json
, однако они могут находиться в Gruntfile.js
и быть назначены переменной, если это необходимо.
Или файлы могут быть получены с использованием подходящего шаблона (ов) глобуса и при необходимости изменить сущность выше. В этом случае вместо этого будет использоваться итерация над grunt.file.expand , а не текущий массив mapping
.
Для вышеупомянутой основы были использованы следующие плагины grunt:
Грунт-вно-часы
Грунт-оболочка
нагрузка-Грунт-задача
Следующий Gruntfile.js
предназначен для подхода, ранее упомянутого в пункте №. два в разделе Дополнительные примечания (т. е. Globbing вместо внешней конфигурации файла JSON).
module.exports = function(grunt) { 'use strict'; var tests = 'tests/**/*.php', watch = {}, shell = {}; grunt.file.expand(tests).forEach(function(filepath, index) { watch[index] = { files: [filepath], tasks: [index] }; shell[index] = { command: 'vendor/bin/phpunit ' + filepath }; grunt.registerTask(index, ['shell:' + index]); }); grunt.initConfig({ watch: watch, shell: shell }); require('load-grunt-tasks')(grunt); grunt.registerTask('default', [ 'watch' ]); };