Настройка IDE для автоматического запуска тестов

Original author: Miško Hevery
  • Translation
Источник

Блог Google Testing

Когда я программирую, то сначала пишу тесты. Частый ручной прогон тестов может превратиться в утомительное занятие.

Опишу обычный сценарий разработки кода:

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


Что я хочу, так это иметь возможность, чтобы моя среда разработки (IDE) автоматически запускала тесты каждый раз, когда я делаю изменения в коде. Этот способ подразумевает, что когда я делаю десять маленьких изменений, то и IDE запускает тесты десять раз. И тогда в тот момент, когда вы делаете что-то, как вы думаете, простое, но которое в реальности ломает программу, IDE укажет вам на ваши ошибки. Вы сможете просто нажать Ctrl+z (отмена) и получить обратно работающий код.

Что мне нужно, так это то, чтобы моя IDE запускала тесты каждый раз, как только я сохраняю код. Для этого тесты должны быть быстрыми, поскольку мое терпение после нажатия Ctrl+s составляет только 2 секунды. Что-либо длящееся больше будет меня раздражать. Если ваш набор тестов прогоняется медленно, то сделайте им рефакторинг.

Эта техника подходит только к быстрым модульным тестам (unit-test). Я не запускаю мои сценарные тесты как событие по Ctrl+s.


Я знаю, как это сделать в Eclipse, но, возможно, те из вас, кто пользуется другими IDE, смогут сделать подобную вещь. Я уже подготовился и создал проект, который вы можете скачать.
Eclipse IDE
Вот какая была последовательность действий.
  1. Создайте проект. Eclipse имеет такую удобную вещь как запуск компиляции в фоновом режиме при каждом сохранении.
  2. Создайте код для junit для запуска ваших тестов, как это показано здесь: AllTests.java
    import junit.framework.TestSuite;
    import junit.textui.TestRunner;
    
    public class AllTests {
       public static void main(String[] args) {
          TestSuite suite = new TestSuite();
          suite.addTestSuite(GreeterTest.class);
          TestRunner.run(suite);
       }
    }
    

  3. Создайте ant файл, который будет запускать ваш тест из папки для скомпилированных файлов eclipse. В этом файле не будет инструкций для компиляции — это сделает за вас eclipse:
    build.xml
    <project>
     <target name="eclipse-test-runner">
      <java classname="AllTests" classpath="bin:libs/junit.jar">
      </java>
     </target>
    </project>
    

  4. Укажите eclipse? у запускать ant-цель (target) после каждой компиляции. Для этого надо создать новый сборщик (builder).
    1. Откройте свойства проекта, выбрав пункт меню Project -> Properties.
    2. Добавьте новый «Ant Builder» сборщик после Java Builder: Builders -> New… -> Ant Builder.
    3. Дайте вашему сборщику красивое имя. И сделайте следующее на каждой вкладке (я считаю, что в eclipse содержится баг, и вы должны каждый раз нажимать Apply (применить) каждый раз, когда вы изменили данные в вкладке):
      • Main: Выберите сборочный файл и базовую директорию (это устанавливает какой ant-файл использовать).
      • Targets: Выберите вашу ant-цель для: «After Clean», «Manual Build», и «Auto Build» (наиболее важная) (Это указывает, что после каждой компиляции должна быть выполнена ant-цель).
      • Build Options: Установите флаг «Specify working set» и выберите все ваши папки с исходниками. (Это определяет изменения в каких файлах будет вызывать этот сборщик — в
        нашем случае, это изменения любого файла.)

Создание сборщика (Ant Builder):


Вкладка Main:


Вкладка Targets:

Пример запуска: (не очень хорошее качество, но разобрать можно)



Или просто скачайте (zip) их моего репозитория проект, импортируйте его в eclipse и пробуйте.

Удачного тестирования...

Об авторе: Мишко Хевери (Miško Hevery)


