Статьи

Тестирование на основе данных с помощью Junit & easytest

В этой статье мы рассмотрим, как мы можем провести тестирование на основе данных с помощью Junit. Для этого я собираюсь использовать библиотеку под названием EasyTest.

Для TestNG, как мы знаем, встроен поставщик данных. Используя простой тест, мы можем использовать Junit для тестирования данных.

Что такое тестирование на основе данных?

Когда вы проводите тестирование на основе ваших данных, это относится к тестированию на основе данных. Формальное определение можно найти в вики.

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

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

Где я использую этот подход?

1. Когда мне нужно проверить большое количество данных и их вывод против методов БД или веб-API (REST / SOAP).

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

3. Когда мне нужно изолировать поведение изменения даты от изменений конфигурации.

Как мы собираемся достичь?

Мы собираемся решить это с помощью параметризованных тестов. И эти параметры будут принимать значения (тестовые данные) из наших определенных файлов. Это недостающая часть из TestNG с Junit. Мы решим с помощью библиотеки EasyTest.

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

Давайте учиться на примере:

Для обучения я использую простой класс калькулятора ( ссылка на Github ). Просто добавив два числа и ожидая результата, все в типе Double.

1
2
3
4
5
public class Calculator {
    public Double add(Double a, Double b){
        return a+b;
    }
}

И, давайте сделаем тестовый случай без Easy Test.

1
2
3
4
5
public class SimpleTest extends DataDrivenTest{
    @Test    public void testAddition(){
        Assert.assertEquals(25.5,calculator.add(10.5,15.0),0.01);
    }
}

Мы будем развивать этот простой тестовый пример с помощью Easy Test. Итак, давайте начнем с создания проекта.

Шаг А: Создание проекта Maven:

1. Создайте проект maven с вашим любимым идентификатором группы и идентификатором артефакта. (Я использовал org.automation & datadriven)

2. Включите следующие зависимости.

Для Junit (как мы используем)

1
2
3
4
5
dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>

Для легкого теста

1
2
3
4
5
<dependency>
    <groupId>org.easetech</groupId>
    <artifactId>easytest-core</artifactId>
    <version>1.4.0</version>
</dependency>

И для регистрации (это необязательно)

01
02
03
04
05
06
07
08
09
10
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.21</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.21</version>
</dependency>

[Этого будет достаточно, чтобы использовать простую проверку внутренней регистрации. ]

