Рубрики
Без рубрики

Подходы к управлению данными для ваших тестов

Введение Теперь у меня есть в моем личном репозитории GitHub способ, которым вы можете задавать мне связанные с этим вопросы… Помеченный как java, тестирование.

Теперь у меня есть в моем личном репозитории GitHub способ, которым вы можете задавать мне вопросы, связанные с темой разработки качества.

Рафаэль Тейшейра прислал мне вопрос относительно подхода к управлению данными |/. Поскольку эта тема очень интересна, я создал этот пост в блоге на основе своих ответов и объяснений.

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

Когда лучше всего запускать сценарии для определения конкретной конфигурации? И главное, когда система очень большая и сложная и требует нескольких настроек, что делать? На мой взгляд, лучший способ настроить данные в вашем тесте – это во время определения предварительного условия ваших тестов, чтобы вы могли совместно использовать одно и то же условие вместе с тестами, которые имеют общее условие данных. Я сталкиваюсь с той же “проблемой”, что и вы: система, которую я тестирую, очень большая и имеет разные условия передачи данных. Подход, который мы применяем, заключается в том, чтобы сгруппировать связанные тесты в одни и те же предварительные условия. Мы создаем базовый тестовый класс с предварительными и последующими условиями для этой ситуации.

Пример: система может запускать функциональные возможности с уровнями утверждений или без них, при этом для утверждений требуется дополнительная конфигурация, другая настройка данных и т.д… У нас есть два разных базовых тестовых класса, основанных на этих потребностях, поэтому мы можем легко управлять изоляцией этих условий (конфигурация, данные и т.д.)

Обычно я использую 3 разных подхода к управлению данными…

Генерация поддельных данных

Это самый простой способ, которым я пользуюсь все время. Вы можете использовать библиотеку генерации данных, чтобы передать ей ответственность. Я использую Java-мошенник . Вместо того, чтобы создавать данные внутри тестового кода (иногда я это делаю) Я использую этот подход:

  • Я создаю объект, который хочу смоделировать
  • Я создаю шаблон Builder для этой модели
  • Я создаю класс фабрики данных для создания объекта с учетом условий Я могу создавать

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

Примеры

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

Объект

public class Person {

    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() { return name; }

    public void setName(String name) { this.name = name; }

    public int getAge() { return age; }

    public void setAge(int age) { this.age = age; }
}

Строитель

public class PersonBuilder {

    private String name;
    private int age;

    public PersonBuilder setName(String name) {
        this.name = name;
        return this;
    }

    public PersonBuilder setAge(int age) {
        this.age = age;
        return this;
    }

    public Person build() {
        return new Person(name, age);
    }
}

Фабрика данных

public class PersonFactory {

    private final Faker faker;

    public PersonFactory() {
        faker = new Faker();
    }

    public Person personAbleToGetDriverLicense() {
        return new PersonBuilder().
            setName(faker.name().fullName()).
            setAge(faker.number().numberBetween(16, 65)).
            build();
    }

    public Person personNotAbleToGetDriverLicense() {
        return new PersonBuilder().
            setName(faker.name().fullName()).
            setAge(faker.number().numberBetween(0, 16)).
            build();
    }
}

Вы не можете использовать класс Data Factory в своих тестах для генерации каких-либо данных. В приведенном ниже примере вы можете увидеть использование personAble Для получения водительских прав , которое вернет объект Person с возрастом от 16 до 65 лет, поэтому вам не нужно заполнять, создавать атрибут для этого или генерировать весь объект, как мы это сделали на фабрике данных, в ваш тест.

public class PersonTest {

    @Test
    public void personCanApplyForDriverLicense() {
        PersonFactory personFactory = new PersonFactory();
        Person person = personFactory.personAbleToGetDriverLicense();
        person.getAge();
        // your test goes here
    }
}

Использование статических файлов

Я не так часто использую этот подход но я думаю, что это хороший вариант, и его нужно использовать, если у вас есть такая необходимость. Вы можете использовать различные статические файлы для получения данных, которые вы хотите использовать в своих тестах, например txt , csv-файл , json , yaml и т.д… При таком подходе вам нужна либо библиотека, которая может читать файл, либо создать класс для этого.

Имейте в виду, что:

  • все статические файлы (по крайней мере, в проектах Java) должны быть помещены в папку resource , а не вместе с вашим исходным кодом
  • вы можете постоянно изменять его, чтобы он мог следовать вашему процессу PR (change -> commit -> push -> approve), чтобы включить его в вашу основную ветку

В приведенном ниже примере я использую файл csv и встроенную функцию JUnit 5 для чтения CSV-файла, предоставленного библиотекой junit-jupiter-params с именем CSVFileSource

CSV-файл

product,amount
Micro SD Card 16Gb,6.09
JBL GO 2,22.37
iPad Air Case, 14.99

Тест

class JUnitCSVSourceTest {

    private static final String MAXIMUM_PRICE = "30.0";

    @CsvFileSource(resources = "/products.csv", numLinesToSkip = 1)
    void productsLassThan(String product, BigDecimal amount) {

        assertThat(product).isNotEmpty();
        assertThat(amount).isLessThanOrEqualTo(new BigDecimal(MAXIMUM_PRICE));
    }
}

Файл @CSVFileSource считывает содержимое файла, помещенного в resources , который должен находиться в папке resources , и пропускает первую строку, потому что в файле CSV первая строка является заголовком.

Динамическое потребление

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

  • счет с кредитной картой
  • счет с лимитом более 10 000 долларов США и инвестициями

У нас была реплика производственной базы данных, где разработчики (серверная часть и отдел контроля качества), когда требовались какие-то данные, выполняли этот ручной процесс:

  • запрос к базе данных-реплике с помощью SQL-скрипта
  • обновление данных в тестовом или статическом файле
  • запуск тестов

Это также был ручной процесс (настройка данных) перед регрессионным тестом… вы же видите, что это отнимает много времени.

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

public class MyTestWithDynamicData {

    @Test
    void cannotPayWithExpiredCreditCard() {
         DynamicData dynamicData = new DynamicData();

         CreditCard creditCard = dynamicData.creditCard().withRestriction(Restriction.EXPIRED);

         // extraction the credit card information to use in the test
         String holderName = creditCard.getHolderName();
         String creditCardNumber = creditCard.getNumber();
         String expirationDate = creditCard.getExpirationDate();
         String cvv = creditCard.getCvv();
    }
}

В приведенном выше примере нам нужна была кредитная карта с уже истекшим сроком действия. Метод с ограничением получил ограничение . ИСТЕК СРОК действия и добавил в запрос операторы SQL ( where предложение), чтобы вернуть объект, соответствующий этим критериям.

Мы можем применять различные подходы к получению данных. Я не упомянул (потому что сейчас я не использую этот подход) еще один, который заключается в том, чтобы генерировать данные, потребляющие и API.

Если у вас есть какие-либо вопросы, пожалуйста, не стесняйтесь комментировать этот пост или присылайте мне вопрос .

Спасибо, что уделили мне время!

Оригинал: “https://dev.to/eliasnogueira/how-i-created-my-1f98”