Как писать тесты без такого количества издевательств?

мы также можем использовать

(.*?\n)*?

для соответствия всем, включая новую строку без жадного

. Это сделает новую строку опцией

(.*?|\n)*?
21
задан Cliff 17 October 2012 в 09:41
поделиться

3 ответа

Наличие большого количества фиктивных объектов показывает, что:

1) У вас слишком много зависимостей. Еще раз взгляните на свой код и попробуйте разбить его на части. Особенно постарайтесь разделить преобразование и обработку данных.

Поскольку у меня нет опыта работы в среде, в которой вы разрабатываете. Позвольте мне привести в качестве примера свой собственный опыт.

В сокете Java вам будет предоставлен набор InputStream и OutputStream простой, чтобы вы могли читать данные и отправлять данные своему партнеру. Итак, ваша программа выглядит так:

InputStream  aIn  = aSocket.getInputStram();
OutputStream aOut = aSocket.getOutputStram();

// Read data
Object Data = aIn.read(); // Simplified read
// Process
if (Data.equals('1')) {
   // Do something
   // Write data
   aOut.write('A');
} else {
   // Do something else 
   // Write another data
   aOut.write('B');
}

Если вы хотите протестировать этот метод, вам придется создать макет для In и Out, для поддержки которого могут потребоваться довольно сложные классы.

Но если вы посмотрите внимательно, чтение из aIn и запись в aOut могут быть отделены от обработки. Таким образом, вы можете создать другой класс, который будет принимать входные и выходные объекты чтения.

public class ProcessSocket {
    public Object process(Object readObject) {
        if (readObject.equals(...)) {
       // Do something
       // Write data
       return 'A';
    } else {
       // Do something else 
       // Write another data
       return 'B';
   }
}

и ваш предыдущий метод будет:

InputStream   aIn  = aSocket.getInputStram();
OutputStream  aOut = aSocket.getOutputStram();
ProcessSocket aProcessor = ...;

// Read data
Object Data = aIn.read(); // Simplified read
aProcessor.process(Data);

Таким образом, вы можете протестировать обработку, практически не требуя имитации. вы можете проверить:


ProcessSocket aProcessor = ...;
assert(aProcessor.process('1').equals('A'));

Потому что обработка теперь не зависит от ввода, вывода и даже сокета.

2) Вы прошли модульное тестирование с помощью модульного теста, что должно быть проверено интеграцией.

Некоторые тесты не предназначены для модульного тестирования. тестирование (в том смысле, что оно требует излишне больших усилий и может не дать эффективного индикатора). Примерами такого рода тестов являются тесты, связанные с параллелизмом и пользовательскими интерфейсами. Они требуют различных способов тестирования, чем модульное тестирование.

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

EDIT

Если вы считаете, что уже разбили его на очень мелкие части, возможно, это ваша проблема.

Программные компоненты или субкомпоненты связаны друг с другом некоторым образом: символы объединяются в слова, слова объединяются в предложения, предложения в абзацы, абзацы в подраздел, раздел, главы и т. Д.

Мой пример говорит, что вам следует разбить подраздел на параграфы, а вы то, что вы уже преобразовали в слова.

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

Так что, возможно, вы нарушаете его настолько хорошо, что синтаксис языка заставляет эти зависимости и, в свою очередь, заставляет вас столько имитирующих объектов.

Если это так, ваше решение - сбалансировать тест. Если часть зависит от многих, и требуется сложный набор имитационных объектов (или просто больше усилий для его тестирования). Может быть, вам не нужно его тестировать. Например, если A использует B, C использует B, а B так чертовски сложно проверить. Так почему бы вам просто не протестировать A + B как единое целое и C + B как другое. В моем примере, если SocketProcessor так сложно протестировать, слишком сложно до такой степени, что вы потратите больше времени на тестирование и поддержку тестов больше, чем на его разработку, то это того не стоит, и я просто протестирую все сразу.

Не видя вашего кода (и с учетом того факта, что я никогда не разрабатываю CocaoTouch), будет сложно сказать. И, возможно, я смогу дать здесь хороший комментарий. Извините: D.

РЕДАКТИРОВАТЬ 2 Например, если A использует B, C использует B, а B так чертовски сложно проверить. Так почему бы вам просто не протестировать A + B как единое целое и C + B как другое. В моем примере, если SocketProcessor так сложно протестировать, слишком сложно до такой степени, что вы потратите больше времени на тестирование и поддержку тестов больше, чем на его разработку, то это того не стоит, и я просто протестирую все сразу.

