Java Assertions: Тестирование предположений

JavaJavaBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

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


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("Java")) -.-> java/FileandIOManagementGroup(["File and I/O Management"]) java(("Java")) -.-> java/BasicSyntaxGroup(["Basic Syntax"]) java(("Java")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["Object-Oriented and Advanced Concepts"]) java(("Java")) -.-> java/SystemandDataProcessingGroup(["System and Data Processing"]) java/BasicSyntaxGroup -.-> java/operators("Operators") java/BasicSyntaxGroup -.-> java/variables("Variables") java/BasicSyntaxGroup -.-> java/switch("Switch") java/BasicSyntaxGroup -.-> java/output("Output") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/user_input("User Input") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/exceptions("Exceptions") java/FileandIOManagementGroup -.-> java/files("Files") java/SystemandDataProcessingGroup -.-> java/math_methods("Math Methods") java/SystemandDataProcessingGroup -.-> java/system_methods("System Methods") subgraph Lab Skills java/operators -.-> lab-117470{{"Java Assertions: Тестирование предположений"}} java/variables -.-> lab-117470{{"Java Assertions: Тестирование предположений"}} java/switch -.-> lab-117470{{"Java Assertions: Тестирование предположений"}} java/output -.-> lab-117470{{"Java Assertions: Тестирование предположений"}} java/user_input -.-> lab-117470{{"Java Assertions: Тестирование предположений"}} java/exceptions -.-> lab-117470{{"Java Assertions: Тестирование предположений"}} java/files -.-> lab-117470{{"Java Assertions: Тестирование предположений"}} java/math_methods -.-> lab-117470{{"Java Assertions: Тестирование предположений"}} java/system_methods -.-> lab-117470{{"Java Assertions: Тестирование предположений"}} end

Создание простого утверждения

Создадим простое утверждение, которое проверяет, является ли число четным. Предположим, что число четное, и напишем утверждение, используя четное число. Затем изменим число и запустим код. Мы должны получить AssertionError.

public class AssertionsLab {
    public static void main(String[] args) {
        int number = 4;
        assert (number % 2) == 0;
        System.out.println("Number is even");

        // измените значение переменной number на нечетное
        number = 3;
        assert (number % 2) == 0;
        System.out.println("Number is even");
    }
}

Отключение утверждений

По умолчанию утверждения отключены в Java. Мы можем включить их с использованием опций командной строки.

Используем опцию -ea для включения утверждений и запустим код.

java -ea AssertionsLab

Код должен вывести "Number is even", за которым следует AssertionError.

Теперь отключим утверждения с использованием опции -da и запустим код снова.

java -da AssertionsLab

Код должен вывести "Number is even" дважды без выброса каких-либо исключений.

Использование утверждений для проверки входных данных

Утверждения также можно использовать для проверки входных данных метода. Создадим метод divide, который принимает два параметра и возвращает частное после деления первого параметра на второй. Предположим, что второй параметр не равен нулю, и создадим утверждение для проверки этого.

public class AssertionsLab {
    public static void main(String[] args) {
        int a = 10;
        int b = 5;
        int result = divide(a, b);
        System.out.println("Result: " + result);

        // измените значение b на ноль
        b = 0;
        result = divide(a, b);
        System.out.println("Result: " + result);
    }

    private static int divide(int a, int b) {
        assert b!= 0 : "Cannot divide by zero";
        return a / b;
    }
}

Использование утверждений для отладки и тестирования

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

echo "0\n3\n0" > input.txt

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

import java.io.File;
import java.io.FileNotFoundException;
+ import java.util.Scanner;

public class AssertionsLab {
    public static void main(String[] args) throws FileNotFoundException {
        Scanner scanner = new Scanner(new File("input.txt"));
        int number = 0;
        while (scanner.hasNext()) {
            number = scanner.nextInt();
            if (number!= 0) {
                break;
            }
        }
        assert number == 3 : "Incorrect number read from file";
        System.out.println("First non-zero number: " + number);
    }
}

Когда не использовать утверждения

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

public class AssertionsLab {
    public static void main(String[] args) {
        int negativeNumber = -1;
        printPositiveNumber(negativeNumber);
    }

    public static void printPositiveNumber(int number) {
        assert (number > 0) : "Not a valid positive number";
        System.out.println("Positive number: " + number);
    }
}

Дайте утверждениям информативность

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

public class AssertionsLab {
    public static void main(String[] args) {
        int number = -1;
        assert (number > 0) : "Negative number found";
        System.out.println("Number is positive: " + number);
    }
}

Сообщение "Negative number found" будет отображаться при выполнении кода.

Предотвращение поломки кода утверждениями

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

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

public class AssertionsLab {
    public static void main(String[] args) {
        double result = squareRoot(4);
        System.out.println("Square root: " + result);

        double negativeNumber = -4;
        result = squareRoot(negativeNumber);
        System.out.println("Square root: " + result);
    }

    public static double squareRoot(double number) {
        assert number >= 0 : "Number should be non-negative";
        return Math.sqrt(number);
    }
}

Избегание побочных эффектов

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

public class AssertionsLab {
    public static void main(String[] args) {
        int firstNumber = 1;
        int secondNumber = 2;
        assert (firstNumber = secondNumber) == 0 : "Values are not equal";
        System.out.println("Values are equal");
    }
}

Использование утверждений для проверки операторов switch

Мы можем использовать утверждения для проверки, были ли охвачены все возможные случаи оператора switch. Создадим оператор switch, который возвращает название дня недели в зависимости от его номера. Предположим, что номер находится в диапазоне от 0 до 6, и создадим утверждение для его проверки.

public class AssertionsLab {
    public static void main(String[] args) {
        int dayNumber = 2;
        String day = getDayName(dayNumber);
        System.out.println("Day: " + day);

        // set dayNumber to an invalid number
        dayNumber = 10;
        day = getDayName(dayNumber);
        System.out.println("Day: " + day);
    }

    public static String getDayName(int dayNumber) {
        String day;
        switch (dayNumber) {
            case 0:
                day = "Sunday";
                break;
            case 1:
                day = "Monday";
                break;
            case 2:
                day = "Tuesday";
                break;
            case 3:
                day = "Wednesday";
                break;
            case 4:
                day = "Thursday";
                break;
            case 5:
                day = "Friday";
                break;
            case 6:
                day = "Saturday";
                break;
            default:
                assert false : "Invalid day number";
        }
        return day;
    }
}

Резюме

Поздравляем! Вы завершили лабораторную работу по Java Assertions. Вы можете практиковаться в более лабораторных работах в LabEx, чтобы улучшить свои навыки.