IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> flyway+junit5做集成测试、单元测试 -> 正文阅读

[开发测试]flyway+junit5做集成测试、单元测试

适用场景

  • 功能开发完成后,后端开发人员进行代码自测
  • 代码重构后,集成测试

一些注解

  • 相关源码包: junit-jupiter-api
annotationsdescription
@Test用例
@ParameterizedTest参数化用例
@DisplayName标识用例的名称
@BeforeEach每个用例运行之前操作
@AfterEach每个用例运行之后操作
@BeforeAll本类的每个用例运行之前操作
@AfterAll本类的每个用例运行之前操作
@Nested标识为嵌套用例集合,该标识下,@BeforeAll与AfterAll,仅运行一次

Getting Started

场景一

  • 我要测试一个dao的sql是否写的正确
// 声明一个测试类
@SpringBootTest
@TestPropertySource("classpath:application-test.properties")
public class ExampleTestApplicationTests {
    @Autowired
    private UserInfoDao userInfoDao;

    // 声明一个测试函数
    @Test
    @DisplayName("用例: 用户更新")
    public void updateUserInfo() {
       UserInfo userInfo = UserInfo.builder().id(1L).userName("香槟").build();

       int result = userInfoDao.updateById(userInfo);

       Assertions.assertEquals(1,result);
    }
}

场景二

  • 测试接口异常
  • 通过Assertions.assertThrows(…)来断言,获取异常
  • JdbcTestUtil2是我针对JdbcTestUtil自己扩展的,用来准备数据、校验数据;这里准备数据与校验数据不直接用dao的原因(测试场景脱离业务代码,防止业务dao语句存在问题而影响测试结果)
    @Test
    public void registerDuplicate() {
        String prepareStatement = "INSERT INTO `user_info` (`id`, `user_name`) VALUES ('101', '香槟')";
        int prepareRows = JdbcTestUtil2.updateTable(jdbcTemplate, prepareStatement);
        Assertions.assertEquals(1, prepareRows);

        DataIntegrityViolationException exception = Assertions.assertThrows(DataIntegrityViolationException.class, () -> {
            userInfoService.register("香槟");
        });
        Throwable rootCause = Optional.ofNullable(ExceptionUtils.getRootCause(exception)).orElse(exception);
        Assertions.assertEquals("Duplicate entry '香槟' for key 'idx_uinfo_uname'", rootCause.getMessage());
    }

场景三

  • 测试下Controller接口
  • mockMvc是针对DispatcherServlet进行操作的,这就需要我们手动添加一些filters,这与interrupter不同

    @Autowired
    private WebApplicationContext webApplicationContext;

    public MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
            .addFilters(webApplicationContext.getBean(LoggerFilter.class))
            .build();

    @Test
    @DisplayName("注册成功")
    public void registerSuccess() throws Exception {
        MvcResult mvcResult = mockMvc.perform(
                        MockMvcRequestBuilders.get("/api/user/register")
                                .header("traceId", "123456")
                                .param("userName", "香槟"))
                .andExpect(MockMvcResultMatchers.status().is2xxSuccessful())
                .andReturn();
        String responseStr = mvcResult.getResponse().getContentAsString();
        BaseResult<Object> baseResult = objectMapper.readValue(responseStr, new TypeReference<BaseResult<Object>>() {
        });
        Assertions.assertEquals("success", baseResult.getCode());
    }

场景四

  • 接口入参条件不同,返回的结果是相同的,这时候写多个@Test函数,会造成代码重复性较高,也不利维护
  • 引入 @ParameterizedTest 参数化用例,该注解仅适用于同返回结果,Assertions…相同场景
    @ParameterizedTest
    @CsvSource({
            "'99999899',123456",
            "'99999899',dfadfdf",
            "'99999899',0000000",
    })
    public void userInfoModify(ArgumentsAccessor arguments) throws Exception {
        UserInfoModifyCommand build = UserInfoModifyCommand.builder()
                .oldPassword((String) arguments.get(0))
                .password((String) arguments.get(1))
                .build();

         // .......
    }

场景五

  • 用例归类;往往我们一个Controller/Bean的Method有多个场景需要测试,这时候如果在idea-structure里会看到几十个的method,非常不利于阅读
  • 引入 @Nested 、内部类
  @Nested
  @DisplayName("注册")
  class registerTest {

      @Test
      @DisplayName("注册成功")  
      public void registerSuccess(){
        // ......
      }

      @Test
      @DisplayName("重复注册")
      public void registerDuplicate(){
        // ......
      }
  } 

在这里插入图片描述

场景六

  • 每个测试用例的数据需要隔离; 所以我们可以在执行用例前,清一下表数据
  • show tables; => TableName.getAllTableNames()
    @BeforeEach
    public void cleanTable() {
        JdbcTestUtils.deleteFromTables(jdbcTemplate, TableName.getAllTableNames());
    }

场景七

  • 外部渠道、中间件由于存在不稳定性及依赖关系,我们需要对相关的API进行Mock
    mockito

    // mock下 userDao
    @MockBean
    private UserDao userDao;
 
    @Test
    @DisplayName("用例: 注册成功")
    public void registerSuccess() {
      
        Mockito.when(userDao.save(Mockito.any()))
                .thenReturn(UserInfo.builder().userName("小西").build());

        Mockito.when(userDao.save(Mockito.any())).thenThrow(new IllegalArgumentException("异常"));

        // ....... do something
    }

场景八

        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
        </dependency>

在这里插入图片描述

在这里插入图片描述

  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-08-31 15:45:12  更:2021-08-31 15:46:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/10 12:49:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码