시작에 앞서
해당 내용은 <가장 빠른 풀스택을 위한 Flask & FastAPI>, Dave Lee 지음. BJ Public 출판.
내용을 토대로 작성되었습니다. 보다 자세한 사항은 해당 교재를 참고하시기 바랍니다.
테스팅(testing)
[테스팅이란?]
개발한 소프트웨어가 예상대로 작동하는지 검증하는 과정.
버그를 미리 찾아 수정하거나 새로운 기능을 추가했을 때 기존 기능에 문제가 발생하지 않는지 확인하는 과정.
테스팅 없이 코드를 배포하면 사용자가 버그를 만나거나 시스템이 예상치 못한 방식으로 작동할 위험이 있다.
테스팅은 이러한 문제를 미리 발견하고, 높은 품질의 소프트웨어를 제공하는 데 도움을 준다.
플라스크에서의 테스팅
플라스크에서는 pytest나 플라스크 자체의 unittest를 이용하여 테스팅할 수 있다.
my_app.py라는 파일을 만들고 하단의 코드를 입력하여 저장한다.
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello, World!'
이 코드를 하단의 명령어로 실행하고
flask --app my_app.py run
http://127.0.0.1:5000/ 링크에 접속하면
플라스크 애플리케이션 테스트를 위한 테스트 케이스를 작성해본다. (test_app.py 파일)
※ 테스트 케이스: 특정 기능이 예상한 대로 동작하는지 확인하는 코드
import unittest
from my_app import app # my_app 모듈에서 플라스크 애플리케이션 가져옴
# BasicTestCase 클래스는 unittest.TestCase를 상속받음
class BasicTestCase(unittest.TestCase):
# index 라우트를 테스트하는 메서드
def test_index(self):
# 플라스크 애플리케이션을 위한 테스트 클라이언트 인스턴스 생성
tester = app.test_client(self)
# 테스트 클라이언트를 사용하여 루트 URL로 GEET 요청
response = tester.get('/', content_type='html/text')
# 응답받은 상태 코드가 200인지 확인
self.assertEqual(response.status_code, 200)
[코드 설명]
- app.test_client() 메서드: 플라스크 애플리케이션을 테스트하기 위한 테스트 클라이언트를 생성
- 테스트 클라이언트는 실제 웹 서버를 실행하지 않고도 애플리케이션에 요청을 보내고 그 응답을 확인할 수 있게 해줌
- tester.get() 메서드: 지정된 경로로 HTTP GET 요청을 보내는 데 사용.
- response.status_code: 서버가 반환한 HTTP 상태 코드 나타냄
- self.assertEqual() 메서드: unittest의 기능으로, 두 값을 비교하여 같으면 테스트 통과
[테스팅 관련 주요 문법]
- import unittest: unittest 프레임워크를 가져옴. 파이썬의 표준 라이브러리에 포함되어 있으며 테스트를 작성하고 실행하는 데 필요한 도구 제공
- unittest.TestCase: 모든 테스트 케이스는 이 클래스를 상속받아야 하며, 여러 가지 어설션 메서드(assertion methods)를 제공하여 테스트를 쉽게 작성할 수 있게 한다
- 어설션 메서드(assertion methods): unittest.TestCase 클레스가 제공하는 메서드의 한 종류. 테스트 중에 조건이 참인지 확인하기 위해 사용.
★ 기본적인 assertion methods
- assertEqual(a, b): a와 b가 같은지 확인
- assertTrue(x): x가 True 인지 확인
- assertFalse(x): x가 False 인지 확인
- assertRaises(Error): 지정된 예외가 발생하는지 확인
- assertIn(a, b): a가 b 컨테이너에 포함되어 있는지 확인
- assertIsNone(x): x가 None 인지 확인
▶ 이러한 메서드들은 테스트를 작성할 때 기대하는 결과를 명확히 표현하고, 코드가 올바르게 동작하는지 자동으로 검증할 수 있게 해주는 강력한 도구이다.
unittest 프레임워크는 테스트 실패 시 테스트 결과에 대한 자세한 정보를 출력하여 디버깅을 돕는다.
- test_client(): 플라스크 애플리케이션의 테스트 클라이언트 인스턴스 생성. 이를 사용하여 실제 서버를 구동하지 않고도 HTTP 요청을 애플리케이션에 보낼 수 있다
- get(): 테스트 클라이언트의 메서드. HTTP GET 요청을 보내고 응답을 받는 데 사용된다.
- assertEqual(): 어설션 메서드 중 하나. 두 값이 같은지 확인하는 메서드. 테스트하려는 값이 예상과 다르면 테스트가 실패한다.
테스트 실행하기
작성한 테스트 케이스를 실행하기 위해 터미널에 하단의 명령 입력
python -m unittest test_app.BasicTestCase
- -m unittest: -m 옵션은 모듈을 스크립트로 실행하려고 할 때 사용. -m unittest 명령은 unittest 모듈을 명령줄에서 실행하도록 한다
- test_app.BasicTestCase: test_app.py 파일에 정의된 BasicTestCase 클래스를 지정. 해당 클래스 내의 모든 테스트 메서드가 실행된다
해당 명령어를 실행하면 BasicTestCase 클래스에 있는 모든 테스트 메서드가 실행된다.
테스트가 성공적으로 완료되면, 터미널에 'OK' 가 출력된다. (테스트 결과가 예상한 결과와 일치함을 의미)
unittest의 다양한 기능
unittest는 파이썬 프로그램을 테스트하는 대표적인 라이브러리로서, 다양한 기능을 갖고 있다.
import unittest
from my_app import app # my_app 모듈에서 플라스크 애플리케이션 가져옴
class AdvancedTestCase(unittest.TestCase):
def setUp(self):
# 플라스크 애플리케이션의 테스트 클라이언트 생성
# self.tester는 테스트 동안 사용할 가상의 클라이언트 객체
self.tester = app.test_client(self)
def tearDown(self):
# 테스트가 끝난 후 정리 작업 수행. 현재는 비어 있는 상태
pass
def test_index(self):
# self.tester 객체를 사용하여 루트 URL('/')로 HTTP GET 요청 보냄
response = self.tester.get('/', content_type='html/text')
# 응답의 상태 코드가 200인지 확인
self.assertEqual(response.status_code, 200)
◆ unittest의 주요 메서드
setUp() 메서드
- 테스트 클래스 내에서 각 테스트 메서드가 실행되기 전에 먼저 실행된다
- 테스트에 필요한 객체 생성, 테스트 환경 구성 등의 작업 수행
- 위 코드에서는 app.test_client()를 호출하여 self.tester 객체 생성 (테스트를 위한 가상의 클라이언트 역할)
tearDown() 메서드
- 각 테스트 메서드 실행 후 호출되며, setUp() 에서 생성된 객체를 정리하거나 테스트 환경을 초기 상태로 복구하는 데 사용
- 데이터베이스 세션을 닫거나 임시 파일을 삭제하는 등의 작업 수행
테스트 메서드
- test_로 시작하는 메서드는 unittest에 의해 자동으로 테스트 메서드로 인식
- 이 메서드들 내에서 실제 테스트 수행. (HTTP 요청을 보내고, 응답 확인 등의 작업)
터미널에서 하단의 명령어를 수행하면
python -m unittest test_app.AdvancedTestCase
unittest 테스트 러너가 지정된 테스트 클래스의 모든 테스트 메서드를 자동으로 찾아 실행한다.
- setUp() 메서드는 AdvancedTestCase 클래스의 각 테스트 메서드 실행 전에 self.tester 객체를 생성하여 할당.
- self.tester 객체는 test_index() 메서드에서 루트 URL로 GET 요청을 보내는 데 사용되며, 그 결과로 받은 응답의 상태 코드를 확인하여 테스트가 성공했는지 검증.
OK가 출력되면 테스트가 성공적으로 실행된 것을 의미한다.
다수의 테스트 케이스 실행
import unittest
from my_app import app # my_app 모듈에서 플라스크 애플리케이션 가져옴
# AdvancedTestCase 클래스는 unittest.TestCase를 상속받아 여러 테스트 케이스를 정의
class AdvancedTestCase(unittest.TestCase):
# setUp 메서드는 각 테스트 메서드를 실행하기 전에 호출
def setUp(self):
# self.tester는 플라스크의 test_client 인스턴스를 참조
# 이를 통해 실제 HTTP 서버를 구동하지 않고도 HTTP 요청 테스트 가능
self.tester = app.test_client(self)
# test_index 메서드는 루트 경로('/')에 대한 테스트 정의
def test_index(self):
# self.tester 객체를 사용하여 루트 URL('/')로 HTTP GET 요청 보냄
response = self.tester.get('/', content_type='html/text')
# 응답의 상태 코드가 200인지 확인
self.assertEqual(response.status_code, 200)
# test_index_text 메서드는 루트 경로의 응답 텍스트를 테스트
def test_index_test(self):
# 루트 경로에 GET 요청을 보내고 응답 데이터 검증
response = self.tester.get('/', content_type='html/text')
# 응답 데이터가 'Hello, World!'와 일치하는지 바이트 문자열로 확인
self.assertEqual(response.data, b'Hello, World!')
# test_another_route 메서드는 다른 경로('/another') 에 대한 테스트를 정의
def test_another_route(self):
# '/another' 경로에 GET 요청을 보내고 상태 코드를 검증
response = self.tester.get('/another', content_type='html/text')
# 해당 경로가 존재하지 않으므로 상태 코드가 404 (찾을 수 없음) 인지 확인
self.assertEqual(response.status_code, 404)
해당 코드를 입력한 후, 터미널의 하단의 명령어를 입력하면
python -m unittest test_app.AdvancedTestCase
AdvancedTestCase 클래스에 정의된 모든 테스트 메서드 (test_ 로 시작하는 메서드)가 실행되며,
모든 테스트가 통과하면 터미널에 OK 가 출력되며,
실패하는 경우에는 실패한 테스트에 대한 정보와 여러 메시지가 출력된다.
'[파이썬 Projects] > <파이썬 웹개발>' 카테고리의 다른 글
[파이썬] 플라스크(Flask) - 플라스크 프로젝트 - 메모앱(1) (0) | 2024.07.23 |
---|---|
[파이썬] 플라스크(Flask) - 성능 개선 팁 (2) | 2024.07.23 |
[파이썬] 플라스크(Flask) - 배포(Deployment) (2) | 2024.07.22 |
[파이썬] 플라스크(Flask) - 캐싱(caching) (0) | 2024.07.21 |
[파이썬] 플라스크(Flask) - RESTful API (0) | 2024.07.21 |