zjs1224522500 / BlogIssue

This repo is created for collecting blogs with github issues written by Elvis.
0 stars 0 forks source link

教你写测试 #15

Open zjs1224522500 opened 5 years ago

zjs1224522500 commented 5 years ago
  • 测试开发
  • 结合实际例子介绍相关测试框架的使用
  • 结合实际开发环境中测试开发的场景
  • 结合部分产品发布的标准以及相关Security Scan
  • Findbugs, Fortify,SonarQube,PMD也会做简单介绍

  • 测试的重要性不做过多介绍。简单介绍一种 TDD(Test Driven Development)的模式。
  • TDD 旨在通过先编写相关的测试类和测试代码来驱动实际业务代码的开发。对于测试代码,业务代码更多的像是在承担一个黑盒的角色,而测试代码只需要关注输入输出,从逻辑意义上保证输入输出和我们预期的结果相对应则是业务代码需要去保证实现的。
  • TDD具体实现此处仅提供一种思路。测试类编写完成之后,使其一直运行在本地搭建的服务器上,编写相关业务代码完成后,通过在运行测试类的服务器上指定输入参数,通过测试代码的断言实时反应业务代码的正确性。

    单元测试 Unit Test (UT)

  • 应用场景:从代码层面去测试相关代码的正确性,是否符合预期的结果。此处不涉及和其他软件或者应用交互的过程,仅仅针对代码的逻辑处理。常常用于寻找程序中可能出现的异常以及代码逻辑的正确性。
  • 工具:JUnit4/5, Mockito, SpringTest, PowerMock

    JUnit4/5

  • JUnit5 User Guide
  • JUnit 主要是利用 Java 注解构建了一套单元测试的相关体系,同时提供了很多工具方便单元测试的编写。具体注解的使用,参照官方文档。

Mockito

service/dao unit test
@Before
public void setUp() throws Exception
{
    MockitoAnnotations.initMocks(this);
}
package tech.shunzi.testdev.service;

import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import tech.shunzi.testdev.model.User;
import tech.shunzi.testdev.model.dto.UserDto;
import tech.shunzi.testdev.repo.UserRepository;
import tech.shunzi.testdev.service.impl.UserServiceImpl;

import java.util.ArrayList;
import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

public class UserServiceImplTest {

    @Mock
    private UserRepository userRepository;

    @InjectMocks
    private UserServiceImpl userService;

