Sechs Tipps zur Verwendung von PostgreSQL in Funktionstests

Im Jahr 2018 arbeitete er bei Akvelon Inc. Ich habe eine Person interviewt. Vor dem Interview gaben sie mir seine Testaufgabe zur Überprüfung: eine kleine Webanwendung wie ein Notizbuch oder eine Aufgabenliste - React \ TypeScript, C # im Backend und MS SQL Server als persistenter Speicher. Die Anwendung war in Mode: Mit einer Fülle von Unit-Tests auf Mocks, verpackt in ein Docker-Image - es ist klar, dass die Person es versucht hat. Und diese Lösung hatte nur einen Nachteil - sie funktionierte nicht. Absolut. Fehler beim Versuch, eine neue Zeile in der Datenbank zu speichern.



Ich erinnerte mich sehr gut an diesen Fall, da er mehrere häufig auftretende Probleme gleichzeitig hervorhob.


Die erste davon ist falsches Vertrauen aus Unit-Tests. Selbst eine 100% ige Abdeckung des Codes mit Tests garantiert nicht, dass keine Fehler darin enthalten sind.


– . , . : , production’. , Oracle, H2\HSQLDB, , , production (boolean, group by ).


PostgreSQL 10- 11-. ( ) , .



, : Embedded PostgreSQL Yandex QATools. . :



TestContainers , Docker’ .


otj-pg-embedded. , , HeadHunter DZone. Yandex QATools , otj-pg-embedded Windows MacOS , - . Liquibase Flyway « »:


abstract class DatabaseAwareTestBase {
    @RegisterExtension
    static final PreparedDbExtension embeddedPostgres =
            EmbeddedPostgresExtension.preparedDatabase(
                    LiquibasePreparer.forClasspathLocation("changelogs/changelog.xml"));
}

GitHub.



. PostgreSQL : , .


, , , , , . , .


. , delete from <table> . truncate. , . truncate , cascade:


truncate table tableA;
truncate table tableB cascade;
truncate table tableE;

, : , :


truncate table tableA, tableB, tableC, tableD, tableE;

cascade, ; . , .



, , , . , 11- Postgres ( 11- , 12-). otj-pg-embedded Zonky, , :


testImplementation enforcedPlatform('io.zonky.test.postgres:embedded-postgres-binaries-bom:11.6.0')
testImplementation 'io.zonky.test:embedded-postgres:1.2.6'

, 100% , .


    @Test
    void checkPostgresVersion() {
        final String pgVersion = jdbcTemplate.queryForObject("select version();", String.class);
        assertThat(pgVersion, startsWith("PostgreSQL 11.6"));
    }


, – . Java-, Linux, . , (, ), CI- , .


SQL


: plain SQL . xml, yml , , . , - \ . xml- psql\pgAdmin – . C plain SQL .


<databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
            http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
    <changeSet id="orders_table_create_2020-05-09" author="ivan.vakhrushev">
        <createTable tableName="orders">
            <column name="id" type="BIGINT">
                <constraints nullable="false" primaryKey="true"/>
            </column>
            <column name="shop_id" type="BIGINT">
                <constraints nullable="false"/>
            </column>
            <column name="buyer_id" type="BIGINT">
                <constraints nullable="false"/>
            </column>
            <column name="status" type="VARCHAR(20)">
            <column name="creation_time" type="TIMESTAMP">
                <constraints nullable="false"/>
            </column>
            <column name="update_time" type="TIMESTAMP"/>
        </createTable>
    </changeSet>
</databaseChangeLog>


--liquibase formatted sql
--changeset ivan.vakhrushev:orders_table_create_2020-05-09
create table if not exists orders
(
    id bigint not null primary key,
    shop_id bigint not null,
    buyer_id bigint not null,
    status varchar(20),
    creation_time timestamp not null,
    update_time timestamp
);


. Java 8 Java 11 . Instant\LocalDateTime. PostgreSQL Timestamp , «» . Java . , «» . , - :


Timestamp.valueOf(localDateTime.truncatedTo(ChronoUnit.MICROS));
Timestamp.from(instant.truncatedTo(ChronoUnit.MICROS));


. , - .
.


All Articles