所以试图了解如何使用 testcontainers 测试 ktor 应用程序
这是我的代码
package com.app
import com.app.base.db.DbFactory
import com.app.features.auth.RegisterDTO
import com.app.plugins.*
import io.kotest.assertions.ktor.client.shouldHaveStatus
import io.kotest.core.extensions.install
import io.kotest.core.spec.style.FreeSpec
import io.kotest.extensions.testcontainers.JdbcTestContainerExtension
import io.ktor.client.*
import io.ktor.client.engine.apache.*
import io.ktor.client.request.*
import io.ktor.http.*
import io.ktor.serialization.kotlinx.json.*
import io.ktor.server.application.*
import io.ktor.server.plugins.contentnegotiation.*
import org.testcontainers.containers.PostgreSQLContainer
import io.ktor.server.testing.*
import kotlinx.serialization.json.Json
import org.jetbrains.exposed.sql.Database
class AuthSpec : FreeSpec({
val postgres = PostgreSQLContainer<Nothing>("postgres").apply {
withDatabaseName("test_appDB")
startupAttempts = 1
withUsername("test_viktor")
withPassword("test_longPass")
withExposedPorts(5432)
}
postgres.start()
val ds = install(JdbcTestContainerExtension(postgres)) {
poolName = "myconnectionpool"
maximumPoolSize = 8
idleTimeout = 10000
}
"register creator" - …Run Code Online (Sandbox Code Playgroud) 我在使用 Spring 应用程序进行集成测试时遇到问题。我正在使用 testcontainer 设置 pubsub 模拟器:
@Container
private static final PubSubEmulatorContainer pubsubEmulator =
new PubSubEmulatorContainer(DockerImageName.parse("gcr.io/google.com/cloudsdktool/cloud-sdk:317.0.0-emulators"));
@DynamicPropertySource
static void emulatorProperties(DynamicPropertyRegistry registry) {
registry.add("spring.cloud.gcp.pubsub.emulator-host", pubsubEmulator::getEmulatorEndpoint);
}
@Bean
CredentialsProvider googleCredentials() {
return NoCredentialsProvider.create();
}
Run Code Online (Sandbox Code Playgroud)
我正在发布这样的消息:
publisherTemplate.publish("My_Topic", "{\"name\": \"test\"}", headers)
Run Code Online (Sandbox Code Playgroud)
这是我的 pubsub 和 jackson 的应用程序配置:
@Configuration
@RequiredArgsConstructor
public class PubSubConsumerConfiguration {
private final ConsumerRepository consumerRepository;
@Bean
public PubSubMessageConverter pubSubMessageConverter(ObjectMapper objectMapper) {
return new JacksonPubSubMessageConverter(objectMapper);
}
@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
return mapper; …Run Code Online (Sandbox Code Playgroud) 我的 Java 和 Spring Boot 应用程序集成测试使用testContainers并且我在 Windows 计算机上使用Podman 。
当尝试运行集成测试时,我收到此权限错误:
Failed to load ApplicationContext
java.lang.IllegalStateException: Failed to load ApplicationContext
.....
Caused by: com.github.dockerjava.api.exception.InternalServerErrorException: Status 500: {"cause":"permission denied","message":"container create: statfs /var/run/docker.sock: permission denied","response":500}
Run Code Online (Sandbox Code Playgroud)
所有集成测试都失败了。
我需要向 Podman 提供特定的权限命令吗?
我有一个 .Net Core 6 项目,我正在尝试使用 TestContainers 设置集成测试。
我正在使用 Visual Studio 生成的 Dockerfile,这会构建我的映像,并且我能够在本地运行容器,并且 Web api 按预期工作,但是当我在 TestContainers 项目中运行相同的 DockerFile 时,出现异常:
Docker.DotNet.DockerApiException : Docker API responded with status code=Conflict, response={"message":"Container 51d3ead2c1f194aef0c5876cbc29affe89c81c40b142131cd037e6eba8f5e624 is not running"}
Run Code Online (Sandbox Code Playgroud)
这是我的 Dockerfile
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /
COPY ./nuget.config /nuget.config
COPY ["MyProjectDir/MyProject.csproj", "MyProject/"]
COPY ["Common/Common.csproj", "Common/"]
RUN dotnet restore "MyProjectDir/MyProject.csproj"
COPY . .
WORKDIR "/MyProject"
RUN dotnet build "MyProject.csproj" -c Release -o /app/build
FROM build AS publish …Run Code Online (Sandbox Code Playgroud) 我有以下用于本地开发的 docker-compose 文件:
version: '3.4'
networks:
mynetwork:
services:
samba:
image: instantlinux/samba-dc:latest
container_name: samba-dc
cap_add:
- CAP_SYS_ADMIN
hostname: my.org
environment:
DOMAIN_ACTION: provision
REALM: my.org
volumes:
- etc:/etc/samba
- lib:/var/lib/samba
ports:
- "53:53"
- "53:53/udp"
- "88:88"
- "88:88/udp"
- "389:389"
secrets:
- samba-admin-password
volumes:
etc:
lib:
secrets:
samba-admin-password:
file: secrets.yaml
Run Code Online (Sandbox Code Playgroud)
现在我尝试使用 testContainers 来实现集成测试:
@Testcontainers
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("test")
....
init {
try {
val ldapContainer =
GenericContainer("instantlinux/samba-dc:latest")
.withEnv("DOMAIN_ACTION", "provision")
.withEnv("REALM", "my.company")
.withEnv("ADMIN_PASSWORD_SECRET", "samba-admin-password")
.withExposedPorts(53, 88, 389)
ldapContainer.start()
print("Containers has started")
} …Run Code Online (Sandbox Code Playgroud) 不同测试容器的每次启动都会抛出com.github.dockerjava.api.exception.InternalServerErrorException: {"message":"Get https://quay.io/v1/_ping: dial tcp x.x.x.x: getsockopt: connection refused"}
这并不奇怪(docker 背后有一个公司代理)。如何配置 testcontainers 使用特定的 HTTP 代理?
另一种方法可能是禁用“ping”命令并使用我们公司的 docker 存储库。
我正在使用带有 Docker 代理的 Jenkins 声明式管道来构建和测试我的软件,包括使用 testcontainers 运行集成测试。我可以在我的开发环境中运行我的 testcontainers 测试(不使用 Jenkins),但它们在 Jenkins 下失败。
testcontainers Ryuk 资源收割守护进程不起作用
16:29:20.255 [testcontainers-ryuk] WARN o.t.utility.ResourceReaper - Can not connect to Ryuk at 172.17.0.1:32769
java.net.NoRouteToHostException: No route to host (Host unreachable)
at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399)
at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242)
at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:403)
at java.base/java.net.Socket.connect(Socket.java:591)
at java.base/java.net.Socket.connect(Socket.java:540)
at java.base/java.net.Socket.<init>(Socket.java:436)
at java.base/java.net.Socket.<init>(Socket.java:213)
at org.testcontainers.utility.ResourceReaper.lambda$start$1(ResourceReaper.java:112)
at java.base/java.lang.Thread.run(Thread.java:834)
Run Code Online (Sandbox Code Playgroud)
我能够解决这个问题禁用守护进程通过设置TESTCONTAINERS_RYUK_DISABLED环境变量true。但是,一些集成测试仍然反复失败。
使用ElasticsearchContainer重复的集成测试无法启动:等待 HTTP 端口响应超时。
17:04:57.595 [main] INFO d.e.c.7.1] - Starting container with ID: f5c653442103b9073c76f6ed91fc9117f7cb388d576606be8bd85bd9f3b2051d
17:04:58.465 …Run Code Online (Sandbox Code Playgroud) 我尝试升级我的测试以使用 TestContainers 和 Spring @DynamicPropertySource。
@Container
static Neo4jContainer<?> neo4jContainer = new Neo4jContainer<>("neo4j:4.0")
.withStartupTimeout(Duration.ofMinutes(5));
@DynamicPropertySource
static void neo4jProperties(DynamicPropertyRegistry registry) {
registry.add("org.neo4j.driver.uri", neo4jContainer::getBoltUrl);
registry.add("org.neo4j.driver.authentication.username", () -> "neo4j");
registry.add("org.neo4j.driver.authentication.password", neo4jContainer::getAdminPassword);
}
Run Code Online (Sandbox Code Playgroud)
当我运行示例测试并得到以下异常时,测试开始时 Neo4j docker 似乎尚未准备好。
java.lang.IllegalStateException: Error processing condition on org.neo4j.driver.springframework.boot.autoconfigure.DriverConfiguration.neo4jDriver
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60) ~[spring-boot-autoconfigure-2.2.6.RELEASE.jar:2.2.6.RELEASE]
at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:184) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:144) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:331) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:236) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:95) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:706) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532) ~[spring-context-5.2.5.RELEASE.jar:5.2.5.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.2.6.RELEASE.jar:2.2.6.RELEASE] …Run Code Online (Sandbox Code Playgroud) 我想运行一个通过 Docker 运行 ES 镜像的容器测试。\n经过一番研究,我发现https://www.testcontainers.org/并且他们还有一个内置的ES 模块。
\n\n因为我的开发环境在端口 9200 和 9300 中使用 ES,所以我更喜欢使用其他端口进行测试,让\xe2\x80\x99s 说 1200 和 1300。\n因此,要从 CLI 运行 docker 映像,我使用以下命令:
\n\ndocker run -p 1200:9200 -p 1300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.6.2
我尝试使用测试容器来做到这一点,例如:
\n\nstatic ElasticsearchContainer esContainer =\n new ElasticsearchContainer("docker.elastic.co/elasticsearch/elasticsearch:7.6.2")\n .withExposedPorts(1200, 9200)\n .withExposedPorts(1300, 9300)\n .withEnv("discovery.type", "single-node");\n // .waitingFor(Wait.forHttp("/")); // Wait until elastic start \xe2\x80\x93 cause an error\n\n@BeforeClass\npublic static void initEsDockerImage() {\n esContainer.start();\n esContainer.isRunning();\n}\nRun Code Online (Sandbox Code Playgroud)\n\nesContainer.isRunning() 中的断点:
\n\n端口是 32384,运行esContainer.getHttpHostAddress()return localhost/127.0.0.1:32847 并从 docker 仪表板运行:\n无论如何,无法与两者(1200 …
我有一个副项目,我正在使用 Spring Boot、Liquibase 和 Postgres。
我有以下测试序列:
test1();
test2();
test3();
test4();
Run Code Online (Sandbox Code Playgroud)
在这四个测试中,我创建了相同的实体。由于我没有在每个测试用例之后从表中删除记录,因此出现以下异常:org.springframework.dao.DataIntegrityViolationException
我想通过以下约束来解决这个问题:
@repository来清理数据库。简而言之:如何在每个测试用例之后从一个或多个表中删除记录,而无需 1) 使用@repository每个实体的 2) 在每个测试用例上终止并启动数据库容器?
testcontainers ×10
docker ×5
java ×4
spring-boot ×3
kotlin ×2
containers ×1
docker-java ×1
http-proxy ×1
jenkins ×1
kotest ×1
ktor ×1
liquibase ×1
neo4j ×1
networking ×1
permissions ×1
podman ×1
spring ×1