2주 챌린지 - 1. smoke test

yy·2023년 11월 22일

개발일지

목록 보기
39/122

프론트, 백엔드 코드는 대충 짰다.


1. smoke Test : 테스트 잘 되는지 확인용

  • smoke Test : 소프트웨어 개발 또는 시스템 테스트에서 기본 기능이 제대로 작동하는지를 확인하기 위한 간단한 테스트
  • 최소한의 부하로 시나리오 및 시스템에 오류가 없는지 확인
  • 사용자 1명일 경우
  1. 회원가입 api
  • duration: 30
  • arrivalRate: 1
config:
  environments:
    local:
      target: 'http://localhost:3334'
      phases:
        - duration: 30
          arrivalRate: 1
          name: Warm up
      defaults:
        User-Agent: 'Artiilery'
      payload:
        path: 'users.csv'
        fields:
          - 'username'
          - 'password'
scenarios:
  - name: '회원가입'
    flow:
      - post:
          url: '/api/sign-up'
          json:
            username: '{{username}}'
            password: '{{password}}'
           ```

..왜 400이 생기는가. 도랏니? 왜 400이 뜨고 난리니?


  1. 로그인 api (smoke test 성공)
  • duration: 30
  • arrivalRate: 1
config:
  environments:
    local:
      target: 'http://localhost:3334'
      phases:
        - duration: 30
          arrivalRate: 1
          name: Warm up
      defaults:
        User-Agent: 'Artiilery'
      payload:
        path: 'users.csv'
        fields:
          - 'username'
          - 'password'
scenarios:
  - name: '로그인'
    flow:
      - post:
          url: '/api/sign-in'
          json:
            username: '{{username}}'
            password: '{{password}}'```


  1. 공연 목록 조회 api (smoke test 성공)
  • duration: 30
  • arrivalRate: 1
config:
  environments:
    local:
      target: 'http://localhost:3334'
      phases:
        - duration: 30
          arrivalRate: 1
          name: Warm up
      defaults:
        User-Agent: 'Artiilery'
      payload:
        path: 'users.csv'
        fields:
          - 'username'
          - 'password'
scenarios:
  - name: '공연 목록 조회'
    flow:
      - get:
          url: '/api/reservation'```


  1. 공연 상세 조회 api (smoke test 성공)
  • duration: 30
  • arrivalRate: 1
config:
  environments:
    local:
      target: 'http://localhost:3334'
      phases:
        - duration: 30
          arrivalRate: 1
          name: Warm up
      defaults:
        User-Agent: 'Artillery'
      payload:
        path: 'users.csv'
        fields:
          - 'username'
          - 'password'
scenarios:
  - name: '공연 상세 조회'
    flow:
      - get:
          url: '/api/reservation/1'
      - get:
          url: '/api/reservation/2'
      - get:
          url: '/api/reservation/3'


  1. 공연 예매 api
  • duration: 30
  • arrivalRate: 1
  • 한 명의 사용자를 기준으로 예매 시도
config:
  environments:
    local:
      target: 'http://localhost:3334'
      phases:
        - duration: 30
          arrivalRate: 1
          name: Warm up
      defaults:
        User-Agent: 'Artillery'
      payload:
        path: 'users.csv'
        fields:
          - 'username'
          - 'password'
scenarios:
  - name: '공연 예매'
    flow:
      # 공연 예약
      - post:
          url: '/api/reservation/2'
          headers:
            authorization: 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjIxLCJpYXQiOjE3MDA2MTMxNzJ9.r5_zty3Q_6W2Q0bKHWU9mxdE6suy4NNQyAgur8xLVKw'

- 예매전예매전예매후
예매후
여기서 http.codes.400이 뜨는 이유는 사용자의 credit은 300,000원이 있고, 공연의 price가 90,000원이기때문에 3번밖에 결제가 안되기때문임.

그렇다면 reservation 테이블에도 3개만 들어가있어야 말이된다.
... 말이 안된다.

/** 공연 예매 **/
router.post('/reservation/:showId', authMiddleware, async (req, res, next) => {
  let transaction;
  try {
    const { showId } = req.params;
    const { userId } = req.user;

    const show = await prisma.shows.findFirst({
      where: { showId: +showId },
    });

    if (!show) {
      return res.status(400).json({ message: '찾는 공연이 없습니다.' });
    }

    const user = await prisma.users.findFirst({
      where: { userId: +userId },
    });

    transaction = await prisma.$transaction(async (tx) => {
      await tx.reservation.create({
        data: { UserId: user.userId, ShowId: show.showId },
      });

      //예매한다면, show의 quantity 하나 줄이기
      if (show.quantity > 0) {
        await tx.shows.update({
          where: { showId: +showId },
          data: { quantity: --show.quantity },
        });
      } else {
        return res.status(400).json({ message: '예매 수량이 부족합니다.' });
      }
      //계속해서 user의 credit도 줄어들기
      if (user.credit > show.price) {
        await tx.users.update({
          where: { userId: +userId },
          data: { credit: user.credit - show.price },
        });
      } else {
        return res.status(400).json({ message: '보유한 credit이 부족합니다.' });
      }
      return res.status(200).json({ message: '좌석 예매가 완료되었습니다.' });
    });
  } catch (error) {
    console.log(error);

    if (transaction) {
      await prisma.$executeRaw`ROLLBACK`;
    }
    next(error);
  }
});

위의 코드에서 create되는 코드를 수정해줬다. 트랜잭션 안에 있어서 상관이 없다고 생각했는데 우선 shows, users의 내용을 업데이트를 한 후에 create해주는게 맞았나보다. 아래와 같이 코드를 수정후에 credit이 부족할때 reservation에 데이터가 입력이 되지않는다.

/** 공연 예매 **/
router.post('/reservation/:showId', authMiddleware, async (req, res, next) => {
  let transaction;
  try {
    const { showId } = req.params;
    const { userId } = req.user;

    const show = await prisma.shows.findFirst({
      where: { showId: +showId },
    });

    if (!show) {
      return res.status(400).json({ message: '찾는 공연이 없습니다.' });
    }

    const user = await prisma.users.findFirst({
      where: { userId: +userId },
    });

    transaction = await prisma.$transaction(async (tx) => {
      //예매한다면, show의 quantity 하나 줄이기
      if (show.quantity > 0) {
        await tx.shows.update({
          where: { showId: +showId },
          data: { quantity: --show.quantity },
        });
      } else {
        return res.status(400).json({ message: '예매 수량이 부족합니다.' });
      }
      //계속해서 user의 credit도 줄어들기
      if (user.credit > show.price) {
        await tx.users.update({
          where: { userId: +userId },
          data: { credit: user.credit - show.price },
        });
      } else {
        return res.status(400).json({ message: '보유한 credit이 부족합니다.' });
      }

      await tx.reservation.create({
        data: { UserId: user.userId, ShowId: show.showId },
      });

      return res.status(200).json({ message: '좌석 예매가 완료되었습니다.' });
    });
  } catch (error) {
    console.log(error);

    if (transaction) {
      await prisma.$executeRaw`ROLLBACK`;
    }
    next(error);
  }
});
  • duration: 1
  • arrivalRate: 5
    으로 변경하여 다시 테스트 해봤다. 5번의 시도에서 3번(사용자의 credit으로 공연을 살 수 있는 횟수는 3번(270,000원)이고, 그 후에는 credit이 없다고 하여 2번이 실패된게 맞다.

smoke test 끝~!
이제 진짜 load test를 해보자.

profile
시간이 걸릴 뿐 내가 못할 건 없다.

0개의 댓글