Ответ 1
Вы считали структуру unit test, например QUnitjs? Было бы довольно много работы, чтобы написать модульные тесты, но в итоге у вас будет повторяющаяся процедура тестирования.
Недавно мы обновили до новой сборки библиотеки миниатюр JavaScript.
После того, как команда тестирования провела значительную работу по обеспечению качества, было обнаружено, что в новой версии нашего minifier была проблема, которая изменила намерение и значение за блоком кода.
(Урок Life: не обновляйте JS minifiers, если вы действительно не уверены, что вам нужна новая версия.)
minifier используется для кода JavaScript на стороне клиента с большим вниманием к деятельности, связанной с DOM, а не почти так же "бизнес-логикой".
Упрощенный пример того, что было нарушено при обновлении minifier:
function process(count)
{
var value = "";
value += count; //1. Two consecutive += statements
value += count;
count++; //2. Some other statement
return value; //3. Return
}
Недопустимо неверно присвоено значение:
function process(n){var t="";return t+n+n,n++,t}
Хотя мы могли бы написать некоторые модульные тесты, чтобы уловить некоторые из возможных проблем, учитывая, что JavaScript тяжелый для взаимодействия с DOM (ввод данных и т.д.), очень сложно тщательно протестировать без тестирования пользователя (неавтоматизированным). Мы размышляли об использовании библиотеки JS в AST, такой как Esprima, но учитывая характер изменений, которые могут быть внесены в минифицированный код, это создало бы слишком много ложных срабатываний.
Мы также подумали о том, чтобы попытаться написать репрезентативные тесты, но это похоже на бесконечную задачу (и, вероятно, пропустит случаи).
FYI: это очень сложное веб-приложение с несколькими сотнями тысяч строк кода JavaScript.
Мы ищем методологию для тестирования процесса миниатюризации, а не "просто повторить все, тщательно и повторить". Мы хотели бы применить к процессу немного более строгое/научное.
В идеале мы могли бы попробовать несколько minifiers, не опасаясь, что каждый из них будет разбит наш код новыми тонкими способами, если бы у нас был лучший научный метод тестирования.
Обновление:
Одна из наших идей заключалась в следующем:
Это казалось хорошей идеей, однако различия были настолько распространены, что инструмент diff помечен почти каждой строкой как отличающийся.
Вы считали структуру unit test, например QUnitjs? Было бы довольно много работы, чтобы написать модульные тесты, но в итоге у вас будет повторяющаяся процедура тестирования.
Звучит для меня так, как будто вам нужно начать использовать автоматические тесты устройств в вашей CI (среда непрерывной интеграции). QUnit был запущен, но на самом деле QUnit - довольно слабая система тестирования, и его утверждения - это barebones как минимум (он даже не использует хороший синтаксис на основе утверждений). Он лишь незначительно квалифицируется как TDD и не очень хорошо справляется с BDD.
Лично я бы рекомендовал Jasmine с JsTestDriver (он может использовать другие UT-рамки или свои собственные, и это невероятно быстро... хотя у него есть некоторые проблемы с стабильностью, которые я действительно желаю, чтобы они исправили), и установки модульных тестов, которые могут проверять процессы минимизации несколькими сравнениями.
Некоторые сравнения, вероятно, должны быть:
Эти типы тестов - это то, почему вы, вероятно, выиграли бы от BDD-совместимой структуры, такой как Jasmine, в отличие от просто чистого TDD (например, результаты, которые вы обнаружили в визуальном различии, являющемся бесполезным), поскольку вы тестируете поведение и сравнения и состояния предшествующего/постсостояния функциональности/поведения, а не только если a истинно и по-прежнему истинно после анализа.
Настройка этих тестов модулей может занять некоторое время, но это итеративный подход с такой большой кодовой базой... быстро и рано проверять ваши начальные критические точки затухания или хрупкие точки, а затем распространять тесты на все (так, я всегда устанавливал свои команды в том, что все, что с этого момента не считается полным, и RC, если у него нет Unit Tests... ничего старого, у которого нет тестов Unit, и который должен быть обновлен/затронут/сохранен, должен иметь Unit Tests, написанный, когда они касаются, так что вы постоянно улучшаете и уменьшаете количество непроверенного кода более управляемым и логичным способом, увеличивая охват кода).
После того, как у вас есть тесты модулей и запущены в CI, вы можете привязать их к процессу сборки: сборочные сборки, которые не имеют модульных тестов, или когда модульные тесты не выдают оповещения, проактивно отслеживают каждую проверку и т.д. и т.д. Автоматическая генерация документации с помощью JSDoc3 и т.д. и т.д.
Проблема, которую вы описываете, - это то, что были построены для CI и Unit Tests, а более конкретно в вашем случае этот подход минимизирует влияние размера кодовой базы... размер не делает его более сложным, просто делает продолжительность дольше тестировать работу над доской.
Затем объедините это с JSDoc3, и вы станете лучше 90% от большинства магазинов переднего конца. В этот момент он невероятно прочен и полезен для инженеров, и он становится самовоспроизводящимся.
Я действительно мог бы продолжать и обсуждать эту тему, есть много нюансов, как вы подходите к ней и заставляете команду сплотиться за ней и сделать ее самообразованием и самовоспроизводящейся, а самое главное - писать проверяемый код... но с уровня концепции... записывать модульные тесты и автоматизировать их. Всегда.
Слишком длинные интерфейсные разработчики разрабатывали наполовину, не применяя фактическую инженерную строгость и дисциплину. Поскольку интерфейс стал все более и более мощным и горячим, это должно измениться и меняется. Концепция хорошо протестированных, хорошо охваченных, автоматизированных испытаний и непрерывной интеграции для приложений с интерфейсом /RIA является одной из огромных потребностей в этом изменении.
Вы можете посмотреть что-то вроде Selenium Web Driver, который позволяет автоматизировать тесты для веб-приложений в различных средах. Есть несколько облачных решений VM для проведения многоуровневого тестирования, поэтому вы не попадаете в Webkit, но не в IE.
Вы должны обязательно изучить использование исходных карт, чтобы помочь с отладки минимизированного JavaScript. исходные карты также будут работать с надмножествами JavaScript, такими как CoffeeScript или мой новый любимый TypeScript.
Я использую компилятор закрытия, который не только минимизирует, но и создает исходные карты. не говоря уже о том, что он самый агрессивный и производит самые маленькие файлы. Наконец, вам нужно знать, что происходит в минификсации и писать совместимый код, ваш примерный код может использовать некоторый рефакторинг.
ознакомьтесь с этой статьей на исходных картах: http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/
также проверьте документацию для компилятора замыкания, он получил предложения о том, как писать лучший код для минимизации: https://developers.google.com/closure/compiler/
Не тестовое решение, но как насчет перехода на TypeScript для написания больших приложений JS, таких как ваши?
Я тестировал его с помощью TypeScript и его минимального двигателя по умолчанию, и он отлично работает.
Предполагая, что ваш аргумент count
является числом.
Тип script будет:
class ProcessorX {
ProcessX(count: number): string {
var value = '';
value += count.toString();
value += count.toString();
count++;
return value;
}
}
Что создает js следующим образом:
var ProcessorX = (function () {
function ProcessorX() { }
ProcessorX.prototype.ProcessX = function (count) {
var value = '';
value += count.toString();
value += count.toString();
count++;
return value;
};
return ProcessorX;
})();
Затем округляется до:
var ProcessorX=function(){function n(){}return n.prototype.ProcessX=function(n){var t="";return t+=n.toString(),t+=n.toString(),n++,t},n}()
На jsfiddle.
Если ваш count
является string
, тогда fiddle.
мы используем компилятор замыкания в расширенном режиме, который как минимизирует, так и изменяет код, поэтому мы также скомпилируем наши модульные тесты, чтобы вы могли рассмотреть возможность минимизации своих тестов рядом с вашим кодом и запускать его таким образом.