Post

UnitTest,Pytest

UnitTest,Pytest

## 🎯 정리: 언제 unittest vs pytest?

언제 사용하면 좋을까?unittestpytest
내장 모듈만 사용하고 싶을 때❌ (설치 필요)
단순하고 빠른 테스트가 필요할 때
클래스 기반의 체계적인 테스트
간결한 코드 & 가독성이 중요할 때
출력 결과가 보기 쉬운 게 좋을 때

Python 가상환경 만들기!!!

프로젝트 폴더에서 가상 환경 생성 순서!!

1
2
python -m venv venv   # 가상환경을 만들기 위한 폴더가 만들어지뮤..
venv\Scripts\activate  # 이러면 이제 가상환경이 켜지는것임
1
(venv) PS C:\Users\user\Desktop\QA공부\테스트용  # (venv) 가 붙어있음

심플하다


unittest&pytest

우선 환경설정 부터 셋팅해 줘야 함

1
pip install pytest      # pytest 설치함

프로젝트 폴더 구조!!

project-folder/
└── tests/
  └── test_sample.py

이런식으로 ‘파일명:test_ @#$@#$.py’ 해야 하고, 함수들은 ‘test_ @#$@#$’로 시작해야 인식 된다

테스트 실행 명령

1
2
python -m unittest discover      # unittest 임 
pytest tests/                    # pytest 임  

unittest 실행 흐름 (클래스 기반임)

  • 테스트 코드 작성(TestCase 상속 클래스 작성)
  • unittest 몯듈로 테스트 실행 (python -m unittest discover)
  • 결과 출력(성공 or 실패 표시, 에러 메시지 확인)
1
2
3
4
5
6
7
8
9
10
11
import unittest                      # 파이썬 내장 테스트 프레임워크임  
                                     # 기본적으로 제공되는 단위 테스트 모듈임  
def add(a, b):                       # 테스트 할 함수를 정의한 것임  
    return a + b

class TestSample(unittest.TestCase): # unittest.TestCase를 상속받아 테스트 클래스 만듬  
    def test_add(self):              # 테스트 함수 작성함    
        self.assertEqual(add(2,3),5) # test_add() 함수는 add(2, 3)의 결과가 5인지 검사함
                                     # assertEqual(add(2,3),5)이므로 add(2, 3)이 5가 맞음 통과  
if __name__ == '__main__':           # 테스트 실행, 파일을 직접 실행했을 때만 테스트가 동작하도록  
    unittest.main()

테스트 실행 결과

1
2
3
4
5
6
python -m unitteest discover
.                                # 테스트 하나가 성공 했다는 뜻임  
----------------------------------------------------------------------
Ran 1 test in 0.001s             # 1개의 테스트가 실행 되었다는 뜻임

OK                               # 모든 테스트가 통과함  

테스트 실행

1
2
3
4
5
6
7
8
9
10
11
12
13
import unittest

class TestMathOperations(unittest.TestCase):   # unittest.TestCase를 상속해서 테스트 클래스를 만든다  
                                               # TestMathOperations 클래스 안에서 여러 개의 테스트 메서드를 작성가능  
    def setUp(self):                           # 각 테스트 실행 전 실행되는 메소드  
        self.a = 2                             # self a,b 는 각 테스트 마다 초기화된 값으로 설정 가능함
        self.b = 3
# 여기서 부터 테스트 함수임
    def test_add(self):                          
        self.assertEqual(self.a + self.b, 5)   # self.a + self.b가 기대한 값(5)과 같은지 확인  

    def tearDown(self):                        # 테스트 끝난 뒤에 실행되는 메소드
        pass
1
2
3
4
5
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

TestCase 클래스 주요 메서드

  • setUp() : 테스트 전 공통 준비 작업
  • tearDown() : 테스트 후 정리 작업 (테스트 끝난뒤 실행됨)
  • assertEqual() : 값이 같은지 확인함 (assertEqual(a,b) 이런식으로 씀)
  • assertTrue() : 조건이 참인지 확인 (assertTrue(x >0) 이런식으로 씀)
  • assertIn() : 값이 리스트나 문자열에 포함되는지 확인 (assertIn(“a”,”abc”) 이런식으로 씀)
  • assertRaises() : 특정 에러 발생 여부를 확인
  • assertIsNone() : 값이 None인지 확인 (assertIsNone(x) 이런식으로 씀)

pytest 실행 흐름 (함수 기반임)

  • 테스트 코드 작성(‘test_‘로 시작하는 함수 작성)
  • pytest명령어로 테스트 실행 (pytest tests/)
  • 결과 출력 (성공 or 실패 표시, 상세 로그 제공)

  • 테스트 진행할 코드 ```python def apply_coupon(price, coupon_rate): if not (0 <= coupon_rate <= 100): # 쿠폰 할인율이 0 ~ 100 사인지 확인
    raise ValueError(‘쿠폰 할인율 범위값 에러’) # 범위 벗어나면 에러임
    return proce * (1 - coupon_rate / 100) # 할인된 값 계산해 반환함

coupon.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- *테스트 코드*
```python
import pytest
from coupon import apply_coupon              # coupon.py 에서 apply_coupon 함수 가져옴  

def test_apply_valid_coupon():
    assert apply_coupon(10000, 20) == 8000

def test_apply_zero_coupon():
    assert apply_coupon(10000, 0 ) == 10000

def test_apply_full_coupon():
    assert apply_coupon(10000, 10000) == 0

def test_invalid_coupon_rate():
    with pytest.raises(ValueError):
        apply_coupon(10000, 101)
  • 테스트 진행 ```bash pytest collected 4 items # 4개의 테스트 진행

test_alone.py …. # 4개의 테스트 통과 [100%]

================================== 4 passed in 0.02s ================================== ```

This post is licensed under CC BY 4.0 by the author.