{"id":3631,"date":"2022-07-26T11:02:35","date_gmt":"2022-07-26T11:02:35","guid":{"rendered":"http:\/\/the-codest.localhost\/blog\/test-containers-how-to-make-tests-easier\/"},"modified":"2026-03-11T06:00:15","modified_gmt":"2026-03-11T06:00:15","slug":"testcontainere-hvordan-man-gor-test-lettere","status":"publish","type":"post","link":"https:\/\/thecodest.co\/da\/blog\/test-containers-how-to-make-tests-easier\/","title":{"rendered":"Testcontainere - Hvordan g\u00f8r man test lettere?"},"content":{"rendered":"<p>Moderne applikationsudvikling er baseret p\u00e5 en enkel regel:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><b>Brug sammens\u00e6tning<\/b><\/p>\n<\/blockquote>\n\n\n\n<p>Vi sammens\u00e6tter klasser, funktioner og tjenester til st\u00f8rre stykker software. Det sidste element er grundlaget for <a href=\"https:\/\/thecodest.co\/da\/dictionary\/microservices\/\">mikrotjenester<\/a> og <a href=\"https:\/\/thecodest.co\/da\/blog\/the-power-of-hexagonal-architecture\/\">Sekskantet arkitektur<\/a>. Vi vil gerne bruge eksisterende l\u00f8sninger, integrere dem med vores software og g\u00e5 direkte i gang. <a href=\"https:\/\/thecodest.co\/da\/dictionary\/what-is-the-size-of-your-potential-reachable-market\/\">marked<\/a>.<\/p>\n\n\n\n<p>Vil du h\u00e5ndtere kontoregistrering og gemme brugeren? <a href=\"https:\/\/thecodest.co\/da\/blog\/app-data-collection-security-risks-value-and-types-explored\/\">data<\/a>? Du kan v\u00e6lge en af OAuth-tjenesterne. M\u00e5ske tilbyder din applikation en form for abonnement eller betaling? Der er mange tjenester, der kan hj\u00e6lpe dig med at h\u00e5ndtere dette. Har du brug for nogle analyser p\u00e5 dit website, men forst\u00e5r ikke <a href=\"https:\/\/thecodest.co\/da\/blog\/cyber-security-dilemmas-data-leaks\/\">GDPR<\/a>? Du er velkommen til at v\u00e6lge en af de f\u00e6rdige l\u00f8sninger.<\/p>\n\n\n\n<p>Noget, der g\u00f8r udvikling s\u00e5 let fra et forretningsm\u00e6ssigt synspunkt, kan give dig hovedpine - i det \u00f8jeblik, hvor du skal skrive en simpel test.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">De fantastiske dyr: K\u00f8er, databaser og hvordan man tester dem<\/h2>\n\n\n\n<p>Unit testing er ret enkelt. Hvis du bare f\u00f8lger reglerne, s\u00e5 vil dit testmilj\u00f8 og <a href=\"https:\/\/thecodest.co\/da\/dictionary\/what-is-code-refactoring\/\">Kode<\/a> er sunde. Hvilke regler er det?<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><b>Let at skrive<\/b> - En enhedstest skal v\u00e6re nem at skrive, fordi man skriver mange af dem. Mindre indsats betyder, at der skrives flere tests.<\/li>\n\n\n\n<li><b>L\u00e6sbar<\/b> - Testkoden skal v\u00e6re let at l\u00e6se. Testen er en historie. Den beskriver softwarens opf\u00f8rsel og kan bruges som en genvej til dokumentation. En god enhedstest hj\u00e6lper dig med at rette fejl uden at debugge koden.<\/li>\n\n\n\n<li><b>P\u00e5lidelig<\/b> - Testen b\u00f8r kun fejle, hvis der er en fejl i det system, der testes. Er det indlysende? Ikke altid. Nogle gange best\u00e5r tests, hvis du k\u00f8rer dem en efter en, men fejler, n\u00e5r du k\u00f8rer dem som et s\u00e6t. De best\u00e5r p\u00e5 din maskine, men fejler p\u00e5 CI (<a href=\"https:\/\/blog.codinghorror.com\/the-works-on-my-machine-certification-program\/\">Virker p\u00e5 min maskine<\/a>). En god enhedstest har kun \u00e9n grund til at fejle.<\/li>\n\n\n\n<li><b>Hurtig<\/b> - tests skal v\u00e6re hurtige. Forberedelse til k\u00f8rsel, start og selve testudf\u00f8relsen skal v\u00e6re meget hurtig. Ellers vil du skrive dem, men ikke k\u00f8re dem. Langsomme tests betyder mistet fokus. Man venter og kigger p\u00e5 statuslinjen.<\/li>\n\n\n\n<li><b>Uafh\u00e6ngig<\/b> - Endelig skal testen v\u00e6re uafh\u00e6ngig. Denne regel udspringer af de foreg\u00e5ende. Kun virkelig uafh\u00e6ngige tests kan blive til en enhed. De forstyrrer ikke hinanden, kan k\u00f8res i vilk\u00e5rlig r\u00e6kkef\u00f8lge, og potentielle fejl afh\u00e6nger ikke af resultaterne af andre tests. Uafh\u00e6ngig betyder ogs\u00e5, at man ikke er afh\u00e6ngig af eksterne ressourcer som databaser, beskedtjenester eller filsystem. Hvis du har brug for at kommunikere med eksterne ressourcer, kan du bruge mocks, stubs eller dummies.<\/li>\n<\/ul>\n\n\n\n<p>Alt bliver kompliceret, n\u00e5r vi vil skrive nogle integrationstests. Det er ikke s\u00e5 slemt, hvis vi gerne vil teste nogle f\u00e5 tjenester sammen. Men n\u00e5r vi skal teste tjenester, der bruger eksterne ressourcer som databaser eller beskedtjenester, s\u00e5 beder vi om problemer.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">For at k\u00f8re testen skal du installere...<\/h3>\n\n\n\n<p>For mange \u00e5r siden, da vi ville lave nogle integrationstest og bruge f.eks. databaser, havde vi to muligheder:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Vi kan installere en database lokalt. Ops\u00e6t et skema og opret forbindelse fra vores test;<\/li>\n\n\n\n<li>Vi kan oprette forbindelse til en eksisterende instans \"et eller andet sted i rummet\".<\/li>\n<\/ol>\n\n\n\n<p>Begge havde fordele, begge havde ulemper. Men begge introducerer yderligere niveauer af kompleksitet. Nogle gange var det teknisk kompleksitet som f\u00f8lge af visse v\u00e6rkt\u00f8jers egenskaber, f.eks. installation og styring af Oracle DB p\u00e5 din localhost. Nogle gange var det en ulempe i processen, f.eks. at man skal v\u00e6re enig med testen. <a href=\"https:\/\/thecodest.co\/da\/dictionary\/how-to-lead-software-development-team\/\">hold<\/a> om JMS-brug ... hver gang du vil k\u00f8re tests.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Containere til unds\u00e6tning<\/h3>\n\n\n\n<p>I l\u00f8bet af de sidste 10 \u00e5r har ideen om containerisering vundet anerkendelse i branchen. S\u00e5 det er en naturlig beslutning at v\u00e6lge containere som l\u00f8sning p\u00e5 vores integrationstestproblem. Det er en enkel og ren l\u00f8sning. Du k\u00f8rer bare dit proces-build, og s\u00e5 virker det hele! Kan du ikke tro det? Se p\u00e5 denne enkle konfiguration af et maven-build:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"xml\" class=\"language-xml\">.\n   \n     com.dkanejs.maven.plugins.\n     docker-compose-maven-plugin.\n     4.0.0\n     \n       \n         up\n         test-compile\n         \n           op\n         \n         \n           ${<a href=\"https:\/\/thecodest.co\/da\/dictionary\/why-do-projects-fail\/\">projekt<\/a>.basedir}\/docker-compose.yml.\n           true.\n         \n       \n       \n         down\n         efter-integrationstest\n         \n           down\n         \n         \n           ${project.basedir}\/docker-compose.yml.\n           true.\n         \n       \n     \n   \n \n.<\/code><\/pre>\n\n\n\n<p>Og den <code>docker-compose.yml<\/code> Filen ser ogs\u00e5 ret flot ud!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"yaml\" class=\"language-yaml\">version: \"3.5\"\n\ntjenester:\n\n postgres:\n   container_name: reactivedb\n   image: postgres:13.2\n   genstart: altid\n   milj\u00f8:\n     - POSTGRES_USER=admin\n     - POSTGRES_PASSWORD=password\n     - POSTGRES_DB=byer\n   porte:\n     - \"5432:5432\"\n   m\u00e6ngder:\n     - postgres_data:\/data\/db\n\n pgadmin:\n   container_name: pgadmin4\n   image: dpage\/pgadmin4\n   genstart: altid\n   milj\u00f8:\n     PGADMIN_DEFAULT_EMAIL: admin@admin.com\n     PGADMIN_DEFAULT_PASSWORD: password\n   porte:\n     - \"15050:80\"\n   m\u00e6ngder:\n     - pgadmin_data:\/data\/pgadmin\n\nm\u00e6ngder:\n postgres_data:\n pgadmin_data:<\/code><\/pre>\n\n\n\n<p>Men kan du se problemet her?<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Et fragtskib, der blokerer alt<\/h3>\n\n\n\n<p>Eksemplet ovenfor er meget enkelt. Bare en postgres-database, pgAdmin og det er alt. N\u00e5r du k\u00f8rer<\/p>\n\n\n\n<p><code>bash<br>\n$ mvn clean verify<br>\n<\/code><br>s\u00e5 starter maven-plugin'et containerne og slukker dem efter testene. Problemerne begynder, n\u00e5r projektet vokser, og vores compose-fil ogs\u00e5 vokser. Hver gang skal du starte alle containere, og de vil v\u00e6re i live gennem hele buildet. Du kan g\u00f8re situationen lidt bedre ved at \u00e6ndre konfigurationen af plugin-udf\u00f8relsen, men det er ikke nok. I v\u00e6rste fald udnytter dine containere systemets ressourcer, f\u00f8r testene starter!<\/p>\n\n\n\n<p>Og det er ikke det eneste problem. Du kan ikke k\u00f8re en eneste integrationstest fra dit IDE. F\u00f8r det skal du starte containerne manuelt. Desuden vil den n\u00e6ste maven-k\u00f8rsel rive disse containere ned (se p\u00e5 <code>ned<\/code> udf\u00f8relse).<\/p>\n\n\n\n<p>S\u00e5 denne l\u00f8sning er som et stort fragtskib. Hvis alt fungerer godt, er det ok. Enhver uventet eller us\u00e6dvanlig opf\u00f8rsel f\u00f8rer til <a href=\"https:\/\/thecodest.co\/da\/blog\/why-us-companies-are-opting-for-polish-developers\/\">os<\/a> til en eller anden form for katastrofe.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Test containere - k\u00f8r containere fra tests<\/h2>\n\n\n\n<p>Men hvad nu, hvis vi kunne k\u00f8re vores containere fra tests? Ideen ser god ud, og den er allerede ved at blive implementeret. <a href=\"https:\/\/www.testcontainers.org\/\" rel=\"nofollow\">Testcontainere<\/a>Fordi vi taler om dette projekt, er her en l\u00f8sning p\u00e5 vores problemer. Ikke ideel, men ingen er perfekt.<\/p>\n\n\n\n<p>Dette er en <strong><a href=\"https:\/\/thecodest.co\/da\/blog\/top-programming-languages-to-build-e-commerce\/\">Java<\/a><\/strong> biblioteket, som underst\u00f8tter JUnit- og Spock-tests, hvilket giver lette og nemme m\u00e5der at k\u00f8re <a href=\"https:\/\/thecodest.co\/da\/dictionary\/docker-developer\/\">Docker<\/a> container. Lad os se p\u00e5 det og skrive noget kode!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Foruds\u00e6tninger og konfiguration<\/h3>\n\n\n\n<p>F\u00f8r vi g\u00e5r i gang, skal vi tjekke vores konfiguration. <strong>Testbeholdere<\/strong> behov:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Docker i version v17.09,<\/li>\n\n\n\n<li>Java minimum version 1.8,<\/li>\n\n\n\n<li>Adgang til netv\u00e6rk, is\u00e6r til docker.hub.<\/li>\n<\/ul>\n\n\n\n<p>Du kan l\u00e6se mere om kravene til specifikke OS og CI her<br>i <a href=\"https:\/\/www.testcontainers.org\/supported_docker_environment\/\" rel=\"nofollow\">dokumentation<\/a>.<\/p>\n\n\n\n<p>Nu er det tid til at tilf\u00f8je nogle linjer til <code>pom.xml<\/code>.<\/p>\n\n\n\n<aside>Jeg bruger Spring Boot i projektet for at reducere boilerplate. <strong>Testbeholdere<\/strong> er uafh\u00e6ngige af Spring Framework, og du kan bruge dem uden.<\/aside>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"xml\" class=\"language-xml\">org.testcontainers\n       testcontainers-bom.\n       ${testcontaines.version}\n       pom\n       import\n     \n   \n \n \n   \n     org.postgresql\n     postgresql.\n     k\u00f8rselstid.\n   \n   \n     org.testcontainers\n     postgresql.\n     test\n   \n   \n     org.testcontainers\n     junit-jupiter.\n     test<\/code><\/pre>\n\n\n\n<p>Jeg bruger <strong>Testbeholdere<\/strong> version <code>1.17.3<\/code>men du er velkommen til at bruge den nyeste.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Test med Postgres-container<\/h3>\n\n\n\n<p>Det f\u00f8rste skridt er at forberede vores instans af en container. Du kan g\u00f8re det direkte i testen, men det ser bedre ud med en uafh\u00e6ngig klasse.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"java\" class=\"language-java\">public class Postgres13TC extends PostgreSQLContainer {\n\n private static final Postgres13TC TC = new Postgres13TC();\n\n private Postgres13TC() {\n   super(\"postgres:13.2\");\n }\n\n public static Postgres13TC getInstance() {\n   return TC;\n }\n\n @Override\n public void start() {\n   super.start();\n   System.setProperty(\"DB_URL\", TC.getJdbcUrl());\n   System.setProperty(\"DB_USERNAME\", TC.getUsername());\n   System.setProperty(\"DB_PASSWORD\", TC.getPassword());\n }\n\n @Override\n public void stop() {\n   \/\/ g\u00f8r ingenting. Dette er en delt instans. Lad JVM h\u00e5ndtere denne operation.\n }\n}\n<\/code><\/pre>\n\n\n\n<p>I begyndelsen af testene opretter vi en forekomst af <code>Postgres13TC<\/code>. Denne klasse kan h\u00e5ndtere oplysninger om vores container. Det vigtigste her er databasens forbindelsesstrenge og legitimationsoplysninger. Nu er det tid til at skrive en meget simpel test.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"java\" class=\"language-java\">@Testcontainere\nclass SimpleDbTest {\n\n @Container\n private static Postgres13TC = Postgres13TC.getInstance();\n\n @Test\n void testConnection() {\n   assumeThat(postgres13TC.isRunning());\n   var connectionProps = new Properties();\n   connectionProps.put(\"user\", postgres13TC.getUsername());\n   connectionProps.put(\"password\", postgres13TC.getPassword());\n\n   try (Connection = DriverManager.getConnection(postgres13TC.getJdbcUrl(),\n       connectionProps)) {\n     var resultSet = connection.prepareStatement(\"Select 1\").executeQuery();\n     resultSet.next();\n     assertThat(resultSet.getInt(1)).isEqualTo(1);\n   } catch (SQLException sqlException) {\n     assertThat((Exception) sqlException).doesNotThrowAnyException();\n   }\n }\n}<\/code><\/pre>\n\n\n\n<p>Jeg bruger JUnit 5 her. Annotation <code>@Testcontainere<\/code> er en del af de udvidelser, der styrer containere i testmilj\u00f8et. De finder alle felter med <code>@Container<\/code> annotation og henholdsvis start- og stopcontainere.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Test med Spring Boot<\/h3>\n\n\n\n<p>Som jeg n\u00e6vnte f\u00f8r, bruger jeg Spring Boot i projektet. I dette tilf\u00e6lde er vi n\u00f8dt til at skrive lidt mere kode. Det f\u00f8rste skridt er at oprette en ekstra konfigurationsklasse.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"java\" class=\"language-java\">@Slf4j\noffentlig klasse ContainerInit implementerer\n   ApplicationContextInitializer {\n\n offentlig statisk Postgres13TC;\n\n static {\n   postgres13TC = Postgres13TC.getInstance();\n   postgres13TC.start();\n }\n\n @Override\n public void initialize(ConfigurableApplicationContext applicationContext) {\n   TestPropertySourceUtils.addInlinedPropertiesToEnvironment(\n       applicationContext,\n       \"spring.datasource.url=\" + postgres13TC.getJdbcUrl(),\n       \"spring.datasource.username=\" + postgres13TC.getUsername(),\n       \"spring.datasource.password=\" + postgres13TC.getPassword(),\n       \"db.host=\" + postgres13TC.getHost(),\n       \"db.port=\" + postgres13TC.getMappedPort(postgres13TC.POSTGRESQL_PORT),\n       \"db.name=\" + postgres13TC.getDatabaseName(),\n       \"db.username=\" + postgres13TC.getUsername(),\n       \"db.password=\" + postgres13TC.getPassword()\n   );\n }\n}<\/code><\/pre>\n\n\n\n<p>Denne klasse tilsides\u00e6tter de eksisterende egenskaber med v\u00e6rdier fra <strong>Testbeholder<\/strong>. De f\u00f8rste tre egenskaber er standard Spring-egenskaber. De n\u00e6ste fem er yderligere, brugerdefinerede egenskaber, der kan bruges til at konfigurere andre ressourcer og udvidelser som f.eks. liquibase:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"properties\" class=\"language-properties\">spring.liquibase.change-log=classpath:\/db\/changelog\/dbchangelog.xml\nspring.liquibase.url=jdbc:postgresql:\/\/${db.host:localhost}:${db.port:5432}\/${db.name:cities}\nspring.liquibase.user=${db.username:admin}\nspring.liquibase.password=${db.password:password}\nspring.liquibase.enabled=true<\/code><\/pre>\n\n\n\n<p>Nu er det tid til at definere en simpel integrationstest.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"java\" class=\"language-java\">@SpringBootTest(webEnvironment = RANDOM_PORT)\n@AutoConfigureTestDatabase(replace = NONE)\n@ContextConfiguration(initializers = ContainerInit.class)\n@Testcontainere\nklasse DummyRepositoryTest {\n\n @Autowired\n privat DummyRepository;\n\n @Test\n void shouldReturnDummy() {\n   var byId = dummyRepository.getById(10L);\n   var expected = new Dummy();\n   expected.setId(10L);\n   assertThat(byId).completes().emitsCount(1).emits(expected);\n }\n}<\/code><\/pre>\n\n\n\n<p>Vi har nogle ekstra kommentarer her.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>@SpringBootTest(webEnvironment = RANDOM_PORT)<\/code> - markerer testen som en Spring Boot-test og starter Spring-konteksten.<\/li>\n\n\n\n<li><code>@AutoConfigureTestDatabase(replace = NONE)<\/code> - Disse annotationer siger, at Spring Test Extension ikke b\u00f8r erstatte postgres-databasekonfigurationen med H2 i hukommelseskonfigurationen.<\/li>\n\n\n\n<li><code>@ContextConfiguration(initializers = ContainerInit.class)<\/code> - en ekstra for\u00e5rskontekst<br>konfiguration, hvor vi ops\u00e6tter egenskaber fra <strong>Testbeholdere<\/strong>.<\/li>\n\n\n\n<li><code>@Testcontainere<\/code> - Som tidligere n\u00e6vnt styrer denne annotation containerens livscyklus.<\/li>\n<\/ul>\n\n\n\n<p>I dette eksempel bruger jeg reaktive repositorier, men det fungerer p\u00e5 samme m\u00e5de med almindelige JDBC- og JPA-repositorier.<\/p>\n\n\n\n<p>Nu kan vi k\u00f8re denne test. Hvis det er f\u00f8rste gang, den k\u00f8res, skal motoren hente billeder fra docker.hub. Det kan tage et \u00f8jeblik. Derefter vil vi se, at to containere har k\u00f8rt. Den ene er postgres, og den anden er Testcontainers controller. Den anden container styrer de k\u00f8rende containere, og selv hvis JVM'en uventet stopper, slukker den containerne og rydder op i milj\u00f8et.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Lad os opsummere<\/h2>\n\n\n\n<p><strong>Testbeholdere<\/strong> er meget brugervenlige v\u00e6rkt\u00f8jer, som hj\u00e6lper os med at skabe integrationstest, der bruger Docker-containere. Det giver os mere fleksibilitet og \u00f8ger udviklingshastigheden. Korrekt ops\u00e6tning af testkonfiguration reducerer den tid, det tager at s\u00e6tte nye udviklere i gang. De beh\u00f8ver ikke at ops\u00e6tte alle afh\u00e6ngigheder, de skal bare k\u00f8re de skrevne tests med udvalgte konfigurationsfiler.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/thecodest.co\/contact\"><img decoding=\"async\" src=\"\/app\/uploads\/2024\/05\/interested_in_cooperation_.png\" alt=\"Samarbejdsbanner\"\/><\/a><\/figure>","protected":false},"excerpt":{"rendered":"<p>Leder du efter en m\u00e5de at lave test p\u00e5 en nemmere m\u00e5de? S\u00e5 har vi noget til dig! Se den f\u00f8lgende artikel og l\u00e6r, hvordan du g\u00f8r det muligt.<\/p>","protected":false},"author":2,"featured_media":3632,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[8],"tags":[],"class_list":["post-3631","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-software-development"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Test Containers \u2013 How to Make Tests Easier? - The Codest<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/thecodest.co\/da\/blog\/testcontainere-hvordan-man-gor-test-lettere\/\" \/>\n<meta property=\"og:locale\" content=\"da_DK\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Test Containers \u2013 How to Make Tests Easier?\" \/>\n<meta property=\"og:description\" content=\"Are you looking for a way to make tests in an easier way? We got you! Check the following article and learn how to make it possible.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/thecodest.co\/da\/blog\/testcontainere-hvordan-man-gor-test-lettere\/\" \/>\n<meta property=\"og:site_name\" content=\"The Codest\" \/>\n<meta property=\"article:published_time\" content=\"2022-07-26T11:02:35+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-03-11T06:00:15+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/test_containers_-_how_to_make_tests_easier_.png\" \/>\n\t<meta property=\"og:image:width\" content=\"960\" \/>\n\t<meta property=\"og:image:height\" content=\"540\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"thecodest\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"thecodest\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutter\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/test-containers-how-to-make-tests-easier\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/test-containers-how-to-make-tests-easier\\\/\"},\"author\":{\"name\":\"thecodest\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#\\\/schema\\\/person\\\/7e3fe41dfa4f4e41a7baad4c6e0d4f76\"},\"headline\":\"Test Containers \u2013 How to Make Tests Easier?\",\"datePublished\":\"2022-07-26T11:02:35+00:00\",\"dateModified\":\"2026-03-11T06:00:15+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/test-containers-how-to-make-tests-easier\\\/\"},\"wordCount\":1399,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/test-containers-how-to-make-tests-easier\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/05\\\/test_containers_-_how_to_make_tests_easier_.png\",\"articleSection\":[\"Software Development\"],\"inLanguage\":\"da-DK\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/thecodest.co\\\/blog\\\/test-containers-how-to-make-tests-easier\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/test-containers-how-to-make-tests-easier\\\/\",\"url\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/test-containers-how-to-make-tests-easier\\\/\",\"name\":\"Test Containers \u2013 How to Make Tests Easier? - The Codest\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/test-containers-how-to-make-tests-easier\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/test-containers-how-to-make-tests-easier\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/05\\\/test_containers_-_how_to_make_tests_easier_.png\",\"datePublished\":\"2022-07-26T11:02:35+00:00\",\"dateModified\":\"2026-03-11T06:00:15+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/test-containers-how-to-make-tests-easier\\\/#breadcrumb\"},\"inLanguage\":\"da-DK\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/thecodest.co\\\/blog\\\/test-containers-how-to-make-tests-easier\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"da-DK\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/test-containers-how-to-make-tests-easier\\\/#primaryimage\",\"url\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/05\\\/test_containers_-_how_to_make_tests_easier_.png\",\"contentUrl\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/05\\\/test_containers_-_how_to_make_tests_easier_.png\",\"width\":960,\"height\":540},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/blog\\\/test-containers-how-to-make-tests-easier\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/thecodest.co\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Test Containers \u2013 How to Make Tests Easier?\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#website\",\"url\":\"https:\\\/\\\/thecodest.co\\\/\",\"name\":\"The Codest\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/thecodest.co\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"da-DK\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#organization\",\"name\":\"The Codest\",\"url\":\"https:\\\/\\\/thecodest.co\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"da-DK\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/03\\\/thecodest-logo.svg\",\"contentUrl\":\"https:\\\/\\\/thecodest.co\\\/app\\\/uploads\\\/2024\\\/03\\\/thecodest-logo.svg\",\"width\":144,\"height\":36,\"caption\":\"The Codest\"},\"image\":{\"@id\":\"https:\\\/\\\/thecodest.co\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/pl.linkedin.com\\\/company\\\/codest\",\"https:\\\/\\\/clutch.co\\\/profile\\\/codest\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/thecodest.co\\\/#\\\/schema\\\/person\\\/7e3fe41dfa4f4e41a7baad4c6e0d4f76\",\"name\":\"thecodest\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"da-DK\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g\",\"caption\":\"thecodest\"},\"url\":\"https:\\\/\\\/thecodest.co\\\/da\\\/author\\\/thecodest\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Testcontainere - Hvordan g\u00f8r man test lettere? - The Codest","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/thecodest.co\/da\/blog\/testcontainere-hvordan-man-gor-test-lettere\/","og_locale":"da_DK","og_type":"article","og_title":"Test Containers \u2013 How to Make Tests Easier?","og_description":"Are you looking for a way to make tests in an easier way? We got you! Check the following article and learn how to make it possible.","og_url":"https:\/\/thecodest.co\/da\/blog\/testcontainere-hvordan-man-gor-test-lettere\/","og_site_name":"The Codest","article_published_time":"2022-07-26T11:02:35+00:00","article_modified_time":"2026-03-11T06:00:15+00:00","og_image":[{"width":960,"height":540,"url":"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/test_containers_-_how_to_make_tests_easier_.png","type":"image\/png"}],"author":"thecodest","twitter_card":"summary_large_image","twitter_misc":{"Written by":"thecodest","Est. reading time":"7 minutter"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/thecodest.co\/blog\/test-containers-how-to-make-tests-easier\/#article","isPartOf":{"@id":"https:\/\/thecodest.co\/blog\/test-containers-how-to-make-tests-easier\/"},"author":{"name":"thecodest","@id":"https:\/\/thecodest.co\/#\/schema\/person\/7e3fe41dfa4f4e41a7baad4c6e0d4f76"},"headline":"Test Containers \u2013 How to Make Tests Easier?","datePublished":"2022-07-26T11:02:35+00:00","dateModified":"2026-03-11T06:00:15+00:00","mainEntityOfPage":{"@id":"https:\/\/thecodest.co\/blog\/test-containers-how-to-make-tests-easier\/"},"wordCount":1399,"commentCount":0,"publisher":{"@id":"https:\/\/thecodest.co\/#organization"},"image":{"@id":"https:\/\/thecodest.co\/blog\/test-containers-how-to-make-tests-easier\/#primaryimage"},"thumbnailUrl":"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/test_containers_-_how_to_make_tests_easier_.png","articleSection":["Software Development"],"inLanguage":"da-DK","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/thecodest.co\/blog\/test-containers-how-to-make-tests-easier\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/thecodest.co\/blog\/test-containers-how-to-make-tests-easier\/","url":"https:\/\/thecodest.co\/blog\/test-containers-how-to-make-tests-easier\/","name":"Testcontainere - Hvordan g\u00f8r man test lettere? - The Codest","isPartOf":{"@id":"https:\/\/thecodest.co\/#website"},"primaryImageOfPage":{"@id":"https:\/\/thecodest.co\/blog\/test-containers-how-to-make-tests-easier\/#primaryimage"},"image":{"@id":"https:\/\/thecodest.co\/blog\/test-containers-how-to-make-tests-easier\/#primaryimage"},"thumbnailUrl":"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/test_containers_-_how_to_make_tests_easier_.png","datePublished":"2022-07-26T11:02:35+00:00","dateModified":"2026-03-11T06:00:15+00:00","breadcrumb":{"@id":"https:\/\/thecodest.co\/blog\/test-containers-how-to-make-tests-easier\/#breadcrumb"},"inLanguage":"da-DK","potentialAction":[{"@type":"ReadAction","target":["https:\/\/thecodest.co\/blog\/test-containers-how-to-make-tests-easier\/"]}]},{"@type":"ImageObject","inLanguage":"da-DK","@id":"https:\/\/thecodest.co\/blog\/test-containers-how-to-make-tests-easier\/#primaryimage","url":"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/test_containers_-_how_to_make_tests_easier_.png","contentUrl":"https:\/\/thecodest.co\/app\/uploads\/2024\/05\/test_containers_-_how_to_make_tests_easier_.png","width":960,"height":540},{"@type":"BreadcrumbList","@id":"https:\/\/thecodest.co\/blog\/test-containers-how-to-make-tests-easier\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/thecodest.co\/"},{"@type":"ListItem","position":2,"name":"Test Containers \u2013 How to Make Tests Easier?"}]},{"@type":"WebSite","@id":"https:\/\/thecodest.co\/#website","url":"https:\/\/thecodest.co\/","name":"Codest","description":"","publisher":{"@id":"https:\/\/thecodest.co\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/thecodest.co\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"da-DK"},{"@type":"Organization","@id":"https:\/\/thecodest.co\/#organization","name":"Codest","url":"https:\/\/thecodest.co\/","logo":{"@type":"ImageObject","inLanguage":"da-DK","@id":"https:\/\/thecodest.co\/#\/schema\/logo\/image\/","url":"https:\/\/thecodest.co\/app\/uploads\/2024\/03\/thecodest-logo.svg","contentUrl":"https:\/\/thecodest.co\/app\/uploads\/2024\/03\/thecodest-logo.svg","width":144,"height":36,"caption":"The Codest"},"image":{"@id":"https:\/\/thecodest.co\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/pl.linkedin.com\/company\/codest","https:\/\/clutch.co\/profile\/codest"]},{"@type":"Person","@id":"https:\/\/thecodest.co\/#\/schema\/person\/7e3fe41dfa4f4e41a7baad4c6e0d4f76","name":"thecodest","image":{"@type":"ImageObject","inLanguage":"da-DK","@id":"https:\/\/secure.gravatar.com\/avatar\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5dbfe6a1e8c86e432e8812759e34e6fe82ebac75119ae3237a6c1311fa19caf4?s=96&d=mm&r=g","caption":"thecodest"},"url":"https:\/\/thecodest.co\/da\/author\/thecodest\/"}]}},"_links":{"self":[{"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/posts\/3631","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/comments?post=3631"}],"version-history":[{"count":9,"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/posts\/3631\/revisions"}],"predecessor-version":[{"id":8016,"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/posts\/3631\/revisions\/8016"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/media\/3632"}],"wp:attachment":[{"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/media?parent=3631"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/categories?post=3631"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thecodest.co\/da\/wp-json\/wp\/v2\/tags?post=3631"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}