TIL] 테스트 코드

Song-Minhyung·2023년 7월 19일

TIL

목록 보기
7/12

테스트 코드?

말 그대로 코드를 테스트 할 수 있는 코드입니다.
테스트 코드를 작성하는 방법은 정말 많고 방법도 정말 많습니다.
그 중 대표적인 테스트는 단위 테스트, 통합 테스트, 인수 테스트 정도가 있을수 있겠습니다.

테스트 코드를 작성할 때 장점은 코드를 안정적으로 짤 수 있습니다. 그래서 리팩토링을 할 때도 정말 아무렇게나 마아아악 하다가 안되면 되돌리고 하는 방식이 가능합니다.

그런데 단점은 그냥 코드만 작성하는 시간에 비해 시간이 더 소요됩니다. 전에 과제를 제출하는 코테를 봤을 때 테스트 코드를 작성한적이 있었는데 요구사항대로 테스트 코드를 작성하다가 시간이 모잘라서 과제를 제출 못했던 기억이 있습니다. 아마 그냥 코드만 짯다면 제출할 수 있었을것 같습니다.

이렇게 장단점이 뚜렷하지만 정말 간단한 코드를 짜는게 아니면 쓰는 방향으로 가는게 맞는것같습니다. 전에 테스트 코드에 대해 찾아보다 정말 감명깊게 들은 말이 있습니다.

테스트 코드 작성하는건 미래의 고통을 미리 당겨오는 겁니다.

단위테스트

테스트 가능한 가장 작은 단위의 프로그램을 테스트 한다.

단위테스트는 정말 작은 단위로 테스트 하는것을 말합니다.
그래서 테스트 코드의 실행 시간이 정말 짧고 하나의 모듈만 독립적으로 테스트 하기때문에 해당 모듈에 문제가 있다는걸 바로 알아챌 수있습니다. 그래서 이때는 어떤 버튼을 눌렀을때 뭐가 실행된다. 로그인을 하면 창이 나온다 정도의 간단한 테스트 정도만 실시하게 됩니다.

통합테스트

단위테스트한 모듈을 모아서 작동하는지 테스트한다.

통합테스트는 단위테스트를 진행하며 모듈을 통합하는 과정에서 진행하는 조금 더 큰 단위의 테스트 입니다.
프로그램은 하나의 모듈로만 동작할 수 없기에 설제로 모듈들을 서로 연결했을 때 문제가 없는지 여기서 확인합니다. 예를들면 프론트엔드에 API를 연결해서 실제로 작동이 되는지 등의 테스트를 할 수 있습니다.

그런데 여기서 명심해야 할 점은 통합 테스트가 발견하기 어려운 버그를 찾을수는 있지만 버그를 찾을수 있을 뿐이지 프로그램이 완벽하게 작동할 수 있다는걸 증명할수는 없습니다. 그리고 신뢰성이 떨어질 수 있고 단위테스트와 달리 어디에서 문제가 발생했는지 확인하기 어려워 유지보수 하기 힘들다는 점도 있습니다.

인수테스트

인수 전 요구사항대로 작동하는지 시나리오를 만들고 테스트를 진행한다.

마지막으로 인수테스트는 프로그램에서 문제를 찾는 앞의 두 테스트와는 다르게 실제로 프로그램을 실행하는 사람 입장에서 테스트를 진행합니다. 테스트를 진행하기 앞서 시나리오를 만들고 이에 맞춰 테스트 코드를 작성하게 됩니다. 즉, 소프트웨어를 인수하기 전에 요구사항대로 프로그램이 제대로 작성됐는지 확인하기 위해 진행하는 테스트입니다.

테스트 방법은 이 외에도 더 다양하게 존재하지만 상황에 맞는 테스트 방법을 적절하게 골라 테스트 하는것이 중요하다.

Jest

jest는 nodejs 테스트 하는 테스팅 프레임워크입니다. 비슷한 프레임워크로는 Mocha가 있습니다. 그런데 러닝커브가 높다고 해서 이번에는 다시한번 복습할겸 jest로 테스트 코드를 작성했습니다.

간단한 테스트코드

describe("계산기 테스트", () => {
  it("덧셈 1 + 1", () => {
    const calc = new Calculator();
    expect(calc.add(1,1)).toBe(2);
  });
});

위는 한눈에 어떤 동작을 하는 코드인지 바로 알수있을정도로 간단한 코드입니다.
1 + 1이 2가 됐는지 확인하는 테스트 코드인데요

만약 add 메소드가 인자 두개를 더하는 방식으로 짜여있지 않고 곱하는 방식으로 짜여있다면 테스트는 실패하게 될겁니다.

jest.fn()

해당 함수를 mock 함수로 대체함니다. 원래 구현에 접근이 불가능 합니다.

describe("계산기 목업 테스트", () => {
  it("덧셈 1 + 1", () => {
    Calculator.add = jest.fn();
    Calculator.add(1,1);
    expect(Calculator.add).toBeCalledWith(1,1);
  });
});

jest.mock

모둘의 함수를 모두 대체합니다. 하지만 원래 구현에 접근이 불가능합니다.

jest.mock(Calculator);
describe("계산기 목업 테스트", () => {
  it("덧셈 1 + 1", () => {
    Calculator.add(1,1);
    expect(Calculator.add).toBeCalledWith(1,1);
  });
});

jest.spyOn

함수가 호출됐는지 여부를 파악할 때 사용합니다.


describe("계산기 목업 테스트", () => {
  it("덧셈 1 + 1", () => {
    Calculator.add(1,1);
    const spyAdd = jest.mock(Calculator, "add");
    expect(spyAdd).toBeCalledWith(1,1);
	expect(spyAdd).toBeCalledTimes(1);
  });
});

배운점/실수한점

  • 월요일
    • 상속관계를 표현하는데 abstract class를 사용하자.
    • 클래스의 구조를 설명할 때 interface를 사용하자
    • 보드 등을 탐색할 때 중간에 break하지 않도록 다시 체크해보자.
    • 클래스 설계에 조금 더 신경쓰자
  • 화요일
    • console.table을 사용하면 로그를 더 이쁘게 찍을 수 있다.
    • 불변성(immutable)을 지키려면 다른 메모리에 할당해주면 된다.
    • 참조 투명성은 입력에 대해서만 계산이 이뤄져야하고 외부에는 영향을 주지 않는걸 말한다.
  • 수요일
    • 요구사항이 복잡하고 많으면 테스트 코드를 작성해보자!
profile
기록하는 블로그

0개의 댓글