Автоматическое создание модульных тестов для устаревшего Java-кода

Каков наилучший, желательно бесплатный инструмент с открытым исходным кодом для автоматического создания модульных тестов Java? Я знаю, что модульные тесты не могут служить той же цели, что и обычные модульные тесты TDD, которые документируют и определяют дизайн системы. Однако автоматически сгенерированные модульные тесты могут быть полезны, если у вас есть огромная устаревшая кодовая база и вы хотите знать, будут ли требуемые изменения иметь нежелательные, неясные побочные эффекты.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
12
0
4 849
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Если честно, наверное, я бы этого не сделал. Модульные тесты изолированы, и вы фактически не узнаете, есть ли у вас «нежелательные, неясные побочные эффекты», потому что все отделено стеной от других вещей, вызывающих побочные эффекты. В результате вам нужна интеграция или тестирование системы, а который нельзя автоматизировать.

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

Как только вы обнаружите ошибки, напишите модульные тесты только для них. По мере продвижения вперед вы можете использовать TDD для тех битов, которые хотите реорганизовать.

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

в качестве дополнения к этому подходу я рекомендую прочитать objectmentor.com/resources/articles/… (предупреждающий PDF-файл) и этот www-128.ibm.com/developerworks/java/library/j-legacytest.htm‌ l. Я не думаю, что вы действительно хотите автоматически генерировать тесты

Jean 17.09.2008 13:00
Ответ принят как подходящий

Не бесплатно. Не с открытым исходным кодом. Но я обнаружил, что AgitarOne Agitator (http://www.agitar.com/solutions/products/agitarone.html) ДЕЙСТВИТЕЛЬНО подходит для автоматического создания модульных тестов И поиска нежелательных неясных побочных эффектов.

Мне бы хотелось увидеть реализацию чего-то вроде Agitar с открытым исходным кодом - это то, для чего Open Source должен быть действительно хорош.

Vihung 17.09.2008 16:15

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

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

Теперь о генерируя себя. Я не знаю ни о каком волшебном инструменте, но вы можете поискать функциональность JUnit для включения некоторых тестов в javadocs для методов. Это позволит вам написать несколько простых тестов. И да, это действительно имеет некоторую ценность.

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

Бонусный совет! Есть отличная книга «Эффективная работа с унаследованным кодом» с примерами на Java, включая методы, которые можно использовать в таких ситуациях. К сожалению, вам придется делать некоторые вещи вручную, но вам все равно придется сделать это на каком-то этапе.

Плагин Coview для Eclipse (http://www.codign.com/products.html) выглядит как раз то, что нужно. Я заинтересован в создании тестов, охватывающих все пути в коде, и, похоже, это помогает. Он также генерирует макеты, которые должны сэкономить мне массу времени.

Diffblue Cover - это продукт, который делает это, и существует бесплатная версия Community Edition, представляющая собой плагин IntelliJ, здесь: https://plugins.jetbrains.com/plugin/14946-diffblue-cover-community-edition--unit-test-generator

Он работает, используя обучение с подкреплением для поиска потенциально полезных тестов, и стремится писать тесты, подобные людям. Он автоматически создает макеты и имеет полную поддержку Spring / SpringBoot.

Вот пример теста для контроллера-владельца в Spring PetClinic, который он написал:

@Test
public void testInitUpdateOwnerForm() throws Exception {
    // Arrange
    Owner owner = new Owner();
    owner.setLastName("Doe");
    owner.setId(1);
    owner.setCity("Oxford");
    owner.setPetsInternal(new HashSet<Pet>());
    owner.setAddress("42 Main St");
    owner.setFirstName("Jane");
    owner.setTelephone("4105551212");
    when(this.ownerRepository.findById((Integer) any())).thenReturn(owner);
    MockHttpServletRequestBuilder requestBuilder = MockMvcRequestBuilders.get("/owners/{ownerId}/edit", 123456789);

    // Act and Assert
    MockMvcBuilders.standaloneSetup(this.ownerController)
        .build()
        .perform(requestBuilder)
        .andExpect(MockMvcResultMatchers.status().isOk())
        .andExpect(MockMvcResultMatchers.model().size(1))
        .andExpect(MockMvcResultMatchers.model().attributeExists("owner"))
        .andExpect(MockMvcResultMatchers.view().name("owners/createOrUpdateOwnerForm"))
        .andExpect(MockMvcResultMatchers.forwardedUrl("owners/createOrUpdateOwnerForm"));
}

Другие вопросы по теме