Java как проверить программу

Содержание

В составе JDK есть полезная утилита jvisualvm (Java VisualVM), позволяющая снимать дампы, анализировать производительность, состояние потоков и памяти.

Для анализа создадим вот такую программу на Java «MainTestProgram.java»:

MainTestProgram.java
import java . util . concurrent . Executors ;
import java . util . concurrent . ExecutorService ;
import java . util . concurrent . TimeUnit ;
import java . util . concurrent . Future ;
import java . util . concurrent . Callable ;
import java . util . concurrent . ConcurrentMap ;
import java . util . concurrent . ConcurrentHashMap ;
import java . util . concurrent . ThreadLocalRandom ;
public class MainTestProgram <
private static final int THREAD_COUNT = 10 ;
private static final int TASKS_COUNT = 10 ;
private static final long WORK_MINUTES = 60L ;
private static class MyClass <
private byte [ ] bytes = new byte [ 100_000 ] ;
private static final ConcurrentMap < Integer , MyClass >concurrentMap = new ConcurrentHashMap <> ( ) ;
private static class MyTask implements Callable
public Boolean call ( ) throws Exception <
long startTime = System . currentTimeMillis ( ) ;
// Каждый поток работает только WORK_MINUTES минут с момента старта.
while ( System . currentTimeMillis ( ) < startTime + 1000L * 60L * WORK_MINUTES ) <
Thread . sleep ( 500L ) ;
> catch ( InterruptedException ie ) <
ie . printStackTrace ( ) ;
concurrentMap . put (
ThreadLocalRandom . current ( ) . nextInt (
Integer . MIN_VALUE , Integer . MAX_VALUE ) ,
new MyClass ( ) ) ;
return true ;
public static void main ( String [ ] args ) throws InterruptedException <
ExecutorService executorService = Executors . newFixedThreadPool ( THREAD_COUNT ) ;
Future [ ] futures = new Future [ TASKS_COUNT ] ;
System . out . println ( «Scheduling threads. » ) ;
for ( int n = 0 ; n < TASKS_COUNT ; n ++ ) <
futures [ n ] = executorService . submit ( new MyTask ( ) ) ;
System . out . println ( «Awaiting termination. » ) ;
executorService . awaitTermination ( WORK_MINUTES * 2L , TimeUnit . MINUTES ) ;
System . out . println ( «Finished.» ) ;

Как узнать версию Java на компьютере

Скомпилируем (в случае проблем рекомендую ознакомиться с вот этой статьей):

javac MainTestProgram.java

И запустим на выполнение:

java MainTestProgram

Теперь перейдём в каталог bin внутри JDK. У меня для Windows это было «C:Program FilesJavajdk1.8.0_91bin», но у вас он может немного отличаться в зависимости от версии Java и операционной системы.

Запустим jvisualvm. В левой части окна Java VisualVM в дереве кликнем два раза на нашей программе MainTestProgram:

Java VisualVM

Должна появиться вкладка MainTestProgram (pid NNNN). Внутри неё будет ещё пять вкладок:

  1. Overview;
  2. Monitor;
  3. Threads;
  4. Sampler;
  5. Profiler;

На вкладке Overview отображается общая информация о версии Java-машины, системных параметрах и прочем.

Почему Java для десктопа это плохая идея и какие есть аналоги

На вкладке Monitor можно смотреть загрузку ЦП, выделение памяти, количество запущенных и активных потоков. Здесь можно заметить моменты работы сборщика мусора. Для нашей программы там будет отображено примерно такое:

Monitor, Memory, CPU, Threads, jvisualvm, Java

Обратите внимание на правый верхний график. График Used heap постоянно растёт. Можно смотреть на него очень долго, но даже если будет происходить сборка мусора, то график всё равно будет продвигаться вверх. Это сигнализирует о возможной утечке памяти.

