Сравнение CSV в тестах JUnit на Java – в случае ошибки указывайте конкретные строки с ошибками.

Вопрос или проблема

У меня есть несколько тестов Junit, которые сравнивают большие блоки JSON с помощью фреймворка под названием JsonUnit.

Когда тест не проходит, обычно это всего лишь несколько строк в JSON длиной более 1000 строк. Фреймворк JsonUnit даст мне точные разделы JSON, которые не прошли проверку, вот так:

но: JSON-документы различаются:

Найденно различие в узле “sent[0].acknowledgedTime”, ожидалось
<“09:56:22.216213”>, но было.

Найденно различие в узле “sent[0].reopeningNumber”, ожидалось
<“RA”>, но было <“RU”>.

Найденно различие в узле “sent[0].sentTime”, ожидалось
<“09:55:42.776926”>, но было <“09:55:53.901321”>.

Найденно различие в узле “sent[0].value”, ожидалось <1.0E+8>, но
было <2.0E+10>.

Найденно различие в узле “sent[0].volume”, ожидалось <10000>, но
было <30000>.

У меня также есть большие CSV длиной более 1000 строк, которые я хочу сравнить в тесте Junit. Если есть ошибка, я хочу, чтобы он дал мне точную строку(ы), которые не прошли проверку. Существует ли фреймворк для CSV, подобный JsonUnit?

Я просто прочитала бы CSV-документ в список строк и затем использовала бы AssertJ

assertThat(currentCsvAsLines)
    .contains("some, example, line");

Ответ или решение

Чтобы сравнивать CSV файлы в JUnit тестах и получать детальную информацию о местах, где происходят ошибки, вы можете воспользоваться библиотекой Apache Commons CSV для чтения CSV файлов и использовать AssertJ для проверки значений. Хотя нет прямого аналога JsonUnit для CSV, вы можете создать свою обертку, которая будет предоставлять информацию о различиях на уровне строк.

Вот пошаговое решение, как вы можете реализовать это:

  1. Добавьте зависимости в ваш проект: В файле pom.xml для Maven добавьте следующие зависимости:
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-csv</artifactId>
    <version>1.8</version> <!-- Убедитесь, что используете актуальную версию -->
</dependency>
<dependency>
    <groupId>org.assertj</groupId>
    <artifactId>assertj-core</artifactId>
    <version>3.21.0</version> <!-- Актуальная версия AssertJ -->
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version> <!-- Актуальная версия JUnit -->
</dependency>
  1. Создайте функцию для чтения CSV файла: С помощью Apache Commons CSV создайте метод для считывания CSV файла в список строк.
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class CsvUtils {
    public static List<String[]> readCsv(String filePath) throws IOException {
        List<String[]> records = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            Iterable<CSVRecord> csvRecords = CSVFormat.DEFAULT.withFirstRecordAsHeader().parse(reader);
            for (CSVRecord csvRecord : csvRecords) {
                String[] record = new String[csvRecord.size()];
                for (int i = 0; i < csvRecord.size(); i++) {
                    record[i] = csvRecord.get(i);
                }
                records.add(record);
            }
        }
        return records;
    }
}
  1. Создайте тест на сравнение CSV файлов: Используйте AssertJ для сравнения строк из двух CSV файлов.
import org.assertj.core.api.Assertions;
import org.junit.Test;

import java.io.IOException;
import java.util.List;

public class CsvComparisonTest {

    @Test
    public void compareCsvFiles() throws IOException {
        List<String[]> expected = CsvUtils.readCsv("path/to/expected.csv");
        List<String[]> actual = CsvUtils.readCsv("path/to/actual.csv");

        Assertions.assertThat(actual).hasSameSizeAs(expected);

        for (int i = 0; i < expected.size(); i++) {
            String[] expectedRow = expected.get(i);
            String[] actualRow = actual.get(i);
            if (!Assertions.assertThat(actualRow).isEqualTo(expectedRow)) {
                Assertions.fail("Различия найдены на строке " + (i + 1) + ". Ожидалось: " + String.join(", ", expectedRow) + 
                                " но было: " + String.join(", ", actualRow));
            }
        }
    }
}

Объяснение решения:

  • Чтение CSV: Мы читаем CSV файл с помощью Apache Commons CSV, загружая каждую строку в массив строк.
  • Сравнение: Мы сравниваем количество строк между двумя файлами. Если они не равны, это сразу вызывает ошибку. Для каждой строки сравниваются значения, и если они не равны, выводается детальная информация о строке, включая ожидаемую и фактическую строки.

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

Оцените материал
Добавить комментарий

Капча загружается...