Java → Автоматизация тестов!

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

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

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

И так, напишем свой первый тест. 

1. TDD

TDD - Test Driven Development (Разработка через тестирование) это техника разработки приложений, в котором разработчик сначала пишет тесты, в которых он определяет нужные ему требования, потом пишет код, который будет проходить успешно все тесты. Затем разработчик обязан сделать рефакторинг, т.е. оптимизацию и улучшение кода (читабельности, красоты кода). 

Это три стадии условно представляют в виде светофора: 

Красный - тесты есть, и он еще не проходят
Зеленый - тесты проходят
Синий - Рефакторинг сделан и тесты все еще проходят

Разрабатываю таким образом, вы всегда будете уверены что ваш код работает правильно. Теперь конкретно к делу, что же это такое, тесты?

2. Тестируем задачу Фибоначчи

В этой задаче нужно было написать программу(класс) которая возвращала число фибоначчи по его порядковому номеру. Т.е. у нас должен быть класс, у которого есть метод, который принимает порядковый номер числа Фибоначчи, и возвращает само число. Так и напишем в тестах. Пусть класс будет называться Fibanacci, а метод который возвращает число будет называться get(). В тестах мы будем создавать объект этого класса и вызывать его метод get() с разными параметрами и проверять результат. 

Тесты, это обычные java-классы, которые наследуются от класса TestCase. Все классы тестов должны содержать слов Test. У этого класса должны быть public void методы которые начинаются со слова test и названия которых определяет что они проверяют. Давайте создадим первый тестовый класс и с одним методом проверки, который будет проверять что первое число фибоначчи возвращается правильно.

import junit.framework.TestCase;

public class FibonacciTest extends TestCase {

    public void testFibonnacciReturn1For1(){
        Fibonacci fibonacci = new Fibonacci();
        assertEquals(1, fibonacci.get(1));
    }
}

 класс TestCase нужно подключить с помощью сочетания клавиш Alt+Enter и сверху появится у вас импорт

import junit.framework.TestCase;

Как вы видите, мы сначала создаем объект класса Fibonacci, затем вызываем метод assertEquals(), который принимает два параметра. Первый параматр это ожидаемое значение, второй параметр это действительное значение которые мы получили. И этот метод сравнит два этих значение, в случае несовпадении скажет что тест не прошел. 

В нашем случаем мы ожидаем получить число 1, если вы возовем метод get() с параметром 1 у объекта класса Fibonacci, т.е. мы ожидаем что первое число Фибоначчи будет 1. 

У нас этот код даже не запустится, потому что мы еще не создали класс Fibonacci, который мы собрались тестировать. Давайте создадим этот класс, с одним методом get(), который будет всегда возвращать 0:

public class Fibonacci {
    public int get(int n){
        return 0;
    }
}

Теперь этот класс мы должны подключить в класс FibonacciTest, если он автоматически не подключился. После этого мы попробуем запустить тест. Для запуска теста нужно курсор ввода установить в название тестового класса FibonacciTest и нажать Ctrl+Shift+F10. Вы увидите что Intellij IDEA показал внизу что тесты запущены и они не прошли. Мы прошли красный этап, где у нас есть тесты и они не проходят. 

Теперь изменим наш класс Fibonacci так, чтобы тест начал проходить. Просто поменяем возвращаем значение на 1. Снова запустим тесты и опаля, тест зеленый! Наши тесты проходят! Значит мы все написали правильно? Нет, потому что у нас очень мало проверок. Мы проверяем только первое число. Нам нужно еще несколько проверок сделать чтобы убедиться что все правильно считается. 

Давайте добавим проверку на 2, на 4, на 6, на 10 числа фибоначчи.
2 число фибоначчи равна 1,
4 число равна 3,
6 число равна 8,
10 число равна 55.

Теперь у нас в тестовом классе будет еще 4 метода:


import junit.framework.TestCase;

public class FibonacciTest extends TestCase {

    public void testFibonnacciReturn1For1(){
        Fibonacci fibonacci = new Fibonacci();
        assertEquals(1, fibonacci.get(1));
    }

    public void testFibonnacciReturn1For2(){
        Fibonacci fibonacci = new Fibonacci();
        assertEquals(1, fibonacci.get(2));
    }

    public void testFibonnacciReturn3For4(){
        Fibonacci fibonacci = new Fibonacci();
        assertEquals(3, fibonacci.get(4));
    }

    public void testFibonnacciReturn8For6(){
        Fibonacci fibonacci = new Fibonacci();
        assertEquals(8, fibonacci.get(6));
    }

    public void testFibonnacciReturn55For10(){
        Fibonacci fibonacci = new Fibonacci();
        assertEquals(55, fibonacci.get(10));
    }

}

Запустим тесты  и увидим, что прохохят только 2, остальные не проходят. Пора написать правильное решение нашей задачи Фибоначчи. Изменим класс Fibonacci так, чтобы он решал правильно. Напишем рекурсивную функцию нахождения числа фибоначчи. 

public class Fibonacci {
    public int get(int n){
        if(n==1 || n== 2){
            return 1;
        }else{
            return get(n-1)+ get(n-2);
        }
    }
}

Мы знаем что первое и второе число Фибоначчи это 1, по этому вначале проверяем указанный порядковый номер, если он равен 1 или 2, то возвращаем 1. Иначе, возвращаем сумму двух предыдущих чисел Фибоначчи, используя этот же метод. Это идеально использование рекурсии. Метод будет вызывать самого себя пока не дойдет до 1 или 2, и после этого просто начнет суммировать результаты. 

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

public class Fibonacci {
    public int get(int n){
        if(n==1 || n== 2){
            return 1;
        }
        return get(n-1)+ get(n-2);
    }
}

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

Круто да? Меняете код сколько угодно раз и одним запуском тестов, вы можете проверить, работает ли ваш код правильно. И не нужно по сто раз перезапускать приложение чтобы проверять. 

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

Надеюсь автоматизированные тесты облегчат вам жизнь!

488 22
Alisher Alikulov