GithubHelp home page GithubHelp logo

meethere-backend's Introduction

Hi there 👋

Typing SVG

Anurag's GitHub stats

🤔 Vistor Counter

Visitor Count

meethere-backend's People

Stargazers

 avatar

Watchers

 avatar  avatar

meethere-backend's Issues

Defect: 对于前端上传的 Base64 图片数据处理

我们的系统允许管理员在后台人工添加新的场馆,同时上传场馆配图。由于前段采用了上传转换后的 Base64 数据,因此后端必须对 Base64 数据进行处理。搜索资料后,后端决定使用 Java8 自带的 Base64 工具库,只需要 import java.util.Base64; 即可。但是当我们尝试:

byte[] decodedImg = Base64.getDecoder().decode(encodedImg.getBytes(StandardCharsets.UTF_8));

时,后端提示错误,无法解析。

Defect: 代码风格和规范问题

代码规范问题

通过P3C对代码风格和规约进行静态分析检查,发现了5个critical级别的错误:

image-20200102204756618

必须修改以上的critical错误

Defect: 高并发场景下存在严重的性能缺陷

在经过性能测试后,我们发现系统在高并发场景下存在严重的性能缺陷。如图所示,是从测试结果中所统计得出的平均响应时间:

Average Response Time (ms)

           
场景 1 10 20 50 100 200
登录 177.68 997.56 1904.45 4904.39 9917.64 18165.41
获取新闻 160.81 296.91 498.67 1280.95 2724.41 9354.38
浏览场馆/浏览评论 88.42 289.26 497.21 1325.76 2996.91 5592.29
浏览场馆/预定场馆 139.90 276.63 498.81 1334.04 2528.29 5927.28
个人信息管理 182.55 946.45 1802.45 4577.84 9381.85 19768.66
登录->浏览新闻->浏览场馆->预定场馆->修改个人信息 101.18 764.15 1497.49 3840.91 9191.59 12078.53
登录->浏览场馆->预定场馆 216.26 485.83 915.81 2326.19 5609.73 9999.62
登录->浏览新闻->修改密码->修改个人信息 216.26 485.83 915.81 2326.19 5609.73 9999.62
登录->浏览新闻->浏览场馆->发布评论 66.46 525.51 1342.56 3929.27 8295.51 12888.50

Defect:场馆空闲时间返回结果出错

空闲时间统计问题

在我们的需求中,管理员需要能够对场馆进行管理,可以查看每个场馆的空闲时间。但在测试管理员获取场馆空闲时间的方法时,发现了bug:

如果某个场馆被预约的时间为[8:00 - 9:00, 10:00-11:00...]这样连续的时间段,本应该空闲时间包含时间段[9:00 - 10:00],然而后端返回的结果却不包含该时间段。导致该问题的原因应该是后端获取空闲时间的函数实现出现了问题。

于是重新review了后端代码,选取了新的实现方式,修改了该缺陷:

public List<String> getSpareTimeFromBookingList(List<Booking> bookingList,
                                                LocalDate date) {
  DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
  List<String> spareTime = new ArrayList<>();

  // timeSlotTable为一个flag数组,表示该时间槽是否被预约,每小时算一个时间槽
  // e.g. timeSlotTable[0] -> 8:00-9:00,共12个
  boolean[] timeSlotTable = new boolean[12];
  for (boolean used : timeSlotTable) {
    used = false;
  }

  // 只考虑一天内的预约
  for (Booking booking : bookingList) {
    LocalDateTime startTime = booking.getStartTime();
    if (date.isEqual(startTime.toLocalDate())) {
      int start = startTime.getHour();
      int end = booking.getEndTime().getHour();
      for (int i = start; i < end; i++) {
        timeSlotTable[i - 8] = true;
      }
    }
  }

  int startIndex = (timeSlotTable[0]) ? 0 : -1;
  int endIndex = 0;
  for (int i = 1; i <= 11; i++) {
    // 若全部空闲则循环没有操作
    if (timeSlotTable[i]) {
      if (!timeSlotTable[i - 1]) {
        endIndex = i;
        StringBuilder builder = new StringBuilder();
        LocalTime startTime = LocalTime.of(startIndex + 9, 0);
        LocalTime endTime = LocalTime.of(endIndex + 8, 0);
        builder.append(formatter.format(startTime))
          .append("-")
          .append(formatter.format(endTime));
        spareTime.add(builder.toString());
      }
      if (i <= 10 && !timeSlotTable[i + 1]) {
        startIndex = i;
      }
    }
  }
  if (!timeSlotTable[11]) {
    StringBuilder builder = new StringBuilder();
    LocalTime startTime = LocalTime.of(startIndex + 9, 0);
    builder.append(formatter.format(startTime))
      .append("-")
      .append("20:00");
    spareTime.add(builder.toString());
  }
  return spareTime;
}