Теперь, чтобы предоставить параметр данных, нам нужно включить наши файлы данных. Как лучшая практика, я буду помещать все свои данные в качестве ресурсов . Итак, мне нужно включить в качестве ресурса в пом. Итак, наконец, проект pom.xml выглядит следующим образом .

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8"?><project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xmlns="http://maven.apache.org/POM/4.0.0"         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>org.automation</groupId>
    <artifactId>datadriven</artifactId>
    <version>1.0-SNAPSHOT</version>
 
    <dependencies>
        <!--Only mandatory part : start-->
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
        <dependency>
            <groupId>org.easetech</groupId>
            <artifactId>easytest-core</artifactId>
            <version>1.4.0</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!--Only mandatory part: End -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.21</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.21</version>
        </dependency>
    </dependencies>
    <build>
        <resources>
            <resource>
                <directory>src/test/resources</directory>
                <includes>
                    <include>**/*</include>
                </includes>
            </resource>
        </resources>
    </build>
</project>

Шаг B: Создание файлов данных: поддержка Easy Test

1. Excel: формат Office 97/2003 (расширение xls)

2. CSV: значение, разделенное запятыми

3. XML

4. Формат JSON через файлы CSV.

Примечание: Easy test также поддерживает пользовательские типы данных (мы пропустим эту часть, чтобы упростить ее в блоге, пример вы можете увидеть в Github)

Для CSV и EXCEL следуйте этим правилам

1. Первая строка, первый столбец будет именем метода (поэтому каждая строка этого столбца будет пустой)

2. Первая строка Во втором столбце все будет именем переменной параметра.

3. Все строки столбца, где написано имя метода, будут пустыми.

CSV:

Excel (.xls):

XML:

Вы можете увидеть все мои файлы из этого в github .

Теперь давайте загрузим данные из другого загрузчика данных.

Для загрузки данных, как правило, мы используем аннотации

1. @DataLoader для определения источника файла.

2. @Param, чтобы определить, какие данные столбца будут рассматриваться как элемент для получения.

Поскольку эти аннотации относятся к Easy Test, нам нужно запустить этот тестовый класс с DataDrivenTestRunner.class, который предоставляется

Итак, сначала мы видим загрузчик данных CSV.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
@RunWith(DataDrivenTestRunner.class)
public class CSVLoaderExample extends DataDrivenTest {
 
    @Test    @DataLoader(filePaths = "calculator.csv", loaderType = LoaderType.CSV)
    public String testAddFromCSV(@Param(name = "a") Double a,
                                 @Param(name = "b") Double b,
                                 @Param(name = "expected") Double expected) {
        Assert.assertEquals(expected, calculator.add(a, b), 0.1);
        return "success";
 
    }
    @Test    @DataLoader(filePaths = "calculator2.csv")
    public void testAdd(@Param(name = "a") Double a, @Param(name = "b")Double b, @Param(name = "expected")Double expected){
        Assert.assertEquals(expected, calculator.add(a,b),0.1);
    }
}

Здесь вы можете видеть, я

=> запуск теста с DataDrivenTestRunner.class

=> загрузка calculator.csv (и другой тоже)

=> получение параметра с именем a, b, ожидается.

Вот как выглядит содержимое файла CSV

01
02
03
04
05
06
07
08
09
10
11
12
testAddFromCSV,a,b,expected
 ,15.0,25.0,40
 ,15.0,25.0,40
 ,15.0,25.0,40
 ,15.0,25.0,40
 ,15.0,25.0,40
 ,15.0,25.0,40
 ,15.0,25.0,40
 ,15.0,25.0,40
 ,15.0,25.0,40
 ,15.0,25.0,40
 ,900.0,250.0,1150.0

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

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

Точно так же, если мы посмотрим на загрузчик данных Excel:

01
02
03
04
05
06
07
08
09
10
11
12
@RunWith(DataDrivenTestRunner.class)
public class ExcelLoaderExample extends DataDrivenTest {
    @Test    @DataLoader(filePaths = "calculator.xls", loaderType = LoaderType.EXCEL)
    public void testAddFromExcel(@Param(name = "a") Double a, @Param(name = "b") Double b, @Param(name = "expected") Double expected) {
        Assert.assertEquals(expected, calculator.add(a, b), 0.1);
    }
    @Test    @DataLoader(filePaths = {"calculator2.xls"})
    public void testAdd(@Param(name = "a") Double a, @Param(name = "b")Double b, @Param(name = "expected")Double expected){
        Assert.assertEquals(expected, calculator.add(a,b),0.1);
    }
 
}

И XML загрузчик данных

01
02
03
04
05
06
07
08
09
10
@RunWith(DataDrivenTestRunner.class)
public class XMLLoaderExample extends DataDrivenTest {
 
    @Test    @DataLoader(filePaths = "calculator2.xml", loaderType = LoaderType.XML)
    public String testAddXMLOutput(@Param(name = "a") Double a, @Param(name = "b") Double b, @Param(name = "expected") Double expected) {
        Assert.assertEquals(expected, calculator.add(a, b), 0.1);
        return "success";
 
    }
}

Замечания :

1. Путь к файлу содержит физический путь, если файл находится в classpath, достаточно имени файла. Поэтому, когда я определяю свои ресурсы pom.xml, мы должны включить наш файл данных, чтобы он работал следующим образом. Или мы должны поддерживать правильный путь для ввода.

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

3. Когда вы используете для загрузки несколько файлов одного типа, убедитесь, что у вас нет одинакового имени столбца. Если то же самое, столбцы из 2-го или более позднего файла будут учитываться. (Кстати, последний файл будет учтен)

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

5. Один метод / класс не поддерживает множественные аннотации загрузчика данных.

6. Загрузчик данных уровня метода перегрузит загрузчик данных уровня класса.

7. Используйте загрузчик данных на уровне класса, когда вы используете один файл для нескольких параметров метода тестирования.

8. В параметре данные используются в формате Long, String, Double. Но мы можем использовать пользовательский тип данных с нашими собственными парсерами. Простой тест имеет интерфейс для этого. (используйте AbstractConverter <YourDataType>)

9. Если нам нужно настроить отображение данных этого параметра, мы можем использовать аннотацию @Display при работе с загрузчиком. Вы можете увидеть пример здесь .

Вот несколько примеров для нескольких загрузчиков данных:

1
2
3
4
5
6
7
8
@RunWith(DataDrivenTestRunner.class)
public class MultipleDataLoaderExample extends DataDrivenTest {
 
    // only the first loader will be working..    // in here "calculator2.csv"    @Test    @DataLoader(filePaths = {"calculator2.csv","calculator3.xml"})
    public void testAdd(@Param(name = "a") Double a, @Param(name = "b")Double b, @Param(name = "expected")Double expected) {
        Assert.assertEquals(expected, calculator.add(a, b), 0.1);
    }
}
1
2
3
4
5
6
7
8
@RunWith(DataDrivenTestRunner.class)
public class MultipleDataLoaderExampleSameType extends DataDrivenTest{
 
    @Test    @DataLoader(filePaths = {"calculator3.csv","calculator2.csv"})//calculator2 is accepted not 2=> why, it honors the last item, top item of the array list of files    public void testAdd(@Param(name = "a") Double a, @Param(name = "b")Double b, @Param(name = "expected")Double expected){
        Assert.assertEquals(expected, calculator.add(a,b),0.1);
    }
 
}

Итак, вы можете увидеть более подробные примеры здесь.

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

Отчетность: легкий тест обеспечивает действительно легкий отчет… :). Просто используйте аннотацию. Вот несколько примеров.

Отчет по умолчанию: (введите PDF и сохраните в каталоге пользователя)

1
2
3
4
5
6
7
8
@RunWith(DataDrivenTestRunner.class)
@Reportpublic class DefaultReportExample extends DataDrivenTest{
    @Test    @DataLoader(filePaths = "calculator2.xls")
    public void testAdd(@Param(name = "a") Double a, @Param(name = "b") Double b, @Param(name = "expected") Double expected) {
        Assert.assertEquals(expected, calculator.add(a, b), 0.1);
    }
 
}

Отчет с изменением пути к классу в classpath: (отчеты хранятся в директории сборки, целевая папка в maven). Будет создано имя папки TestReports

01
02
03
04
05
06
07
08
09
10
11
12
13
14
@RunWith(DataDrivenTestRunner.class)
@Report(outputLocation = "classpath:TestReports")
public class ClassPathExampleReport extends DataDrivenTest{
 
    @Test    @DataLoader(filePaths = "calculator.xls")
    public void testAddFromExcel(@Param(name = "a") Double a, @Param(name = "b") Double b, @Param(name = "expected") Double expected) {
        Assert.assertEquals(expected, calculator.add(a, b), 0.1);
    }
    @Test    @DataLoader(filePaths = "calculator2.xls")
    public void testAdd(@Param(name = "a") Double a, @Param(name = "b") Double b, @Param(name = "expected") Double expected) {
 
        Assert.assertEquals(expected, calculator.add(a, b), 0.1);
    }
}

Отчет с изменением пути к классу в пути к папке: (мы указываем в нашей файловой системе)

01
02
03
04
05
06
07
08
09
10
11
12
@RunWith(DataDrivenTestRunner.class)
@Report(outputLocation = "file:TestReports")// default location = project working directorypublic class CustomPathExampleReport extends DataDrivenTest{
 
    @Test    @DataLoader(filePaths = "calculator.xls")
    public void testAddFromExcel(@Param(name = "a") Double a, @Param(name = "b") Double b, @Param(name = "expected") Double expected) {
        Assert.assertEquals(expected, calculator.add(a, b), 0.1);
    }
    @Test    @DataLoader(filePaths = "calculator2.xls")
    public void testAdd(@Param(name = "a") Double a, @Param(name = "b") Double b, @Param(name = "expected") Double expected) {
        Assert.assertEquals(expected, calculator.add(a, b), 0.1);
    }
}

В репозитории github я привел больше примеров, которые просты для понимания. Вот важные заметки.

1. Существует два типа отчета о функциональном тестировании и отчет о тестировании производительности (включая время для запуска тестов). Мы можем создать несколько типов отчетов.

2. Составление отчетов происходит медленно, поэтому время составления отчета будет учитываться как время выполнения теста.

3. Существует 3 типа формата файла отчета. Excel, PDF & HTML, где pdf является выбором по умолчанию. Мы можем создать несколько типов отчетов.

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

5. Расположение отчета может быть сохранено по конкретному пути к файлу или в каталоге сборки, пути к классам. Отчет о пути к классам будет очищен при использовании mvn clean, поэтому выбирайте осторожно.

Пример отчета в формате PDF:

Параллельные потоки: Easy test имеет простую аннотацию @Parallel, где мы можем определить, сколько потоков JVM выделит для тестирования для тестового класса.

1
2
3
4
5
6
7
8
@Parallel(threads = 5)//this is very fragilepublic class ParallelTestExample extends DataDrivenTest_withDefaultAnnotation {
 
    @Test    @DataLoader(filePaths = "calculator.xls", loaderType = LoaderType.EXCEL)
    public void testAddFromExcel(@Param(name = "a") Double a, @Param(name = "b")Double b, @Param(name = "expected")Double expected){
        Assert.assertEquals(expected, calculator.add(a,b),0.1);
    }
 
}

Как видите, этот тест будет выполняться с 5 потоками.

Мы можем запустить наш тестовый костюм параллельно с ParallelSuit

1
2
3
4
5
@RunWith(Suite.class)
@ParallelSuite(threads = 3)
@Suite.SuiteClasses({RepeatExample.class, TestWithPolicyExample.class})
public class ParallelSuitExample {
}

Примечание: это очень хрупко. Это может привести к ошибкам размещения ресурсов. И легкий тест не гарантирует, что они параллельны.

Повторение теста: в Easy Test мы можем повторить метод теста с аннотацией @Repeat.

01
02
03
04
05
06
07
08
09
10
@RunWith(DataDrivenTestRunner.class)
@TestPolicy(PolicyExample.class)
public class RepeatExample extends DataDrivenTest {
    @Test    @Repeat(times = 5)
    public void testAddFromExcel(@Param(name = "a") Double a,
                                 @Param(name = "b") Double b,
                                 @Param(name = "expected") Double expected) {
        Assert.assertEquals(expected, calculator.add(a, b), 0.1);
    }
}

Это серийно работает, а не параллельно.

Свойство Test: Easy test имеет приятную аннотацию @TestProperties, которую можно использовать для непосредственного добавления свойства test из пути к классам.

1
2
3
4
5
6
7
8
public class TestPropertiesExample extends DataDrivenTest_withDefaultAnnotation {
    @TestProperties(value = {"test.properties"})
    private Properties myProps;
 
    @Test    public void testAddition() {
        Assert.assertEquals("Easy Test Demos", myProps.getProperty("test.title"));
    }
}

[Игнорировать расширяющуюся часть, которая не нужна. Чтобы держать тест хорошо, я использовал. Вы можете увидеть форму источников GitHub. ]

Тестовая политика: тестовая политика — очень полезная вещь в Easy test, где мы можем определить тестовую политику в отдельном классе и использовать ее в тестовом классе.

Для этого определите класс политики.

1
2
3
4
5
6
7
8
@Ignore@Parallel(threads = 2)
@Report(reportTypes = {Report.REPORT_TYPE.DEFAULT,
        Report.REPORT_TYPE.METHOD_DURATION},
        outputFormats = Report.EXPORT_FORMAT.PDF,
        outputLocation = "file:TestReports")
@DataLoader(filePaths = "calculator.xls")// i preffer data loder should be with method@Display(fields = "id")
public class PolicyExample {
}

И использовать его в тестовом классе

1
2
3
4
5
6
7
8
@RunWith(DataDrivenTestRunner.class)
@TestPolicy(PolicyExample.class)
public class TestWithPolicyExample extends DataDrivenTest {
 
    @Test    public void  testAddFromExcel(@Param(name = "a") Double a, @Param(name = "b") Double b, @Param(name = "expected") Double expected) {
        Assert.assertEquals(expected, calculator.add(a, b), 0.1);
    }
}

Итак, мы видим, что политика будет определять файл данных + отчетность и параллельные потоки для потоков.
Где использовать?

=> Во время тестирования, если мы чувствуем, что у нас есть тестовая конфигурация отдельно.

=> Когда у нас есть отдельная конфигурация тестирования для запуска в другой ситуации. Например, тестирование в ПК разработчика или в CI, или для отчета о тестировании, или другой тип тестирования, и т. Д.

Минусы:

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

2. Выполнение Parallels может привести к тому, что связанный с ошибкой ресурс заблокирован или занят.

3. Пустой символ в Excel или CSV может вызвать ошибку. Поэтому будьте осторожны при создании файла данных.

4. Есть некоторые известные ошибки. Одной из популярных ошибок является то, что отчет о неудачном тесте генерируется только с помощью Excel data loader. Другие загрузчики данных не могут генерировать отчеты о неудачных тестах (генерируется только отчет о прохождении теста).

Надеюсь, этот пост поможет использовать Easy test. Пример моего Github: https://github.com/sarkershantonu/Automation-Getting-Started/tree/master/junit-easytest

Todo: Пример конвертера пользовательских типов данных. Я буду добавлять постепенно.