    @Before
    public void setUp() throws Exception
    {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testGetAllUsers() {

        // Prepare data
        List<User> userList = new ArrayList<>();
        User user = new User();
        user.setDesc("DESC");
        user.setId(1111);
        user.setName("Shunzi");
        userList.add(user);

        List<UserDto> dtos = new ArrayList<>();
        UserDto dto = new UserDto();
        dto.setGroupNo(1);
        dto.setName(user.getName());
        dto.setId(user.getId());
        dto.setIntroduction("Hello, I am Shunzi. And my id is 1111. DESC");
        dtos.add(dto);

        // When
        when(userRepository.findAll()).thenReturn(userList);

        // Act
        List<UserDto> users = userService.findAllUsers();

        // Verify
        verify(userRepository).findAll();

        // Assert
        // override method equals() in UserDto class
        assertEquals(dtos, users);
    }

    @Test
    public void testGetUserById() {

        // prepare data
        int id = 1;
        User user = new User();
        user.setId(id);
        user.setName("shunzi");
        user.setDesc("desc");

        // when
        // anyInt() will match all params whose type is int
        when(userRepository.findById(anyInt())).thenReturn(user);

        // Act
        UserDto userDto = userService.findSingleUser(id);

        // verify
        verify(userRepository).findById(anyInt());

        // assert
        assertEquals(id, userDto.getId());
    }
}

SpringTest

mockMvc unit test
private HelloController helloController;
private MockMvc mockMvc;

@Before
public void setUp() throws Exception
{
    MockitoAnnotations.initMocks(this);
    //use controller to build mock mvc.
    mockMvc = MockMvcBuilders.standaloneSetup(helloController).build();
}

//PUT String responseData = mockMvc.perform(put(requestURI).param("tenantId", "dev")). andExpect(status().isOk()).andReturn().getResponse().getContentAsString();

//DELETE String data = mockMvc .perform(delete(requestURI).contentType(MediaType.APPLICATION_JSON).content("the params with json format") .andExpect(status().isOk()).andReturn().getResponse().getContentAsString();


- Example:

```Java
package tech.shunzi.testdev.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import tech.shunzi.testdev.model.dto.UserDto;
import tech.shunzi.testdev.service.impl.UserServiceImpl;

import java.util.ArrayList;
import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

public class UserControllerTest {

    private MockMvc mockMvc;

    @Mock
    private UserServiceImpl userService;

    @InjectMocks
    private UserController userController;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
    }

    @Test
    public void testFindAll() throws Exception {
        // Prepare data
        String requestUrl = "/users";
        List<UserDto> userDtoList = new ArrayList<>();
        UserDto userDto = new UserDto();
        userDto.setName("shunzi");
        userDtoList.add(userDto);

        ObjectMapper mapper = new ObjectMapper();
        String expectedValue = mapper.writeValueAsString(userDtoList);

        // When
        when(userService.findAllUsers()).thenReturn(userDtoList);

        // Act
        String responseStr = mockMvc.perform(get(requestUrl).accept(MediaType.APPLICATION_JSON_UTF8)).andExpect(status().isOk()).andReturn().getResponse().getContentAsString();

        // Verify
        verify(userService).findAllUsers();

        // Assert
        assertEquals(expectedValue, responseStr);
    }
}

PowerMock

@PrepareForTest(ObjectFieldEmptyUtil.class)
@RunWith(PowerMockRunner.class)
public class UserServiceImplTest {

    @Mock
    private UserRepository userRepository;

    @InjectMocks
    private UserServiceImpl userService;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
    }

    @Test(expected = RuntimeException.class)
    public void testSaveUser() {

        // Prepare data
        UserDto user = new UserDto();
        user.setName("shunzi");
        user.setIntroduction("intro");
        User model = new User();
        model.setDesc("intro");
        model.setName("shunzi");
        model.setId(1);
        List<String> stringList = new ArrayList<>();
        stringList.add("name");

        PowerMockito.mockStatic(ObjectFieldEmptyUtil.class);
        PowerMockito.when(ObjectFieldEmptyUtil.findEmptyFields(anyObject(), anyList())).thenReturn(stringList);

        // Act
        UserDto userDto = userService.saveUser(user);

        // Assert
        assertEquals("shunzi", userDto.getName());
    }
}
Caution:

集成测试 Integration Test (IT)

Spring Integration Test

Prepare:

代码实例:

package tech.shunzi.testdev.integration.test;

import org.junit.Before;
import org.junit.Rule;
import org.junit.contrib.java.lang.system.EnvironmentVariables;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.MOCK)
@AutoConfigureMockMvc
@ActiveProfiles("test")
public abstract class BaseIntegrationTest {

    @Autowired
    protected MockMvc mockMvc;

    @Rule
    public final EnvironmentVariables environmentVariables = new EnvironmentVariables();

    @Before
    public void setUpEnv()
    {
        environmentVariables.set("key","value");
    }
}
package tech.shunzi.testdev.integration.test;

import org.junit.Test;
import org.springframework.http.MediaType;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

public class UserControllerIntTest extends BaseIntegrationTest {

    @Test
    public void testFindAll() throws Exception {
        // Prepare data
        String requestUrl = "/users";

        // Act
        String responseStr = mockMvc.perform(get(requestUrl).accept(MediaType.APPLICATION_JSON_UTF8)).andExpect(status().isOk()).andReturn().getResponse().getContentAsString();

        // Advise to use assert, sout in here is just to show query result from DB
        System.out.println(responseStr);
    }
}
package tech.shunzi.testdev.integration.test;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import tech.shunzi.testdev.service.UserService;

@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("test")
public class UserServiceTest {

    @Autowired
    private UserService userService;

    @Test
    public void testFindAll() {
        System.out.println(userService.findAllUsers());
    }
}

系统测试 System Test (ST)

How to use JMeter

Example Code

Head First

Step 1. Create Thread Group

image

Step 2. Define some common variables
Step 3. New Http Request
Step 4. New Asserters.(JSON Assertion, Response Assertion etc.)
Step 5. Processor (Pre/Post)
Step 6. Result Tree

自动化测试(Auto UI Test)