В нашем случае это происходит в строках concurrentMap . put ( , где мы постоянно создаём новые значения и кладём их в глобальный ConcurrentMap , в результате чего они всегда достижимы из кода и никогда не уничтожаются сборщиком мусора. В реальных приложениях найти причину утечки гораздо сложнее.

На вкладке Threads отображается состояние потоков. Для нашего случая это нечто такое:

Java VisualVM Threads

Обратите внимание на потоки pool-1-thread-NN. Они все в состоянии Park, то есть чего-то ожидают. Когда все потоки из пулов находятся в таком состоянии, то это тоже плохой признак. Они могут ожидать ответа от другого сервера по сети или ещё чего-нибудь. В нашем случае они сидят в строке Thread . sleep ( 500L ) ; нашего кода, что мы увидим в последующих вкладках Java VisualVM.

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

jvisualvm, sampler, cpu, memory

Для замера времени выполнения методов нужно кликнуть по кнопке CPU, после чего jvisualvm начнёт собирать данные. Можно делать snapshot-ы для сохранения в файл и последующего анализа:

java VisualVM CPU snapshot

Как вы можете увидеть, все потоки действительно висят на нашем Thread . sleep :

jvisualvm CPU snapshot

Теперь посмотрим на состояние памяти. Для этого снова вернитесь во вкладке Sampler и кликните на кнопку Memory, после чего jvisualvm начнёт собирать статистику использования памяти:

Java VisualVM memory

Информации, которую я уже изложил в статье, должно хватить для выявления большинства проблем и узких мест в вашем приложении. Осталось сказать ещё только одно: как подключиться к удалённому приложению на сервере?

Читайте также:
Самая маленькая программа для записи дисков

Для подключения к приложению на удалённом сервере нужно сперва запустить на этом сервере утилиту jstatd, которая входит в состав JDK. Затем кликаем правой кнопкой мышки на узле Remote в jvisualvm и там на Add Remote Host…, после чего в появившемся окне необходимо указать имя узла и отображаемое имя. В остальном работа с удалённым приложением аналогична анализу локального приложения.

Опубликовано 19.07.2017 19.07.2017 Автор Урванов Фёдор Рубрики Java Метки Java

Один комментарий к “Диагностика Java-приложения с jvisualvm”

Алексей :

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

Источник: urvanov.ru

Тестирование программы, JUnit

JUnit — библиотека для модульного тестирования программ Java. Созданный Кентом Беком и Эриком Гаммой, JUnit принадлежит семье фреймворков xUnit для разных языков программирования, берущей начало в SUnit Кента Бека для Smalltalk. JUnit породил экосистему расширений — JMock, EasyMock, DbUnit, HttpUnit и т. д.

Библиотека JUnit была портирована на другие языки, включая PHP (PHPUnit), C# (NUnit), Python (PyUnit), Fortran (fUnit), Delphi (DUnit), Free Pascal (FPCUnit), Perl (Test::Unit), C++ (CPPUnit), Flex (FlexUnit), JavaScript (JSUnit).

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

Пример теста JUnit

Необходимость использования JUnit

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

Юнит тесты классов и функций являются своего рода документацией к тому, что ожидается в результате их выполнения. И не просто документацией, а документацией которая может автоматически проверять код на соответствие предъявленным функциям. Это удобно, и часто тесты разрабатывают как вместе, так и до реализации классов. Разработка через тестирование — крайне популярная технология создания серьезного программного обеспечения.

Виды тестирования и место JUnit тестирования в классификации

Тестирование программного обеспечение можно разделить на два вида:

  • тестирование черного ящика;
  • тестирование белого ящика.

Во время тестирования программы как черного ящика внутренняя структура приложения в расчет не принимается. Все, что имеет значение, это функциональность, которую приложение должно обеспечить. При тестировании программы как белого ящика во внимание принимается внутренняя структура, т.е. класс и методы. Кроме этого, тестирование можно разделить на четыре уровня:

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

Юнит тестирование по определению является тестированием белого ящика.

Используется unit тестирование в двух вариантах — JUnit 3 и JUnit 4. Рассмотрим обе версии, так как в старых проектах до сих пор используется 3-я версия, которая поддерживает Java 1.4.

JUnit 3

Для создания теста следует наследовать тест-класс TestCase, переопределить методы setUp и tearDown при необходимости, ну и самое главное — разработать тестовые методы, наименование которых должно начинаться с аббривиатуры «test». При запуске теста сначала создается экземляр тест-класса (для каждого теста в классе отдельный экземпляр класса), затем выполняется метод setUp, запускается сам тест, ну и в завершение выполняется метод tearDown. Если какой-либо из методов вызывает исключение, тест считается провалившимся.

Примечание : тестовые методы должны быть public void, могут быть static.

Тесты состоят из выполнения некоторого кода и проверок. Проверки чаще всего выполняются с помощью класса Assert хотя иногда используют ключевое слово assert.

В качестве примера рассмотрим утилиту для работы со строками, включающую методы для проверки пустой строки и представления последовательности байт в виде 16-ричной строки:

public class JUnit3StringUtilsTest extends TestCase < private final Map toHexStringData = new HashMap(); protected void setUp() throws Exception < toHexStringData.put(«», new byte[0]); toHexStringData.put(«01020d112d7f», new byte[]); toHexStringData.put(«00fff21180» , new byte[]); //. > protected void tearDown() throws Exception < toHexStringData.clear(); >public void testToHexString() < for (Iterator iterator = toHexStringData.keySet().iterator(); iterator.hasNext();) < final String expected = (String)iterator.next(); final byte[] testData = (byte[])toHexStringData.get(expected); final String actual = StringUtils.toHexString(testData); assertEquals(expected, actual); >> //. >

Дополнительные возможности, TestSuite

JUnit 3 имеет несколько дополнительных возможностей. Например, можно группировать тесты. Для этого необходимо использовать класс TestSuite:

public class JUnit3StringUtilsTestSuite extends TestSuite < public JUnit3StringUtilsTestSuite() < addTestSuite(StringUtilsJUnit3Test.class); addTestSuite(OtherTest1.class); addTestSuite(OtherTest2.class); >>

Можно исполнение теста повторить несколько раз. Для этого используется RepeatedTest :

public class JUnit3StringUtilsRepeatedTest extends RepeatedTest < public JUnit3StringUtilsRepeatedTest() < super(new JUnit3StringUtilsTest(), 100); >>

Читайте также:
Net framework ошибка при запуске программ

Наследуя тест-класс от ExceptionTestCase, можно проверить код на выброс исключения :

public class JUnit3StringUtilsExceptionTest extends ExceptionTestCase < public JUnit3StringUtilsExceptionTest(final String name) < super(name, NullPointerException.class); >public void testToHexString() < StringUtils.toHexString(null); >>

Как видно из примеров все довольно просто и ничего лишнего — минимум кода для JUnit тестирования.

JUnit 4

В JUnit 4 добавлена поддержка новых возможностей из Java 5.0; тесты могут быть объявлены с помощью аннотаций. При этом существует обратная совместимость с предыдущей версией фреймворка. Практически все рассмотренные выше примеры будут работать и в JUnit 4 за исключением RepeatedTest, который отсутствует в новой версии.

Какие внесены изменения появились в JUnit 4? Рассмотрим тот же пример, но уже с использованием новых возможностей :

Что изменилось в JUnit 4 ?

Примеры использования аннотаций с параметрами, JUnit Test :

Игнорирование выполнения теста, JUnit Ignore

Правила тастирования, JUnit Rule

JUnit позволяет использовать определенные разработчиком правила до и после выполнения теста, которые расширяют функционал. Например, есть встроенные правила для задания таймаута для теста (Timeout), для задания ожидаемых исключений (ExpectedException), для работы с временными файлами(TemporaryFolder) и др.

Для объявления правила необходимо создать public не static поле типа производного от MethodRule и аннотировать его с помощью ключевого слова Rule.

Наборы тестов, JUnit Suite, SuiteClasses

Аннотация Categories

Аннотация, JUnit Parameterized

Аннотация Parameterized позволяет использовать параметризированные тесты. Для этого в тест-классе объявляется статический метод, возвращающий список данных, которые будут использованы в качестве аргументов конструктора класса.

Параметризирование метода : Theories.class, DataPoints, DataPoint, Theory

Порядок выполнения тестов

В противном случае можно использовать следующие 2 подхода.

Список основных аннотаций

Список типов проверок Asserts

Тип проверкиОписание
fail()
fail(String message)
прерывание теста с ошибкой, т.е. тест будет неудачным
assertTrue(boolean condition)
assertTrue(java.lang.String message, boolean condition)
проверка на равенство условия condition значению true
assertFalse(boolean condition)
assertFalse(String message, boolean condition)
проверка на равенство условия condition значению false
assertEquals( expected, actual)
assertEquals(String message, expected, actual)
проверка на равенство; — это Object, int, double и т.д.
assertArrayEquals(byte[] expecteds, byte[] actuals)
assertArrayEquals(String message, [] expecteds, [] actuals)
проверка массивов на равенство; аналогично assertEquals; — это Object, int, double и т.д.
assertNotNull(Object object)
assertNotNull(String message, Object object)
проверка, что Object не null
assertNull(Object object)
assertNull(String message, Object object)
проверка, что Object null
assertSame(Object expected, Object actual)
assertSame(String message, Object expected, Object actual)
проверка на равенство двух объектов expected и actual, т.е. один и тот же объект

Пример JUnit тестирования

Для демонстрации основных возможностей JUnit, используем примитивный java класс FuncMath, который имеет два метода — нахождение факториала неотрицательного числа и суммы двух чисел. Кроме того, в экземпляре класса будет находится счетчик вызовов методов.

public class FuncMath < int calls; public int getCalls() < return calls; >public long factorial(int number) < calls++; if (number < 0) throw new IllegalArgumentException(); long result = 1; if (number >1) < for (int i = 1; i < = number; i++) result = result * i; >return result; > public long plus(int num1, int num2) < calls++; return num1 + num2; >>

Тестовый класс с несколькими сценариями будет иметь следующий вид :

Метод calls тестирует правильность счетчика вызовов. Метод factorial проверяет правильность вычисления факториала для некоторых стандартных значений. Метод factorialNegative проверяет, что для отрицательных значений факотриала будет брошен IllegalArgumentException. Метод todo будет проигнорирован.

В заключении следует отметить, что в статье представлены не все возможности использования JUnit. Но как видно из приведенных примеров, фреймворк достаточно прост в использовании, дополнительных возможностей немного, но есть возможность расширения с помощью правил и запускалок.

Источник: java-online.ru

Как и какими средствами находить ошибки в коде Java?

При написании кода он, порой, не работает так, как я задумал или не работает в принципе. Я сижу и гадаю: что и где не так? Немного посмотрев на код — иду на ресурсы профессионалов, например Stack Overflow и публикую вопрос «Где здесь ошибка?» или «Почему не работает?» В итоге очень часто проблема мелкая: дурацкая опечатка, ошибка в синтаксисе и подобное.

Профессионалом так не стать, если по каждой мелочёвке бегать по ресурсам. А я хочу им быть. Вопрос: какие есть способы, чтобы найти ошибки в Java коде? Какие есть инструменты, методы, пути и пр.?

Отслеживать
33.6k 24 24 золотых знака 128 128 серебряных знаков 217 217 бронзовых знаков
задан 3 авг 2017 в 10:01
Алексей Шиманский Алексей Шиманский
70.5k 12 12 золотых знаков 87 87 серебряных знаков 179 179 бронзовых знаков
Поддерживаю одного из коментаторов, Алексей, Вам бы книжки писать! Уверен читатели бы нашлись.

14 сен 2022 в 15:22

2 ответа 2

Сортировка: Сброс на вариант по умолчанию

Вчера всё работало, а сегодня не работает / Код не работает как задумано

Debugging (Отладка)

В чем заключается процесс отладки? Что это такое?

Читайте также:
Программа для настройки печати принтера

Процесс отладки состоит в том, что мы останавливаем выполнения скрипта в любом месте, смотрим, что находится в переменных, в функциях, анализируем и переходим в другие места; ищем те места, где поведение отклоняется от правильного.

Заметка: Отладка производится как правило в IDE (Интегрированная среда разработки). Что это такое можно чуть подробнее ознакомиться в вопросе

Какие есть способы предупреждения ошибок, их нахождения и устранения?

В данном случае будет рассмотрен пример с Intellij IDEA, но отладить код можно и в любой другой IDE.

Подготовка

Достаточно иметь в наличии IDE, например Intellij IDEA

Запуск

Для начала в левой части панели с кодом на любой строке можно кликнуть ЛКМ , тем самым поставив точку останова (breakpoint — брейкпойнт). Это то место, где отладчик автоматически остановит выполнение Java, как только до него дойдёт. Количество breakpoint’ов не ограничено. Можно ставить везде и много.

введите сюда описание изображения

Отладка запускается сочетанием Shift+F9 или выбором в верхнем меню Run → Debug или нажатием зеленого «жучка»:

введите сюда описание изображения

В данном случае, т.к. функция вызывается сразу на той же странице, то при нажатии кнопки Debug — отладчик моментально вызовет метод, выполнение «заморозится» на первом же брейкпойнте. В ином случае, для активации требуется исполнить действие, при котором произойдет исполнение нужного участка кода (клик на кнопку в UI, передача POST запроса с данными и прочие другие действия)

введите сюда описание изображения

  1. Стэк вызовов, все вложенные вызовы, которые привели к текущему месту кода.
  2. Переменные. На текущий момент строки ниже номера 24 ещё не выполнилась, поэтому определена лишь data и numsStringArr
  3. Показывает текущие значения любых переменных и выражений. В любой момент здесь можно нажать на + , вписать имя любой переменной и посмотреть её значение в реальном времени. Например data или nums[0] , а можно и nums[i] и item.test.data.name[5].info[key[1]] и т.д. На текущий момент строки ниже номера 24 ещё не выполнилась, поэтому sum и output во вкладке Watchers обозначены красным цветом с надписью «cannot find local variable».

Процесс

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

введите сюда описание изображения

Show Execution Point ( Alt+F10 ) — переносит в файл и текущую линию отлаживаемого скрипта. Например если файлов много, решили посмотреть что в других вкладках, а потом забыли где у вас отладка 🙂

Step Over ( F8 ) — делает один шаг не заходя внутрь функции. Т.е. если на текущей линии есть какая-то функция, а не просто переменная со значением, то при клике данной кнопки, отладчик не будет заходить внутрь неё.

Step Into ( F7 ) — делает шаг. Но в отличие от предыдущей, если есть вложенный вызов (например функция), то заходит внутрь неё.

Step Out ( Shift+F8 ) — выполняет команды до завершения текущей функции. Удобна, если случайно вошли во вложенный вызов и нужно быстро из него выйти, не завершая при этом отладку.

Rerun ( Ctrl+F5 ) — Перезапустить отладку

Resume Program( F9 ) — Продолжает выполнения скрипта с текущего момента. Если больше нет других точек останова, то отладка заканчивается и скрипт продолжает работу. В ином случае работа прерывается на следующей точке останова.

Stop ( Ctrl+F2 ) — Завершить отладку

View Breakpoints ( Ctrl+Shift+F8 ) — Посмотреть все установленные брейкпойнты

Mute Breakpoints — Отключить брейкпойнты.

Итак, в текущем коде видно значение входного параметра:

  • data = «23 24 11 18» — строка с данными через пробел
  • numsStringArr = — массив строк, который получился из входной переменной.

введите сюда описание изображения

Если нажмем F8 2 раза, то окажемся на строке 27; во вкладках Watches и Variables и в самой странице с кодом увидим, что переменная sum была инициализирована и значение равно 0, а также nums инициализирована и в ней лежит массив целых чисел .

Если теперь нажмем F8 , то попадем внутрь цикла for и нажимая теперь F8 пока не окончится цикл, можно будет наблюдать на каждой итерации, как значение num и sum постоянно изменяются. Тем самым мы можем проследить шаг за шагом весь процесс изменения любых переменных и значений на любом этапе, который интересует.

Дальнейшие нажатия F8 переместит линию кода на строки 31, 32 и, наконец, 36.

Дополнительно

Если нажать на View Breakpoints в левой панели, то можно не только посмотреть все брейкпойнты, но в появившемся окно можно еще более тонко настроить условие, при котором на данной отметке надо остановиться. В методе выше, например, нужно остановиться только когда sum превысит значение 20.

введите сюда описание изображения

Это удобно, если останов нужен только при определённом значении, а не всегда (особенно в случае с циклами).

Источник: ru.stackoverflow.com

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru