Cucumber — это фреймворк для тестирования, который поддерживает подход Data-Driven.
Что такое тестирование, управляемое данными?
Data-Driven Testing, DDT — это подход к тестированию программного обеспечения, при котором для управления процессом тестирования используются наборы данных. Этот подход предполагает тестирование приложения с помощью ряда входных значений, каждое из которых предназначено для проверки определенной фичи или функциональности приложения.
Зачем прибегать к этому виду тестирования?
У тестировщиков часто есть несколько наборов данных, которые используются для одного теста, и создание отдельных тестов с этими различными наборами данных может занять много времени. Этот тип тестирования позволяет выполнить тест–кейс несколько раз с различными наборами данных (входными данными) и проверочными значениями.
Применение Data-driven тестирования целесообразно по следующим причинам:
Приводит к увеличению тестового покрытия — использование в качестве входных данных различных наборов данных позволяет охватить широкий спектр сценариев и комбинаций входных данных.
Дает возможность повторно использовать тестовые скрипты — тестовые скрипты разрабатываются с учетом возможности их повторного использования, что позволяет выполнять их с несколькими наборами входных данных.
Помогает быстрее находить баги — тестирование различных комбинаций входных данных позволяет быстро выявить баги и аномалии в системе на этапе тестирования.
Тестирование на основе данных дает нам множество преимуществ. Однако, как и любой другой подход, оно имеет ряд потенциальных «подводных камней» и проблем, которые следует учитывать:
Управление набором входных данных — управление большим набором файлов входных данных может быть трудоемким и сложным.
Валидность тестовых данных — наиболее важным моментом является наличие валидных наборов тестовых данных, в противном случае можно получить неточные результаты тестирования, ложноположительные или ложноотрицательные.
Сопровождение и обновление: по мере развития системы тестовые скрипты необходимо актуализировать, а управление тестовыми скриптами и тестовыми данными может оказаться сложной задачей.
Data-driven тестирование в Cucumber
Cucumber поддерживает управляемое данными тестирование с помощью раздела Scenario Outline и примеров. Scenario Outline — это мощная фича, которая позволяет запускать один и тот же сценарий с различными входными данными или наборами данных. Она позволяет написать один сценарий с плейсхолдерами в полях для ввода текста, а Cucumber автоматически сгенерирует несколько сценариев, заменив эти плейсхолдеры реальными данными.
Использование шаблона сценария для написания сценария тестирования
Ниже приведен пример сценария тестирования для сравнения двух CSV-файлов с использованием шаблона сценария.
Фича: Сравнение данных в csv-файлах
Схема сценария: Сравнение двух CSV-файлов
Даны два файла с входными данными "<file1>" и "<file2>".
Когда мы сравниваем эти два файла
Содержимое первого файла должно "<matchOrNot>" содержимому второго.
Примеры:
| file1 | file2 | matchOrNot |
| input1.csv | input2.csv | match |
| input3.csv | input4.csv | not match |
В данном примере шаблон сценария задается в фича-файле с плейсхолдерами для указания части путей к CSV-файлам и ожидаемых результатов совпадений. Ключевое слово Scenario Outline используется для указания того, что у нас есть сценарий с несколькими примерами. Таблица примеров определяется с помощью ключевого слова Examples и содержит различные наборы входных данных, которые мы хотим сравнить.
import io.cucumber.java.en.Given;
import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import static org.junit.Assert.assertEquals;
public class Steps {
private static final String INPUT_DATA_PATH = "./src/test/resources/inputData/";
private String path1;
private String path2;
private boolean filesMatch;
@Given("two input files {string} and {string}")
public void getPathToCsvFiles(String fileName1, String fileName2) {
this.path1 = INPUT_DATA_PATH + fileName1;
this.path2 = INPUT_DATA_PATH + fileName2;
}
@When("we compare those two files")
public void compareFiles() {
filesMatch = compareCSVFiles(path1, path2);
}
@Then("the content from first input should {string} the content from the second one")
public void filesShouldMatchOrNot(String matchOrNot) {
boolean expectedMatch = matchOrNot.equals("match");
assertEquals(expectedMatch, filesMatch);
}
private boolean compareCSVFiles(String file1Path, String file2Path) {
try (BufferedReader reader1 = new BufferedReader(new FileReader(file1Path));
BufferedReader reader2 = new BufferedReader(new FileReader(file2Path))) {
String line1, line2;
int lineCount = 1;
while ((line1 = reader1.readLine()) != null && (line2 = reader2.readLine()) != null) {
if (!line1.equals(line2)) {
return false; }
lineCount++;
}
// Verify if there are any unprocessed lines remaining in the fields
if (reader1.readLine() != null || reader2.readLine() != null) {
return false;
}
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
}
Файл с определением шагов ("Steps.java") содержит реализацию определений шагов, которые соответствуют шагам шаблона сценария. На шаге getPathToCsvFiles
задаются пути к файлам, на шаге compareFiles
производится сравнение файлов, а на шаге filesShouldMatch
проверяется ожидаемый результат совпадения.
На шаге compareFiles
мы вызываем метод compareCsvFiles
, который сравнивает файлы с входными данными построчно. Он возвращает булево значение true
, если все строки в файлах с входными данными одинаковы, и false
в противном случае.
Чтобы сравнить два файла с входными данными, мы можем использовать исполнитель тестов Cucumber на основе предоставленных примеров.
import io.cucumber.junit.CucumberOptions;
import net.serenitybdd.cucumber.CucumberWithSerenity;
import org.junit.runner.RunWith;
@RunWith(CucumberWithSerenity.class)
@CucumberOptions(
features = "src/test/resources/compareCsvFiles.feature",
plugin = {"pretty"},
glue = {"steps"}
)
public class Runner {
}
Заключение
Тестирование на основе данных позволяет сократить объем ручных действий, необходимых для проведения тестирования, а также упростить управление и сопровождение тест-кейсов. В целом использование тестирования на основе данных позволяет повысить качество программного обеспечения и гарантировать, что оно соответствует требованиям и ожиданиям пользователей.
В завершение всех QA-инженеров приглашаем на ближайшие открытые уроки, на которых разберем темы: