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 full-size 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 full-size slide

  3. Die Test-Pyramide

    View full-size slide

  4. Die Test-Pyramide
    Unit-Tests

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  7. www.testcontainers.org

    View full-size 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 full-size slide

  9. Voraussetzungen

    View full-size slide

  10. 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 full-size slide

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

    View full-size slide

  12. @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 full-size slide

  13. @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 full-size slide

  14. Fertige Container

    View full-size slide

  15. 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 full-size slide

  16. 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 full-size slide

  17. 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 full-size slide

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

    View full-size slide

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

    View full-size slide

  20. 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 full-size slide

  21. 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 full-size slide

  22. 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 full-size 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.
    (8% abgeschlossen)
    Dieser Absturz wurde ihnen präsentiert von: Optica Abrechnungszentrum

    View full-size 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.
    (0% abgeschlossen)
    Dieser Absturz wurde ihnen präsentiert von: Optica Abrechnungszentrum
    Mit testcontainers wird es
    schwieriger, Ausreden*
    dafür zu finden!

    View full-size 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.
    (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 full-size slide