Недавно у меня появилось время открыть исходный код предыдущего Система обмена мгновенными сообщениямиВзял и продолжил разработку(Действительно, друзья часто убеждали меня обновиться в эти годы.)。
Да, это действительно эти годы, ведь последняя версия вышла в августе 2019 года.
Этот период относительно важениз Просто обновитецентр метаданныхОтдельностоящий,Раньше это было и zookeeper Коды сильно связаны друг с другом, и после рефакторинга может быть несколько реализаций.
В будущем вы даже можете предоставить пакет jar для запуска всех серверных служб. В настоящее время вы можете использовать простой центр регистрации на основе памяти.
Кроме того, чтобы сделать больше, нужно добавить новый интегрированный тест измодуль.,Идеальной тестовой функции не существует. Будьте осторожны при слиянии кода.,Основные функциональные требования не могут быть гарантированы.
Кроме того, за последние несколько лет я также познакомился со многими отличными проектами с открытым исходным кодом (такими как Pulsar, OpenTelemetry, HertzBeat и т. д.), и все они имеют, прежде всего, полноценные процессы слияния кода; заключается в запуске тестового конвейера.
В сообществе OpenTelemetry это еще строже:
Они очень много выстраивают процессы тестирования.,Включает юнит-тесты, интеграционные тесты, стиль. кодирования、Совместимость с несколькими версиями и т. д.
Итак, объединив опыт этих прекрасных проектов, я также cim В проект добавлены новые связанные модули cim-integration-test,В то же время такжесуществовать github Связанные конфигурации настраиваются на действия, конечный эффект следующий:
существовать “Build with Maven”
Этап запускает модульный и интегрированный тест, и результаты теста в конечном итоге будут загружены в Codecov,тогда будетсуществовать PR Выведите отчет об испытаниях в область комментариев.
Соответствующая конфигурация действий выглядит следующим образом:
Просто настройте несколько заданий, основное внимание здесь:
mvn -B package --file pom.xml
Он скомпилирует и запустит весь тестовый код проекта.
Чтобы облегчить интегрированное тестирование, я добавил cim-integration-test
В этом модуле нет исходного кода, только код, связанный с тестированием.
Схема наследования класса выглядит следующим образом:
потому что Нам нужно сделать интегрированный тест cim Запущены все зависимые службы, в настоящее время в основном следующие службы:
Служба маршрутизации зависит от службы сервера, поэтому маршрут наследует сервер. Клиенту требуется запуск и маршрута, и сервера, поэтому он должен наследовать маршрут.
Давайте сначала посмотрим на тестовую реализацию сервера:
public abstract class AbstractServerBaseTest {
private static final DockerImageName DEFAULT_IMAGE_NAME = DockerImageName
.parse("zookeeper")
.withTag("3.9.2");
private static final Duration DEFAULT_STARTUP_TIMEOUT = Duration.ofSeconds(60);
@Container
public final ZooKeeperContainer
zooKeeperContainer = new ZooKeeperContainer(DEFAULT_IMAGE_NAME, DEFAULT_STARTUP_TIMEOUT);
@Getter
private String zookeeperAddr;
public void startServer() {
zooKeeperContainer.start();
zookeeperAddr = String.format("%s:%d", zooKeeperContainer.getHost(), zooKeeperContainer.getMappedPort(ZooKeeperContainer.DEFAULT_CLIENT_PORT));
SpringApplication server = new SpringApplication(CIMServerApplication.class);
server.run("--app.zk.addr=" + zookeeperAddr);
}
}
потому что server
зависит от zookeeper
какцентр метаданных,таксуществоватьзапускать Нужно сделать это раньше zookeeper Запускать.
В это время вам нужно использовать testcontainer Для обеспечения поддержки его можно использовать во время одного теста. docker запускать любую подобную службу существует CI Пройти интегрированный тест в Китае очень просто.
Большая часть промежуточного программного обеспечения, которое мы используем ежедневно, поддерживается и очень проста в использовании.
Сначала добавьте соответствующие зависимости:
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.7.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.6</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.2</version>
<scope>test</scope>
</dependency>
</dependencies>
Затем выберите сервис, на который нам нужно положиться, например PostgreSQL
:
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<version>1.19.8</version>
<scope>test</scope>
</dependency>
Затем существуют тесты запуска связанных с сервисом программ в коде.
class CustomerServiceTest {
static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(
"postgres:16-alpine"
);
CustomerService customerService;
@BeforeAll
static void beforeAll() {
postgres.start();
}
@AfterAll
static void afterAll() {
postgres.stop();
}
@BeforeEach
void setUp() {
DBConnectionProvider connectionProvider = new DBConnectionProvider(
postgres.getJdbcUrl(),
postgres.getUsername(),
postgres.getPassword()
);
customerService = new CustomerService(connectionProvider);
}
Обычно нам нужно получить ссылки на эти промежуточные программы, такие как IP-порты и т. д.
org.testcontainers.containers.ContainerState#getHost
org.testcontainers.containers.ContainerState#getMappedPort
Соответствующие IP и порт обычно получаются с помощью этих двух функций.
@Container
RedisContainer redis = new RedisContainer(DockerImageName.parse("redis:7.4.0"));
public void startRoute() {
redis.start();
SpringApplication route = new SpringApplication(RouteApplication.class);
String[] args = new String[]{
"--spring.data.redis.host=" + redis.getHost(),
"--spring.data.redis.port=" + redis.getMappedPort(6379),
"--app.zk.addr=" + super.getZookeeperAddr(),
};
route.setAdditionalProfiles("route");
route.run(args);
}
для route Это не только необходимо zookeeper
Все еще нужно Redis
Чтобы сохранить отношения маршрутизации пользователя, в это время Все еще нужно запустить Redis Контейнеры используются таким же образом.
Наконец, необходимо springboot
Чтобы запустить эти два приложения, мы непосредственно создаем SpringApplication
объект, а затем передать параметры, которые необходимо изменить, через --varname=value
Передайте данные в форму.
Вы также можете пройти setAdditionalProfiles()
Функция указывает текущее запущенное приложение. профиль, чтобы мы могли использовать соответствующий файл конфигурации в тестовом каталоге.
route.setAdditionalProfiles("route");
Например, здесь мы установили его на route ты можешь использовать application-route.yaml
как route файл конфигурации, нет необходимости передавать каждый параметр --
прошел дальше.
private void login(String userName, int port) throws Exception {
Long userId = super.registerAccount(userName);
SpringApplication client = new SpringApplication(CIMClientApplication.class);
client.setAdditionalProfiles("client");
String[] args = new String[]{
"--server.port=" + port,
"--cim.user.id=" + userId,
"--cim.user.userName=" + userName
};
client.run(args);
}
@Test
public void olu() throws Exception {
super.startServer();
super.startRoute();
this.login("crossoverJie", 8082);
this.login("cj", 8182);
MsgHandle msgHandle = SpringBeanFactory.getBean(MsgHandle.class);
msgHandle.innerCommand(":olu");
msgHandle.sendMsg("hello");
}
Что мы действительно хотим проверить, так это работу клиента. Если функция клиента работает нормально, это означает, что сервер и маршрут также в порядке.
Такие как здесь olu(oline user)
Процесс тестирования:
Окончательные результаты испытаний соответствуют ожиданиям.
Не знаю, заметили ли вы сейчас проблему сохранения существуиз в тестовом коде. Основная причина в том, что ее нельзя утверждать.
потому чтоклиент、route、server Все они запускаются с точки зрения приложения, и некоторые ключевые показатели получить невозможно.
Например, вывод существует в строке user,Когда клиенткак заявка,онлайн-пользователи просто печатают существующее прямо на терминале,и Нет прямого доступа к интерфейсу для возврата проводных данных, то же самое касается отправки и получения сообщений;
По сути, это все интерфейсы внутри приложения, но они представляют собой единое целое. springboot
Приложение не предоставляет таких возможностей.
Существенная проблема в том, что здесь должен быть модуль client-sdk. Клиент также реализован на основе этого sdk, чтобы можно было лучше тестировать связанные функции.
После этого мы собираемся выделить sdk в отдельный модуль, чтобы можно было легко реализовать разные взаимодействия на основе этого sdk и даже сделать UI-интерфейс.
Другая проблема в том, что я напрямую client/route/server
изполагатьсяинтегрированныйприезжать integration-test
В модуле:
<dependency>
<groupId>com.crossoverjie.netty</groupId>
<artifactId>cim-server</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.crossoverjie.netty</groupId>
<artifactId>cim-forward-route</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.crossoverjie.netty</groupId>
<artifactId>cim-client</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
существовать IDEA Вы можете напрямую запустить тестовые примеры здесь, нажав кнопку тестирования напрямую, но если вы хотите пройти mvn test
Возникла проблема.
существование не удалось во время компиляции, я долго проверял и наконец выяснил, что это было потому. что Эти три модульных приложения используют Springboot Плагин сборки:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
Эти модули в конечном итоге будут упакованы в springboot из jar пакет, в результате чего integration-test существовать Не удалось загрузиться изииспользовать внутрииздобрый。
Хорошего решения пока не найдено,Мне просто нужно сначала удалить эти плагины.,Если требуется упаковка, укажите плагин вручную.
mvn clean package spring-boot:repackage -DskipTests=true
На самом деле, основная проблема здесь в том, что нет многоуровневого результата. Лучше всего полагаться на него. route
и server
из SDK Чтобы протестировать.
сейчассуществоватьпотому что Есть тест из CI Каждый также может внести свой вклад, вы можете посмотреть здесь help want
,Для начала есть несколько простых и легких вещей.
https://github.com/crossoverJie/cim/issues/135
Справочные ссылки: