ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

04-Native模式和单元测试

2021-01-17 14:31:58  阅读:290  来源: 互联网

标签:04 单元测试 quarkus io test import public Native


Naitive 和 Testing

Quarkus 与当前流行的Java应用的区别是提供了基于GraalVM实现的本地镜像模式,使用这种方式才能发挥Quarkus的最大优势。当前并不是说JVM不行,在我们的压测中JVM模式的QPS竟比Native模式要高,说明我们对于Native的优化还没有到位= =
Quarkus 同样提供了基于Junit的单元测试,并提供了Native模式下的实现。
本章将会讲这两部分,Native模式同样也会基于容器运行,如docker、OpenShift容器模式后面再讲。

本章目标

  • 1.如何打Native模式的包
  • 2.如何使用单元测试
  • 3.如何使用Native单元测试

1.如何打Native模式的包

1.1 Quarkus的执行都是依靠包管理工具来实现的,我们的教程基于Maven 下面添加插件

<profiles>
        <profile>
            <id>native</id>
            <properties>
                <quarkus.package.type>native</quarkus.package.type>
            </properties>
            <build>
                <plugins>
                    <plugin>
                        <groupId>io.quarkus</groupId>
                        <artifactId>quarkus-maven-plugin</artifactId>
                        <version>${quarkus-plugin.version}</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>native-image</goal>
                                </goals>
                                <configuration>
                                    <enableHttpUrlHandler>true</enableHttpUrlHandler>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                    <plugin>
                        <artifactId>maven-failsafe-plugin</artifactId>
                        <version>${surefire-plugin.version}</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>integration-test</goal>
                                    <goal>verify</goal>
                                </goals>
                                <configuration>
                                    <systemPropertyVariables>
                                        <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
                                        <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                                        <maven.home>${maven.home}</maven.home>
                                    </systemPropertyVariables>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

可以看到Quarkus 提供了一个-P 命令 native 我们执行打包时带上这个命令就是在打native包了。 后面的第一个插件就是打包插件,第二个插件是Native模式单元测试用的。打包命令如下:
mvn clean package -Pnative

执行命令前还需要确定下环境是否已经满足:
(1)配置了GraalVM的环境变量,使用java --version 验证,具体配置方式在第一讲。
(2)我们的开发机上安装了native-image ${GRAALVM_HOME}/bin/gu install native-image 不同的系统安装可能有些差异,官网也进行了说明如 MacOS Catalina
在这里插入图片描述
1.2 下面执行打Native包的命令
注意:本地包的编译打包过程有点漫长,这个主要看机器配置。耐心等待即可。平常我们开发均使用JVM即可。
在这里插入图片描述
看看target下都生成了什么吧
在这里插入图片描述
可以看到有两种包 一种就是JVM的Jar包 还有一种就是我们要的本地可执行文件 红框框标注的。

打包虽然有点漫长,那看看启动速度吧
在这里插入图片描述
这个速度在Spring中或许都不敢想象哈。

2.如何使用单元测试

2.1 引入单元测试的依赖

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-junit5</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>rest-assured</artifactId>
    <scope>test</scope>
</dependency>

为了支持junit5 还需要添加这个插件做适配

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>${surefire-plugin.version}</version>
    <configuration>
       <systemPropertyVariables>
          <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
          <maven.home>${maven.home}</maven.home>
       </systemPropertyVariables>
    </configuration>
</plugin>

2.2 为了写单元测试,我们先写几个接口

@Path("/hello")
public class GreetingResource {

    @Inject
    GreetingService service;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    @Path("/greeting/{name}")
    public String greeting(@PathParam String name) {
        return service.greeting(name);
    }

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "hello";
    }
}

2.3 写单元测试

package org.acme.getting.started.testing;

import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.Test;

import java.util.UUID;

import static io.restassured.RestAssured.given;
import static org.hamcrest.CoreMatchers.is;

@QuarkusTest
public class GreetingResourceTest {

    @Test
    public void testHelloEndpoint() {
        given()
          .when().get("/hello")
          .then()
             .statusCode(200)
             .body(is("hello"));
    }

    @Test
    public void testGreetingEndpoint() {
        String uuid = UUID.randomUUID().toString();
        given()
          .pathParam("name", uuid)
          .when().get("/hello/greeting/{name}")
          .then()
            .statusCode(200)
            .body(is("hello " + uuid));
    }

}

我们的Demo中使用了RestAssured.given()方法来访问一个我们的Http服务,来验证Http服务是否正常。RestAssured其实就是单元测试封装的一个Http Client 通过它的API来访问我们的服务。需要测试的话只需要熟悉一下他的API 就行了。

