HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-03-10
1 <p>Достаточно часто в процессе написания мы используем функции, которые выкидывают исключения (throws Exception).</p>
1 <p>Достаточно часто в процессе написания мы используем функции, которые выкидывают исключения (throws Exception).</p>
2 String returnFoo() throws IllegalArgumentException { return "foo!"; }<p>Exception -<strong>исключение</strong>в работе программы. Оно возникает, когда что-то пошло не так. К примеру, не была проинициализирована переменная, а мы обращаемся к ней (и получаем Null Pointer Exception).</p>
2 String returnFoo() throws IllegalArgumentException { return "foo!"; }<p>Exception -<strong>исключение</strong>в работе программы. Оно возникает, когда что-то пошло не так. К примеру, не была проинициализирована переменная, а мы обращаемся к ней (и получаем Null Pointer Exception).</p>
3 <p>В процессе разработки ПО, разработчик может пометить, что данная функция может вызывать исключение, чтобы использующий этот метод обработал исключение. Для чего это надо? Представим, что вы подключились к базе данных, но по какой-то причине не смогли выполнить запрос. В обработке исключений вы должны сообщить (написать в лог), что произошла ошибка выполнения запроса и завершить работу с БД.</p>
3 <p>В процессе разработки ПО, разработчик может пометить, что данная функция может вызывать исключение, чтобы использующий этот метод обработал исключение. Для чего это надо? Представим, что вы подключились к базе данных, но по какой-то причине не смогли выполнить запрос. В обработке исключений вы должны сообщить (написать в лог), что произошла ошибка выполнения запроса и завершить работу с БД.</p>
4 <p>Когда мы у себя в коде вызываем функции, которые выкидывают исключения, IDE (среда разработки) заставляет нас их обработать. И сделать мы это можем<strong>двумя способами</strong>: 1. Добавить в сигнатуру, что этот метод тоже выкидывает данное исключение. Тем самым, мы как бы перекладываем обработку на другого. 2. Добавляем<strong>try{} catch {}</strong>и обрабатываем исключение сами.</p>
4 <p>Когда мы у себя в коде вызываем функции, которые выкидывают исключения, IDE (среда разработки) заставляет нас их обработать. И сделать мы это можем<strong>двумя способами</strong>: 1. Добавить в сигнатуру, что этот метод тоже выкидывает данное исключение. Тем самым, мы как бы перекладываем обработку на другого. 2. Добавляем<strong>try{} catch {}</strong>и обрабатываем исключение сами.</p>
5 <p>И оба эти метода, в контексте автотестов, таят подводные камни при неправильном их использовании, ведь при обработке ошибок выполнение программы не прерывается.</p>
5 <p>И оба эти метода, в контексте автотестов, таят подводные камни при неправильном их использовании, ведь при обработке ошибок выполнение программы не прерывается.</p>
6 <p>Рассмотрим первый вариант - исключение в сигнатуре.</p>
6 <p>Рассмотрим первый вариант - исключение в сигнатуре.</p>
7 <p>Предположим, у нас есть метод, который проверяет две переменные:</p>
7 <p>Предположим, у нас есть метод, который проверяет две переменные:</p>
8 public static void checkEquals() throws Exception { assert "a".equals("b"); }<p>Данная проверка заведомо будет провалена. Однако если мы в главном методе вызовем данную функцию (и тоже добавим<strong>throws</strong>в сигнатуру), то наш код выполнится без ошибок.</p>
8 public static void checkEquals() throws Exception { assert "a".equals("b"); }<p>Данная проверка заведомо будет провалена. Однако если мы в главном методе вызовем данную функцию (и тоже добавим<strong>throws</strong>в сигнатуру), то наш код выполнится без ошибок.</p>
9 public static void main(String[] args) throws Exception { checkEquals(); }<p>А что, если бы данный метод, скажем, не проверял, а обновлял данные? А мы потом ссылались на эти данные? В итоге, у нас будет ложные срабатывания в тесте, а дебаг будет крайне затруднен.</p>
9 public static void main(String[] args) throws Exception { checkEquals(); }<p>А что, если бы данный метод, скажем, не проверял, а обновлял данные? А мы потом ссылались на эти данные? В итоге, у нас будет ложные срабатывания в тесте, а дебаг будет крайне затруднен.</p>
10 <p>Рассмотрим теперь второй вариант, где мы обрабатываем ошибку через<strong>try{} catch{}</strong>. Обычно, начинающие автоматизаторы просто выводят стектрейс в консоль, где они видят, что данный метод завалился:</p>
10 <p>Рассмотрим теперь второй вариант, где мы обрабатываем ошибку через<strong>try{} catch{}</strong>. Обычно, начинающие автоматизаторы просто выводят стектрейс в консоль, где они видят, что данный метод завалился:</p>
11 try { checkEquals(); } catch (Exception e) { e.printStackTrace(); }<p>Вроде бы, в данном случае все хорошо, ведь ошибка отображается в консоли. Но это более-менее работает до тех пор, пока тесты запускаются локально, а не на удаленной машине из под, к примеру, Jenkins. Ведь он может и не выводить полный лог, а ведь в этом случае вы не увидите ошибку. И, опять же, если у нас на результат выполнения данного метода завязан тест, то выполнение может пойти по совсем непредвиденному пути.</p>
11 try { checkEquals(); } catch (Exception e) { e.printStackTrace(); }<p>Вроде бы, в данном случае все хорошо, ведь ошибка отображается в консоли. Но это более-менее работает до тех пор, пока тесты запускаются локально, а не на удаленной машине из под, к примеру, Jenkins. Ведь он может и не выводить полный лог, а ведь в этом случае вы не увидите ошибку. И, опять же, если у нас на результат выполнения данного метода завязан тест, то выполнение может пойти по совсем непредвиденному пути.</p>
12 <h3>Выводы:</h3>
12 <h3>Выводы:</h3>
13 <p>1) e.printStactTrace() можно использовать только для дебага. В продакшн-коде его быть не должно; 2) не используйте<strong>throws</strong>в сигнатуре методов (при разработке автотестов это нужно очень редко); 3) если вы используете конструкцию<strong>try{} catch{}</strong>, то обрабатывайте ошибку! Если у вас не получается обработать ошибку или вы не знаете, что делать, то лучше выкиньте<strong>throw new RuntimeException(e)</strong>в блоке<strong>catch</strong>, чтобы выполнение тестов сразу завершилось.</p>
13 <p>1) e.printStactTrace() можно использовать только для дебага. В продакшн-коде его быть не должно; 2) не используйте<strong>throws</strong>в сигнатуре методов (при разработке автотестов это нужно очень редко); 3) если вы используете конструкцию<strong>try{} catch{}</strong>, то обрабатывайте ошибку! Если у вас не получается обработать ошибку или вы не знаете, что делать, то лучше выкиньте<strong>throw new RuntimeException(e)</strong>в блоке<strong>catch</strong>, чтобы выполнение тестов сразу завершилось.</p>
14  
14