TIL 20230805
이번 주 목표
CI / CD 예습
오늘 목표
test code 가 있는 CI / CD 만들기
오늘 한 것
1. Thunder Client에서 localhost 또는 127.0.0.1로 API 전송 시 무한 로딩(Processing)
문제
오늘 아침부터 Thunder Client API가 작동하지 않음.
시도
Postman 으로 시도 할 경우 정상작동하여 나의 이슈가 아닌 Thunder Client의 이슈일 수 있다고 판단
인터넷에 Thunder Client 관련 찾아 봄.
찾은 결과 :
thunder-client-support 공식 레포지토리 이슈
https://github.com/rangav/thunder-client-support/issues/1251#issuecomment-1666113888
해결
결론 : 최신 VScode update를 하게 되면 발생하게 되는 Thunder Client 이슈
- VScode July 2023 (version 1.81) : 127.0.0.1 대신 0.0.0.0 을 입력하여 API 호출
- VScode June 2023 (version 1.80) 으로 돌아가기
알게된 것
가끔 휴먼 에러가 아닐 수도 있다.
문제를 정확히 판별하기 위해 여러가지 방법을 사용해 보고 결과를 도출하자.
2. CI CD - 공부 중
2-1. 테스트 코드 작성
//__test__/integration/items.integration.spec.js
import supertest from 'supertest';
import { ExpressApp } from '../../app.js';
import sequelize from '../../db/sequelize.js';
const expressApp = new ExpressApp();
const app = expressApp.app;
beforeAll(async () => {
if (process.env.NODE_ENV === 'test') await sequelize.sync();
else throw new Error('NODE_ENV가 test 환경으로 설정되어 있지 않습니다.');
});
describe('Layered Architecture Pattern, Posts Domain Integration Test', () => {
test('GET /api/items API (getItems) Integration Test Success Case, Not Found Itmes Data', async () => {
const response = await supertest(app)
.get(`/api/items`)
.query({ category: 'all' })
.send({});
expect(response.body).toEqual({
message: '전체 상품이 조회되었습니다.',
list: [],
});
});
test('POST /api/options API (createOptions) Integration Test Success Case', async () => {
const createOptionRequestBodyParams = {
extra_price: 200,
shot_price: 0,
hot: false,
};
const response = await supertest(app)
.post(`/api/options`)
.query({})
.send(createOptionRequestBodyParams);
expect(response.status).toEqual(200);
expect(response.body).toMatchObject({
message: '옵션 추가에 성공하였습니다.',
});
});
test('POST /api/items API (createItem) Integration Test Success Case', async () => {
const createItemRequestBodyParams = {
name: '치즈케이크',
price: 2000,
type: 'food',
option_id: 1,
};
const response = await supertest(app)
.post(`/api/items`)
.query({})
.send(createItemRequestBodyParams);
expect(response.status).toEqual(200);
expect(response.body).toMatchObject({
message: '상품 추가에 성공하였습니다.',
});
});
test('POST /api/posts API (createPost) Integration Test Error Case, Invalid Params Error', async () => {
const createItemRequestBodyParamsByInvalidParamsError = {
name: '아메리카노',
price: 1000,
type: 'coffee',
option_id: 200,
};
const response = await supertest(app)
.post(`/api/items`)
.query({})
.send(createItemRequestBodyParamsByInvalidParamsError);
expect(response.body).toMatchObject({
message: '정확한 옵션을 입력해 주세요.',
});
});
test('GET /api/items API (getItems) Integration Test Success Case, is Exist Posts Data', async () => {
const response = await supertest(app)
.get(`/api/items`)
.query({ category: 'all' })
.send({});
expect(response.body).toMatchObject({
message: '전체 상품이 조회되었습니다.',
list: [
{
id: 1,
name: '치즈케이크',
option_id: 1,
price: 2000,
type: 'FOOD',
amount: 0,
createdAt: expect.anything(),
updatedAt: expect.anything(),
option: {
id: 1,
extra_price: 200,
shot_price: 0,
hot: 0,
createdAt: expect.anything(),
updatedAt: expect.anything(),
},
},
],
});
});
});
afterAll(async () => {
if (process.env.NODE_ENV === 'test') await sequelize.sync({ force: true });
else throw new Error('NODE_ENV가 test 환경으로 설정되어 있지 않습니다.');
});
2-2. yml 파일 작성
// github/workflows/test.yml
name: Node.js CI
on:
push:
branches: ['master']
pull_request:
branches: ['master']
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
env:
MYSQL_USERNAME: ${{secrets.MYSQL_USERNAME}}
MYSQL_PASSWORD: ${{secrets.MYSQL_PASSWORD}}
MYSQL_DATABASE: ${{secrets.MYSQL_DATABASE}}
TEST_DATABASE: ${{secrets.TEST_DATABASE}}
MYSQL_HOST: ${{secrets.MYSQL_HOST}}
MYSQL_PORT: ${{secrets.MYSQL_PORT}}
HOST: ${{secrets.HOST}}
PORT: ${{secrets.PORT}}
- run: echo "MYSQL_USERNAME=$MYSQL_USERNAME" >> .env
echo "MYSQL_PASSWORD=$MYSQL_PASSWORD" >> .env
echo "MYSQL_DATABASE=$MYSQL_DATABASE" >> .env
echo "TEST_DATABASE=$TEST_DATABASE" >> .env
echo "MYSQL_HOST=$MYSQL_HOST" >> .env
echo "MYSQL_PORT=$MYSQL_PORT" >> .env
echo "HOST=$HOST" >> .env
echo "PORT=$PORT" >> .env
npm ci
npm test
2-3. github actions 및 secrets 사용 설정
2-4. test 통과
문제
package-lock.json 파일이 없으면 실행이 안 되는 것 같다.
시도
package-lock.json 파일을 생성.
해결
해결함.
알게 된 점
GitHub Actions에서는 캐싱(caching)을 지원하기 때문에 CI 서버에서 npm 패키지를 설치할 때 성능을 향상 시킬 수 있다.
참고 자료 : https://www.daleseo.com/github-actions-setup-node/
정리
가끔 휴먼 에러가 아닐 수도 있다.
문제를 정확히 판별하기 위해 여러가지 방법을 사용해 보고 결과를 도출하자.
체크리스트
[ X ] 코딩 시 복사 + 붙여넣기를 하지 않았는가?
[ ? ] 오늘을 평가하였을 때 주니어 개발자가 될 수 있겠는가?
KPT
Keep
열심히 나아가는 점
Problem
많은 걱정과 시간 허비
Try
문제가 생기기 전에 걱정과 생각 하지 않기
광복절까지 최종 프로젝트 생각 하지 않기
소감
30번 이상 status check가 통과되지 않았지만 재밌었다.