… работает В Google инструктором по Гибкой методологии разработки (Agile Coach)и обучает гуглеров культуре автоматического тестирования. Его деятельность помогает Google выпускать частые релизы веб-приложений с постоянно высоким качеством. До этого Миско работал в Adobe, Sun Microsystems, Intel и Xerox (и это не полный список), где он стал экспертом в разработке веб-приложений на Java, JavaScript, Flex и ActionScript. Он много участвует в Open Source сообществе и является автором нескольких проектов с открытим кодом. Недавние его интересы в Разработке через тестирование (Test-Driven-Development ) вылились в реализацию Обозревателя тестируемости (Testability Explorer) и в JsTestDriver, с которыми он надеятся изменить культуру тестирования в open source сообществе.

Проекты с открытым кодом:


Upd 1: существуют хорошие плагины для Eclipse и IntelliJ, которые помогают автоматически запускать тесты — Infinitest
Upd 2: Перевел статью, которая даст дает объяснение понятию модульного теста и избавит от некоторых вопросов в комментариях.
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 32

    +3
    А что делать если у меня прогон тестов занимет 2 часа?
      +8
      Мэтры говорят по этому поводу следующее:
      Unit tests run fast. If they don't run fast, they aren't unit tests.
        0
        Ваши метры наверное не писали ничего сложнее «Здравствуй Мир».

        Попробуйте написать тест для алгоритма O(e^n).
          +1
          Тут, скорее всего, ошибка в определении того, что считать unit-тестами. Есть статья того-же автора по поводу классификации тестов.

          Так вот следуя этой классификации unit-тесты — это тесты, которые выполняются очень быстро и проверяют конструкции с условиями перехода (if...else, циклы), которые являются основными источниками багов в коде.

          Функциональные и приемочные тесты, чаще всего, выполняются намного дольше и их не следует включать в набор тестов для фонового тестирования в IDE.
            0
            юнит тесты должны быть атомарными, собственно, как и методы, для которых они пишутся, в этом идея
              0
              Если следовать переводу unit и основам XP, то данный вид тестирования подразумевает тестирование отдельных элементов, в частности для ООП это будут методы классов. Но с учетом эффективности времени разработки обычно тестируется уже взаимодействие между несколькими классами, которое и занимает длительное время.
                +3
                да, юнит-тестирование подразумевает именно тестирование отдельных элементов, но тестирование кросмодульного взаимодействия это уже не есть юнит-тестирование) функциональные и приемочные тесты — это уже другой этап тестирования
                +1
                habrahabr.ru/blogs/testing/64874/
                Перевел статью, которая даст дает объяснение понятию модульного теста и избавит от некоторых вопросов в комментариях.
                +3
                Ваши метры наверное не писали ничего сложнее «Здравствуй Мир».
                Eah, eah...

                Попробуйте написать тест для алгоритма O(e^n).
                В чём проблема? Не обязательно тест запускать на наборах данных при n→∞. А при малых n тесты будут отрабатывать быстро.
              0
              Для сложных систем данный вариант не подходит. И понятие юнит-тестирования на текущий момент стало весьма растянутым.

              Вариант решения — ночные билды с прогоном всех тестов.
                0
                нет, вариант решения — это всё-таки билдбот с сеткой билдеров на каждый коммит.
                0
                Использовать Continious Integration!

                Рекомендую JetBrains TeamCity ;)
                0
                Это только для быстрых тестов (это указано в статье). Для этого можете выделить набор тестов, который будет выполняться за короткое время (2 секунды самое оптимальное).
                  0
                  Так же вариантом является создание нескольких сборщиков, каждый их которых работает с определенным набором тестов и каждый запускается только при изменении определенного набора файлов (это можно установить на вкладке Build Options -> Specify Resources при настройке сборщика)
                  +1
                  Нужно просто пользоваться Maven'ом!
                    +1
                    Автоматический запуск тестов для тех, кто программирует на линухе и тесты держит в отдельных скриптах:
                    #!/bin/sh
                    
                    SRC=../src                    # Путь к каталогу с исходниками
                    TESTS=${@:-./*.t}             # .t -- расширение для тестов по-умолчанию
                    
                    inotifywait -rm -e close_write $SRC $TESTS | while read line ; do
                            clear
                            echo ----- $(date) -------
                            for t in $TESTS ; do
                                    echo ">> " $t
                                    $t || break
                            done
                    done
                    


                    Перед запуском надо вписать путь к исходникам (SRC=...), потом открыть в отдельном терминале и запустить:
                    ./autotest.sh <test1> <test2> <test3> ...

                    или, если скрипт находится в катлоге с тестами, и долгих там нет:
                    ./autotest.sh
                      +4
                      Сейчас появились инструменты для фонового модульного тестирования, которые умеют определять средствами статического анализа, какие модульные тесты надо выполнить при изменении того или иного фрагмента исходного кода.
                      Вот тут можно почитать мой перевод обзора таких инструментов на русский язык: software-testing.ru/library/testing/functional-testing/531-background-unit-testing
                      (Если кто предпочитает английский — там есть ссылка на оригинал)
                        0
                        Хорошая ссылка. Подобные иструменты полезны не только для фонового тестирования — снижение времени прогона тестов еще никому не повредило.
                          +1
                          Увы, проект JUnitMax был только что закрыт автором.
                          Недостаточно пользователей.

                          www.threeriversinstitute.org/blog/?p=291
                            0
                            Да, действительно зыкрыл. Что удивительно, но автор (Бек) все-равно не собирается открывать исходники. Похоже провалился его бизнес-план и/или банально нет времени. Дело ясное, что дело темное.
                              +1
                              Упс… А как красиво про стартапы писал — www.threeriversinstitute.org/blog/?p=251
                              Ну и ладно, главное — что идея появилась, кто-нибудь другой реализует.
                            0
                            Какой бред. Для автотестирования есть системы continuous integration. А если после каждого сохранения… я вот привык каждые десять секунд сохранять код, что, получается, каждый раз тесты гнать?
                              0
                              А почему бы нет?
                              Ядер в процессоре много (чем бы их еще загрузить?!), память стоит копейки.
                              Пусть себе в фоне в отдельной JVM прогоняются.
                                +2
                                (1) Цитата: «Для этого тесты должны быть быстрыми, поскольку мое терпение после нажатия Ctrl+s составляет только 2 секунды.»
                                (2) Вам необъязательно запускать все тесты — а только определенный набор
                                (3) Тесты выполняются в фоновом режиме — вы не заметите из присутствия до тех пор пока не поломаете тест.

                                Continuous integration никто не отменял — это один из столпов TDD.
                                  0
                                  Получается что так, каждые 10 сек запускать тесты, если хочешь быть уверен что ты своими десятисекундными изменениями не поломал что-то.
                                    0
                                    Никто не заставляет использовать данную технику — кто-то хочет быть уверен в программе каждые 10 секунд, кто-то не обращает на результаты фоновых тестов никакого внимания. В любой момент можно включить/выключить автоматическую прогонку тестов — это дело вкуса и культуры тестирования для каждого отдельно взятого человека.

                                      +3
                                      — Я поломаю этот проект за 7 секунд.
                                      — А я за 5.
                                      — Ломай.

                                      © Угадай Мелодию
                                    0
                                    По использованию Ant можно почитать www.artlebedev.ru/tools/technogrette/soft/eclipse-ant/
                                      0
                                      а что если прогон тестов занимает почти 2 часа да ещё и на нескольких платформах? Какая-то идиотская идея, вот что это.
                                        0
                                        А разве проект нельзя поделить на несколько подпроектов и назначить для каждого из них свой набор тестов? В Visual Studio так обычно и делается.
                                          0
                                          да все равно в 2секунды уложится слишком нереально — вот я к чему.
                                        0
                                        все здорово, только порой сложно убедить начальство в подходе с модульным тестирование, особенно если еще и код унаследован и для интеграции нужно много времени… Сложно обьяснить что потом экономия будет офигенной…

                                        P.S. хочу постер как картинка к статье ;) повешу напротив начальника )))

                                        Only users with full accounts can post comments. Log in, please.