Подход к модульному тестированию больших пакетов динамически генерируемых строк

#javascript #unit-testing #batch-processing

#javascript #модульное тестирование #пакетная обработка

Вопрос:

В моем веб-приложении есть класс для анализа и манипулирования данными, хранящимися в хэше URL, которые выглядят примерно так

 http://myapp.com/#!/location/hornsea/season/spring/facilities/ shop swimming-airport/size/50
  

Чтобы иметь возможность модульного тестирования различных перестановок, я сохраняю некоторые фрагменты URL в объекте (например

 var fragments {
    valid: ["/location/hornsea", "/season/winter","/size/50"],
    invalid: ["location/hornsea", "/seasonwinter","/size/fifty"]
}
  

И затем, перед запуском своих тестов, я динамически создаю все возможные допустимые и недопустимые URL-адреса, а затем перебираю их, добавляя тест для каждого URL.

Это нормально, когда я запускаю тест на достоверность URL-адреса, поскольку я просто проверяю наличие true или false в моем методе isValid (), но при тестировании на получение параметров из URL-адреса я не знаю, как подойти к проблеме — я должен сравнить возвращаемое значение (например, {location: «hornsea»»}) с ожидаемым значением, но поскольку строка, подлежащая анализу, динамически создается перед запуском теста, у меня нигде не хранится ожидаемое значение.

Теперь я не уверен, является ли мой подход излишним — должен ли я заботиться о тестировании всех методов на всех возможных структурах URL? Могу ли я настроить тесты, которые выполняются со всеми возможными URL-адресами, когда это легко сделать, но запускаются с более управляемым подмножеством, когда мне нужно иметь более точный контроль над тестами, и при этом все же удается охватить все возможные варианты. т. Е. могу ли я написать набор тестов, в котором тестирование

 http://myapp.com/season/autumn
  

достаточно адекватен, чтобы охватить и такие примеры, как следующие.

 http://myapp.com/location/dungeness/season/autumn
http://myapp.com/location/camberwell/seasonautumn
  

И как я могу быть уверен, что я не оставил никаких пробелов? Существуют ли какие-либо общие подходы к такого рода проблемам, или это что-то очень специфичное для конкретного приложения?

Ответ №1:

Вы можете проверить это с помощью теста обратной функции. Вы должны написать функцию (encode), которая является функцией, обратной вашему анализатору URL. Функция encode создает URL-адрес из допустимых входных значений. Тест имеет вид:

 input = {"location" : "hornsea", "season" : "winter", "size" : "50"}
assert input == parse(encode(input))
  

Чтобы получить хорошее покрытие, вы можете использовать одну из реализаций Quickcheck для генерации входных значений. С помощью сгенерированных значений вы можете создавать подмножества допустимого входного параметра или изменять параметры в случайном порядке.

Комментарии:

1. Это выглядит многообещающе, хотя все еще предстоит проделать большую работу по сохранению значения рядом со строкой URL и рассмотрению случаев, когда структура URL (а не только значения) неверна

2. Обычно вы бы не сохраняли значения, а генерировали их. Недопустимый URL — это тот, в котором отсутствуют параметры, верно?

3. Не обязательно. На самом деле, обычно отсутствие параметра — это нормально. Примером недопустимого URL может быть /location//hornsea , или /blocation / hornsea, или наличие конфликтующих (указание местоположения, а также региона) или дублирующихся (указание двух разных местоположений) — всевозможные способы сделать его недействительным, поэтому необходимо где-то хранить примеры допустимых / недействительных фрагментов URL, поскольку любой код, который вычисляет их с нуля, был бы сложным и нуждался бы в таком же большом тестировании, как и само приложение

4. Ваше приложение является тестом для теста. Если тест завершается неудачей, либо приложение сломано, либо тест. Глядя на недопустимые примеры, такие как /location//hornsea или / blocation / hornsea, есть очевидные алгоритмы для описания конструкции. Когда URL состоит из пары префикс ключ: значение, разделенных одной косой чертой, тогда все остальное недопустимо.