Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JUnit meets Docker

Oliver Boehm
September 18, 2018

JUnit meets Docker

Foliensatz zum Dockermeeting
(s. https://www.jugs.org/va2018/09-18.html)

Oliver Boehm

September 18, 2018
Tweet

More Decks by Oliver Boehm

Other Decks in Programming

Transcript

  1. JUnit meets Docker
    [email protected], SW-Arch...

    View Slide

  2. 1
    KURZE WEGE,
    SCHNELLE
    ENTSCHEIDUNGEN
    1
    Die Dr. Güldener Firmengruppe bietet Abrechnungsdienstleistungen und Services für Ärzte, Zahnärzte, Heil- und
    Hilfsmittelerbringer sowie Apotheker
    9 Standorte
    Hauptsitz Stuttgart
    Mehrere Mrd. €
    Abrechnungsvolumen
    Über 1.000 Mitarbeiter
    deutschlandweit
    • Mehr als 40 Jahre Erfahrung
    • Marktführer in der zahnärztlichen
    Privatliquidation
    • Innovative Leistungen und Services
    unterstützen Zahnarztpraxen, MKG-
    Chirurgen und Patienten
    • Abrechnungs- und Erstattungsunterstützung
    • Übernahme des gesamten Mahnwesens
    inklusive Forderungs- / Honorarausfallschutz
    • Teilzahlungsmöglichkeiten für Patienten
    • Mehr als 40 Jahre Erfahrung
    • Abrechnungs- und Finanzdienstleister im
    deutschen Heil- und Hilfsmittelmarkt
    • Abrechnung von Kassen- und
    Privatrezepten für Physiotherapeuten,
    Ergotherapeuten, Logopäden, Podologen,
    Sanitätshäuser
    • Abrechnung von Kassen- und
    Privatrezepten für Unternehmen aus den
    Bereichen Homecare und Medizintechnik
    • Mehr als 65 Jahre Erfahrung
    • Seit Jahrzehnten Partner für Apotheken
    und Ärzte bei der Abrechnung von
    Rezepten bzw. der Privatliquidation
    • Rezeptvorprüfung bei Apotheken
    „Scan & Check“
    • Prüfung der Rechnungsangaben
    anhand der GOÄ
    • Gewährleistung von Datensicherheit
    und Liquidität
    Über 45.000
    Kunden
    60 Entwickler
    8 Admins
    2 DevOps

    View Slide

  3. Die Test-Pyramide

    View Slide

  4. Die Test-Pyramide
    Unit-Tests

    View Slide

  5. Die Test-Pyramide
    Unit-Tests
    Integrations-
    Tests

    View Slide

  6. Die Test-Pyramide
    Unit-Tests
    Integrations-
    Tests
    UI-
    Tests

    View Slide

  7. www.testcontainers.org

    View Slide

  8. www.testcontainers.org
    Testcontainers is a Java
    library that supports JUnit
    tests, providing lightweight,
    throwaway instances of
    common databases, Selenium
    web browsers, or anything
    else that can run in a Docker
    container.

    View Slide

  9. Voraussetzungen

    View Slide

  10. Demo

    View Slide

  11. Beispiele
    @ClassRule
    public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer()
    .withUsername("Oli B.").withPassword("******");
    @BeforeClass
    public static void setUpLogConfig() {
    LOG.info("Setting up logConfig...");
    //URI jdbcURI = URI.create("jdbc:hsqldb:mem:logdb");
    //logConfig = new LogConfig(jdbcURI, "sa", "");
    URI jdbcURI = URI.create(postgreSQLContainer.getJdbcUrl());
    logConfig = new LogConfig(jdbcURI, postgreSQLContainer.getUsername(),
    postgreSQLContainer.getPassword());
    LOG.info("Setting up logConfig {} successful finished.", logConfig);
    }
    https://github.com/oboehm/gdv.xport/blob/feature/testcontainers/lib/src/test/java/gdv/xport/config/LogConfigIT.java

    View Slide

  12. Travis CI
    language: java
    jdk:
    - oraclejdk8
    sudo: required
    services:
    - docker

    View Slide

  13. View Slide

  14. @ClassRule
    public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer();
    /**
    * Einige Properties stehen fuer Spring erst nach Initialisierung des
    * Containers bereit. Das betrifft insbesondere die JDBC-URL. In der
    * @BeforeClass-Methode ist der Docker-Container initialisiert und die
    * Parameter koennen fuer Spring gesetzt werden.
    */
    @BeforeClass
    public static void setUpJdbcProperties() {
    System.setProperty("spring.datasource.url", postgreSQLContainer.getJdbcUrl());
    System.setProperty("spring.datasource.username", postgreSQLContainer.getUsername());
    System.setProperty("spring.datasource.password", postgreSQLContainer.getPassword());
    System.setProperty("spring.datasource.driverClassName", postgreSQLContainer.getDriverClassName());
    }

    View Slide

  15. @ClassRule
    public static PostgreSQLContainer postgreSQLContainer = new PostgreSQLContainer();
    /**
    * Einige Properties stehen fuer Spring erst nach Initialisierung des
    * Containers bereit. Das betrifft insbesondere die JDBC-URL. In der
    * @BeforeClass-Methode ist der Docker-Container initialisiert und die
    * Parameter koennen fuer Spring gesetzt werden.
    */
    @BeforeClass
    public static void setUpJdbcProperties() {
    System.setProperty("spring.datasource.url", postgreSQLContainer.getJdbcUrl());
    System.setProperty("spring.datasource.username", postgreSQLContainer.getUsername());
    System.setProperty("spring.datasource.password", postgreSQLContainer.getPassword());
    System.setProperty("spring.datasource.driverClassName", postgreSQLContainer.getDriverClassName());
    }
    /**
    * Damit nachfolgende Tests, die keinen Testcontainer verwenden, nicht
    * gestoert werden, loeschen wir vorsichtshalber wieder die gesetzten
    * System-Properties.
    */
    @AfterClass
    public static void clearJdbcProperties() {
    System.clearProperty("spring.datasource.url");
    System.clearProperty("spring.datasource.username");
    System.clearProperty("spring.datasource.password");
    System.clearProperty("spring.datasource.driverClassName");
    }

    View Slide

  16. Fertige Container

    View Slide

  17. Eigenbau
    @Rule
    public GenericContainer redis = new GenericContainer("redis:3.0.6")
    .withExposedPorts(6379);
    private Cache cache;
    @Before
    public void setUp() throws Exception {
    Jedis jedis = new Jedis(redis.getContainerIpAddress(), redis.getMappedPort(6379));
    cache = new RedisBackedCache(jedis, "test");
    }

    View Slide

  18. Troubleshooting (Win8)
    • Umgebungsvariablen überprüfen (Win8):
    DOCKER_HOST=tcp://192.168.99.100:2376
    DOCKER_CERT_PATH=%HOMEDRIVE%%HOMEPATH%\.docker\machine\certs
    DOCKER_TLS_VERIFY=0
    • ~/.testcontainers.properties anlegen mit
    checks.disable=true

    View Slide

  19. Erfahrungswerte
    • klappt ganz gut, trotz Exception
    09:05:47,416 ERROR main ientProviderStrategy ping failed with configuration Environment variables, system properties and defaults. Resolved:
    dockerHost=tcp://192.168.99.100:2376
    apiVersion='{UNKNOWN_VERSION}'
    registryUrl='https://index.docker.io/v1/'
    registryUsername='oboehm'
    registryPassword='null'
    registryEmail='null'
    dockerConfig='DefaultDockerClientConfig[dockerHost=tcp://192.168.99.100:2376,registryUsername=oboehm,registryPassword=,registryEmail=,registryUrl=https://index.docker.io/v1/,...
    due to org.rnorth.ducttape.TimeoutException: org.rnorth.ducttape.TimeoutException: java.util.concurrent.TimeoutException
    org.rnorth.ducttape.TimeoutException: org.rnorth.ducttape.TimeoutException: java.util.concurrent.TimeoutException
    at org.rnorth.ducttape.unreliables.Unreliables.retryUntilSuccess(Unreliables.java:53)
    at org.testcontainers.dockerclient.DockerClientProviderStrategy.ping(DockerClientProviderStrategy.java:189)
    at org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy.test(EnvironmentAndSystemPropertyClientProviderStrategy.java:42)
    at org.testcontainers.dockerclient.DockerClientProviderStrategy.lambda$getFirstValidStrategy$2(DockerClientProviderStrategy.java:112)
    at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:267)
    • Startzeit Container: ca. 20 Sek. (Win8; Mac: ca. 5 Sek.)
    • Overhead: Faktor 2 - 3

    View Slide

  20. View Slide

  21. Die Frage ist nicht:
    Können wir es uns
    leisten, zu testen?

    View Slide

  22. Die Frage ist:
    Können wir es uns
    leisten, nicht zu testen?

    View Slide

  23. Auf dem PC ist ein Problem aufgetreten. Er muss neu
    gestartet werden. Es werden einige Fehlinformationen
    gesammelt, und dann wird ein Neustart ausgeführt.
    (0% abgeschlossen)
    Dieser Absturz wurde ihnen präsentiert von: Optica Abrechnungszentrum

    View Slide

  24. Auf dem PC ist ein Problem aufgetreten. Er muss neu
    gestartet werden. Es werden einige Fehlinformationen
    gesammelt, und dann wird ein Neustart ausgeführt.
    (2% abgeschlossen)
    Dieser Absturz wurde ihnen präsentiert von: Optica Abrechnungszentrum

    View Slide

  25. Auf dem PC ist ein Problem aufgetreten. Er muss neu
    gestartet werden. Es werden einige Fehlinformationen
    gesammelt, und dann wird ein Neustart ausgeführt.
    (5% abgeschlossen)
    Dieser Absturz wurde ihnen präsentiert von: Optica Abrechnungszentrum

    View Slide

  26. Auf dem PC ist ein Problem aufgetreten. Er muss neu
    gestartet werden. Es werden einige Fehlinformationen
    gesammelt, und dann wird ein Neustart ausgeführt.
    (8% abgeschlossen)
    Dieser Absturz wurde ihnen präsentiert von: Optica Abrechnungszentrum

    View Slide

  27. Auf dem PC ist ein Problem aufgetreten. Er muss neu
    gestartet werden. Es werden einige Fehlinformationen
    gesammelt, und dann wird ein Neustart ausgeführt.
    (0% abgeschlossen)
    Dieser Absturz wurde ihnen präsentiert von: Optica Abrechnungszentrum
    Mit testcontainers wird es
    schwieriger, Ausreden*
    dafür zu finden!

    View Slide

  28. Auf dem PC ist ein Problem aufgetreten. Er muss neu
    gestartet werden. Es werden einige Fehlinformationen
    gesammelt, und dann wird ein Neustart ausgeführt.
    (0% abgeschlossen)
    Dieser Absturz wurde ihnen präsentiert von: Optica Abrechnungszentrum
    Mit testcontainers wird es
    schwieriger, Ausreden*
    dafür zu finden!
    * gute Ausreden bitte an: [email protected]

    View Slide