Defect: 手机号格式校验

手机号格式问题

我们规定允许用户的手机号为空,且用户手机号默认为空。但是在进行系统测试时,发现了一个问题。

我们在前后端分别为手机号格式进行了校验,必须满足**大陆的手机号格式。我们通过正则表达式来匹配手机号的格式,若匹配则允许进行操作。

但是,当前端将手机号设置为空时,后端不允许进行相应的操作。查看后端报错信息后,我们发现,后端在进行

image-20200102201033082

参数校验时忽略了手机号为空的情况,而是仅仅考虑到了手机号不为空时的匹配模式:

@Pattern(regexp = "^(1([34578])\\d{9}$", message = "手机号码格式错误")
private String phoneNumber;

这里我们修改了手机号的正则表达式,使之在进行参数校验时允许手机号为空。

@Pattern(regexp = "(^$|^(1([34578])\\d{9}))$", message = "手机号码格式错误")
private String phoneNumber;

通过这样的修改,修复了手机号校验的问题。

删除数据的测试问题

删除数据的测试问题

在进行集成测试时,我们可能需要对数据库进行删除一些数据的测试,开始时,我们写的测试开始并没有事先向数据库中添加数据,导致我们的测试用例只能被执行一次,无法多次执行。

之后我们想到可以每次执行前手动向数据库中添加数据,但是这仍然很复杂,但是使用系统已经实现的接口无法很好的添加数据,例如删除订单的集成测试,无法通过已经写好的系统功能添加好合适的订单,然后给测试用例获取删除。

我们的最终解决办法时在 Dao 层添加一些专门为测试使用的接口,来实现对数据库插入一些合适的数据,同时可以返回一些测试用例需要的数据,来供测试用例使用,实现测试用例;这样我们的测试用例就会具有了可重复执行的能力。

Dao 层部分接口代码:

@Delete("DELETE a FROM booking a, (SELECT MAX(booking_id) AS max_id FROM booking) b WHERE booking_id = b.max_id")
int deleteLatestBooking();

@Select("SELECT * FROM booking WHERE booking_id = (SELECT MAX(booking_id) FROM booking)")
Booking getLatestBooking();

@Select("SELECT COUNT(*) FROM booking")
int getAllBookingCount();

其中删除订单的集成测试代码如下:

@Test
@DisplayName("用户删除订单时,若HTTP头部携带的TOKEN与customerId匹配,返回正常结果")
void shouldDeleteBookingByCustomerWithCorrectToken() {
     Booking booking = Booking.builder().customerId(507).stadiumId(1).startTime(LocalDateTime.now()).endTime(LocalDateTime.now()).paid(false).priceSum(BigDecimal.valueOf(0)).build();
     bookingDao.addNewBooking(booking);
     Integer bookingId = booking.getBookingId();
     BookingRequest bookingRequest = BookingRequest.builder().customerId(507).bookingId(bookingId).build();
     HttpHeaders httpHeaders = new HttpHeaders();
     httpHeaders.set("TOKEN", "eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI1MDciLCJpYXQiOjE1Nzc0NTQ0NDMsImV4cCI6MTU3OTUyODA0M30.iT_dyXZ13mqjND1XfDNqvELEWwvgusJwp6mHUmLKNmo");
     HttpEntity<BookingRequest> entity = new HttpEntity<>(bookingRequest, httpHeaders);

     ResponseEntity<ResultEntity> response = testRestTemplate.postForEntity(BASE_URL + "/delete-by-customer", entity, ResultEntity.class);
     ResultEntity result = response.getBody();

     assertAll(
             () -> assertEquals(200, response.getStatusCodeValue()),
             () -> assertEquals(0, result.getCode()),
             () -> assertEquals("success", result.getMessage())
     );
 }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.