Не видя вашего кода (и с учетом того факта, что я никогда не разрабатываю CocaoTouch), будет сложно сказать. И, возможно, я смогу дать здесь хороший комментарий. Извините: D.

РЕДАКТИРОВАТЬ 2 Например, если A использует B, C использует B, а B так чертовски сложно проверить. Так почему бы вам просто не протестировать A + B как единое целое и C + B как другое. В моем примере, если SocketProcessor так сложно протестировать, слишком сложно до такой степени, что вы потратите больше времени на тестирование и поддержку тестов больше, чем на его разработку, то это того не стоит, и я просто протестирую все сразу.

Без вашего кода (и с учетом того факта, что я никогда не разрабатываю CocaoTouch) будет трудно сказать. И, возможно, я смогу дать здесь хороший комментарий. Извините: D.

РЕДАКТИРОВАТЬ 2 слишком сложно до такой степени, что вы будете тратить больше времени на тестирование и поддержку тестов, а не на разработку, тогда это не стоит того, и я просто протестирую все сразу.

Не видя вашего кода (и с тем фактом, что Я никогда не занимаюсь разработкой CocaoTouch) будет сложно сказать. И, возможно, я смогу дать здесь хороший комментарий. Извините: D.

РЕДАКТИРОВАТЬ 2 слишком сложно до такой степени, что вы будете тратить больше времени на тестирование и поддержку тестов больше, чем на разработку, тогда это не стоит того, и я просто протестирую все сразу.

Не видя вашего кода (и с тем фактом, что Я никогда не занимаюсь разработкой CocaoTouch) будет сложно сказать. И, возможно, я смогу дать здесь хороший комментарий. Извините: D.

РЕДАКТИРОВАТЬ 2 Посмотрите на свой пример, довольно ясно, что вы имеете дело с проблемой интеграции. Предполагая, что вы уже тестируете воспроизведение фильма и пользовательского интерфейса отдельно. Понятно, зачем нужно столько фиктивных объектов. Если вы впервые используете такую ​​интеграционную структуру (этот параллельный шаблон), то эти фиктивные объекты могут действительно понадобиться, и вы ничего не можете с этим поделать. Это все, что я могу сказать :-p

Надеюсь, это поможет.

7
ответ дан 29 November 2019 в 22:13
поделиться

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

0
ответ дан 29 November 2019 в 22:13
поделиться

Я провожу довольно полное тестирование, но это автоматическое интеграционное тестирование а не модульное тестирование, поэтому у меня нет макетов (кроме пользователя: я издеваюсь над конечным пользователем, моделируя события ввода пользователя и тестируя / утверждая любой вывод пользователю): Следует ли тестировать внутреннюю реализацию, или только тестировать публичное поведение?


Я ищу передовой опыт использования TDD.

Википедия описывает TDD как,

метод разработки программного обеспечения, полагается на повторение очень короткий цикл разработки: сначала разработчик пишет отказавшую автоматизированную тестовый пример, который определяет желаемый улучшение или новая функция, тогда создает код для прохождения этого теста и наконец, преобразовывает новый код в t нарушена существующая функциональность)

  • Протестируйте новую функциональность:

    a. Конечный пользователь (я) осуществляет ввод данных через пользовательский интерфейс, предназначенный для реализации новой функции

    b. Конечный пользователь (я) проверяет соответствующий вывод программы, чтобы убедиться, что вывод правильный для данного ввода

  • Когда я провожу тестирование на шаге 4, тестовая среда фиксирует ввод пользователя и вывод программы в файл данных; тестовая среда может воспроизвести такой тест в будущем (воссоздать ввод пользователя и проверить, совпадает ли соответствующий вывод с ожидаемым выводом, полученным ранее). Таким образом, тестовые примеры, которые были запущены / созданы на шаге 4, добавляются к набору всех автоматизированных тестов.

  • Я думаю, что это дает мне преимущества TDD:

    • Тестирование связано с разработкой: я тестирую сразу после кодирования вместо перед кодированием, но в любом случае новый код тестируется перед регистрацией; не бывает непроверенного кода.

    • У меня есть автоматизированные наборы тестов для регрессионного тестирования

    Я избегаю некоторых затрат / недостатков:

    • Написание тестов (вместо этого я создаю новые тесты с помощью пользовательского интерфейса, который быстрее, проще и точнее к исходным требованиям)

    • Создание макетов (требуется для модульного тестирования)

    • Редактирование тестов при рефакторинге внутренней реализации (поскольку тесты зависят только от общедоступного API, а не от деталей внутренней реализации).

    0
    ответ дан 29 November 2019 в 22:13
    поделиться
    Другие вопросы по тегам:

    Похожие вопросы: