2023. 6. 22. 17:33ㆍIT관련
1. Test Case 설계
이 단계에서는 테스트할 케이스를 설계 합니다.
단순히 케이스를 생성하는 것이 아닌 추후 쉬운 수정이 될 수 있게 설계를 해야 합니다.
API의 경우에는 같은 API라고 할지라도 새롭게 추가되는 에러코드라던지의 정보들이 빠르게 변할 수 있어서
Test Case를 설계할 때 이를 유의해서 작성을 합니다.
import unittest
class MyTestCase(unittest.TestCase):
def setUp(self):
# 테스트 케이스 실행 전에 수행되는 설정 코드
pass
def tearDown(self):
# 테스트 케이스 실행 후에 수행되는 정리 코드
pass
def test_something(self):
# 테스트하고자 하는 기능 또는 시나리오에 대한 테스트 코드 작성
# self.assertEqual(expected, actual)과 같은 어설션(assertion) 메서드를 사용하여 테스트 수행
pass
def test_another_thing(self):
# 다른 기능 또는 시나리오에 대한 테스트 코드 작성
pass
if __name__ == '__main__':
unittest.main()
일반적으로는 이런 형태로 구성이 되고 test_ 를 메서드 이름에 포함하여 테스트 하고자 하는 기능들을 설계합니다.
여러 개의 Test Case 들을 구성할 때 위와 같은 형태로 만들고, 필요한 함수들은 이름에 test_ 를 포함하지 않고 개발하면 실행되지 않습니다.
2. Test Suite 설계
API 단위로 잘 쪼개져 개발되어있는 Test Case 들을 묶어 줍니다.
이렇게 해서 큰 단위의 Test Suite 들을 unittest 시 묶음으로 수행시킬 수 있습니다.
import unittest
# Test Suite 클래스 생성
class MyTestSuite(unittest.TestSuite):
def __init__(self):
super().__init__()
# 테스트 케이스 그룹화
self.addTest(MyTestCase('test_something'))
self.addTest(MyTestCase('test_another_thing'))
if __name__ == '__main__':
# Test Suite 실행
suite = MyTestSuite()
unittest.TextTestRunner().run(suite)
이런 식으로도 구성하여 실행할 수 있는데 이 설명단계에서는 구체적인 설명보다는 형식을 주로 작성합니다.
3. Test Suite 수행
위에서 만들어진 각각의 Test Suite 들을 unittest의 TextTestRunner() 를 사용하여 묶음된
Test Suite를 수행할 수 있습니다.
또는 Test 의 가시성을 위해서 좀 더 HtmlTestRunner를 통해서 묶음된 Test Suite를 수행할 수 있습니다.
# TestSuite 객체 생성 및 테스트 케이스 추가
suite = unittest.TestSuite()
suite.addTest(unittest.TestLoader().loadTestsFromTestCase(YourTestCaseClass))
# TestSuite 실행 및 결과 저장
result = unittest.TextTestRunner().run(suite)
4. Test Result Report 공유
unittest 자체에서 지원하는 TextTestRunner()의 경우에는 아래의 경우대로 결과확인을 할 수가 있는데
텍스트 형태다보니 공유하기가 쉽지 않습니다.
print("Total tests run:", result.testsRun)
print("Total failures:", len(result.failures))
print("Total errors:", len(result.errors))
이런 일련의 과정을 통해서 Unittest 를 이용하여 Code 들을 자동화할 수 있습니다.
이런 과정들을 좀더 상세하게 각각의 회사 Product Service에 맞게 적절하게 변경을 하면
효율적인 QA Automation 작업을 할 수 있습니다.
이번엔 실제로 HtmlTestRunner & UnitTest & Requests 를 이용한 API Test 를 자동화하는 간단한 샘플을 작성해봅니다.
1. Test Case 설계
이 단계에서 저는 가장 중요하게 생각했던 건 API를 설계할 때 구조가 어떻게 되는지, 실제 클라이언트에 전달될 때는 어떤 형태로 전달이 되는지를 먼저 파악해보고 결정을 했습니다.
결과로 저는 하나의 API에 확인해야 할 에러코드가 많고 설계할 때도 특정 Status_code 를 추가하는 방식으로 개발을 하기 때문에 Test Case 단위를 Status_code 단위로 작성을 하였습니다.
# sunbaeVerificateFile.py
import os
import unittest
import sys
from functions import post_message_to_api
# 현재 파일의 경로에서 상위 디렉토리로 이동한 경로를 구합니다.
current_dir = os.path.dirname(os.path.abspath(__file__))
parent_dir = os.path.dirname(current_dir)
# 상위 디렉토리를 검색 경로에 추가합니다.
sys.path.append(parent_dir)
from utils.property import QAProperties
class SunbaeVerificate(unittest.TestCase):
def setUp(cls) -> None:
return super().setUp()
def test_ACCOUNT_DOES_NOT_EXIST(self):
expectStatusCode = 400
caseName = "ACCOUNT_DOES_NOT_EXIST"
body = {
"email":"adf@df.co",
"password":"test"
}
post_message_to_api(
self,
caseName,
expectStatusCode,
self.url,
body)
def test_INVALID_PASSWORD(self):
caseName = "INVALID_PASSWORD"
expectStatusCode = 400
body = {
"email":"tnsqo1126@naver.com",
"password":"asdf"
}
post_message_to_api(
self,
caseName,
expectStatusCode,
self.url,
body)
def tearDown(self) -> None:
return super().tearDown()
request 쏘는 부분은 함수를 만들어서 테스트 결과를 유용하게 사용할 수 있게 개발을 하였습니다.
2. Test Suite 설계
이렇게 만들게 된 Test Case 들은 unittest의 TestLoader() 를 통해서 가져온 후
unittest의 TestSuite() 메서드를 통해서 Case들을 묶을 수 있습니다.
이것을 통해서 여러 개의 Test Case 를 통합시킬 수 있습니다.
# main.py
import unittest
import os
from sunbaeVerificateFile import sunbaeVerificate
import HtmlTestRunner
import glob
if __name__ == '__main__':
try:
sunbae_TestCase1 = unittest.TestLoader().loadTestsFromTestCase(sunbaeVerificate)
suite = unittest.TestSuite(
[sunbae_TestCase1])
# 여러 개의 경우 [sunbae_TestCase1,sunbae_TestCase2]
except Exception as e:
print(e)
3. Test Suite 수행
위에서 만들어진 각각의 Test Suite 들을 HtmlTestRunner() 사용하여 묶음된 Test Suite를 수행합니다.
runner 에 여러가지 옵션들이 있는데 가독성이 좋게 레포트를 내고 싶을 때 자기에 맞게 커스텀을 하면 될 것 같습니다.
아래 코드가 실행이 되면 콘솔에서 실행결과들이 나오고, 실제 테스트가 완료가 되면 html 파일 형식으로 지정된 경로에 생성이 됩니다.
# main.py
import unittest
import os
from sunbaeVerificateFile import sunbaeVerificate
import HtmlTestRunner
import glob
if __name__ == '__main__':
try:
sunbae_TestCase1 = unittest.TestLoader().loadTestsFromTestCase(sunbaeVerificate)
suite = unittest.TestSuite(
[sunbae_TestCase1])
# 여러 개의 경우 [sunbae_TestCase1,sunbae_TestCase2]
runner = HtmlTestRunner.HTMLTestRunner(
output='api_results',
verbosity=2,
combine_reports=True,
report_name="api_test",
report_title=f'sunbae App API Test',
template=template_path)
runner.run(suite)
except Exception as e:
print(e)
실행되는 중의 콘솔 화면
실행 후 html 파일 화면
4. Test Result Report 공유
이렇게 완료가 된 레포트는 파일로 저장이 되는데, 이 결과를 여러 이해관계자들이 빠르게 볼 수 있도록,
주로 요즘은 Slack 을 많이 사용하는 편인 것 같아서 SlackAPI 를 통해서 공유하기로 했습니다.
slackAPI 로 메시지를 보내거나 파일을 업로드하는 것들은 생각보다 간단하기 때문에 여기에서 자세히 다루지는 않겠습니다.
* 다만 기존에 bot app에 권한이 files:wirte 권한이 없다면 추가를 해서 app을 재설치 해주어야 합니다
# main.py
import unittest
import os
from sunbaeVerificateFile import sunbaeVerificate
import HtmlTestRunner
import glob
if __name__ == '__main__':
try:
sunbae_TestCase1 = unittest.TestLoader().loadTestsFromTestCase(sunbaeVerificate)
suite = unittest.TestSuite(
[sunbae_TestCase1])
# 여러 개의 경우 [sunbae_TestCase1,sunbae_TestCase2]
runner = HtmlTestRunner.HTMLTestRunner(
output='api_results',
verbosity=2,
combine_reports=True,
report_name="api_test",
report_title=f'sunbae App API Test',
template=template_path)
runner.run(suite)
except Exception as e:
print(e)
finally:
api_results_dir = os.path.join(parent_dir,'api_results','*')
sorted_files = sorted(glob.iglob(api_results_dir), key=os.path.getctime, reverse=True)
pdfFileName = f'{os.path.splitext(sorted_files[0])[0]}.pdf'
pdfkit.from_file(sorted_files[0], pdfFileName)
slackapi_file(pdfFileName)
저 같은 경우에는 기존에 만들어둔 함수로 경로를 추가해서 보낼 수 있게 만들어둔 게 있어서 try except 문에 finally로 추가를 했습니다.
(여기에는 pdf로 되어있는 이유는 슬랙에 html을 공유하게되면 report를 보려면 파일을 다운로드 받고 저장 후 실행을 해야하는 번거로움이 있어서 html to pdf 라이브러리를 사용하여 공유를 했습니다.)
'IT관련' 카테고리의 다른 글
개발자 홈페이지 없는데 app-ads.txt 설정하는 방법 (0) | 2022.08.29 |
---|---|
윈도우 배치파일 날짜 시간 입력 (자동증가) (0) | 2022.08.15 |
최초 git 설정 시 마주치는 Username for 'https://github.com' 해결 법 (Mac / 맥북) (0) | 2022.03.20 |
git 특정 branch pull 하기 (0) | 2022.03.20 |
안드로이드 앱피움 가이드 (Appium Guide for Android) (0) | 2022.02.21 |