需要注意的是,如果我们的配置使用了区分环境的配置如 dev、test、prod、那么我们的配置文件中也需要有test环境必要的配置,如数据库连接等。Quarkus的分环境配置会和使用配置中心Consul一块来讲。test环境默认走的端口是是8081 注意不要冲突。可以通过配置来修改。

quarkus.http.test-port=8888

2.4 测试特定接口
个人觉得没有太大用,所以大家如果有需要就看文档吧使用也很简单。https://quarkus.io/guides/getting-started-testing#testing-a-specific-endpoint

2.5 测试Service方法
有时候我们并不需要直接测试接口是否正确,只需要测试一下我们的逻辑方法是否正常。那么我们可以直接注入Service类直接调用方法来测试,当然调用服务的方式也是可以的。

package org.acme.getting.started.testing;

import javax.inject.Inject;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import io.quarkus.test.junit.QuarkusTest;

@QuarkusTest
public class GreetingServiceTest {

    @Inject 
    GreetingService service;

    @Test
    public void testGreetingService() {
        Assertions.assertEquals("hello Quarkus", service.greeting("Quarkus"));
    }
}

2.6 实现自己的单元测试注解 组合拦截器
在上面吧的测试用我们都是使用的官方提供的@QuarkusTest注解,我们可以自定义组合我们需要的注解。
如 在我们的单元测试中需要添加事务,我们可以直接在方法或者类上添加@Transaction注解,也可以自定义我们的组合注解。

@QuarkusTest
@Stereotype
@Transactional
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface TransactionalQuarkusTest {
}

其实也很少用到,知道就行了。
那如果我们的单元测试需要操作数据,但是不想让测试结果影响正常的数据,我们期望对于测试完成之后将对数据库的操作全部rollback,我们可以使用io.quarkus.test.TestTransaction

2.7 单元测试的回调方法
官方提供了接口供我们实现。

io.quarkus.test.junit.callback.QuarkusTestBeforeClassCallback

io.quarkus.test.junit.callback.QuarkusTestAfterConstructCallback

io.quarkus.test.junit.callback.QuarkusTestBeforeEachCallback

io.quarkus.test.junit.callback.QuarkusTestAfterEachCallback

2.7 修改单元测试的配置环境
默认情况下,单元测试走的是test profile的环境,但有时需要走其他的环境 如dev或者自定义环境等等。 用的也不多,通过实现QuarkusTestProfile 实现

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import io.quarkus.test.junit.QuarkusTestProfile;
import io.quarkus.test.junit.QuarkusTestProfile.TestResourceEntry;

public class MockGreetingProfile implements QuarkusTestProfile {

    @Override
    public Map<String, String> getConfigOverrides() { 
        return Collections.singletonMap("quarkus.resteasy.path","/api");
    }

    @Override
    public Set<Class<?>> getEnabledAlternatives() { 
        return Collections.singleton(MockGreetingService.class);
    }


    @Override
    public String getConfigProfile() { 
        return "test";
    }

    @Override
    public List<TestResourceEntry> testResources() { 
        return Collections.singletonList(new TestResourceEntry(CustomWireMockServerManager.class));
    }
}

2.8 Mock 支持
引入Mockito

    <dependency>
      <groupId>org.mockito</groupId>
      <artifactId>mockito-all</artifactId>
      <version>1.10.19</version>
      <scope>test</scope>
    </dependency>

详情见 https://quarkus.io/guides/getting-started-testing#mock-support

2.9 Quarkus Test生命周期管理
Quarkus 提供了Test的生命周期管理类,@io.quarkus.test.common.QuarkusTestResource and io.quarkus.test.common.QuarkusTestResourceLifecycleManager. 在生命周期的回调中我们可以自定做一些操作。

3.如何使用Native单元测试

3.1 Native 单元测试的插件在上面已经加入并配置了

3.2 Native 单元测试类

import io.quarkus.test.junit.NativeImageTest;

@NativeImageTest 
public class NativeGreetingResourceIT extends GreetingResourceTest { 

    // Run the same tests

}

写起来非常简单,只是在JVM单元测试的基础上添加了@NativeImageTest注解,然后输入命令mvn verify -Pnative
在这里插入图片描述
注意:

  1. Native模式的单元测试默认走的Prod的配置,换成其他环境需要添加配置。方法一 在application.properties 中添加 quarkus.test.native-image-profile=test; 方法二 在测试命令后添加额外的命令 ./mvnw verify -Pnative -Dquarkus.test.native-image-profile=test

参考:https://quarkus.io/guides/building-native-image#testing-the-native-executable

总结

本章简单介绍了Quarkus的单元测试写法和如何构建本地可执行文件。

标签:04,单元测试,quarkus,io,test,import,public,Native
来源: https://blog.csdn.net/Tong_Rui/article/details/112728230

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有