복잡한 테스트 설계 전략

복잡한 테스트 설계 전략 사례

우리는 좀 더 복잡한 테스트 케이스를 추가하여 프로그램의 안정성을 높이려면 다양한 상황을 고려한 테스트 설계가 필요합니다. 여기서는 예외 처리, 엣지 케이스, 입력 유효성 검사, 그리고 통합 테스트를 중심으로 어떻게 테스트 코드를 작성할 수 있는지 보여드리겠습니다.


1. 복잡한 테스트 설계 전략

  1. 기본 기능 테스트: 정상적인 입력이 예상된 대로 변환되는지 확인합니다.
  2. 엣지 케이스 테스트: 빈 입력, 특수 문자, 예상치 못한 마크업이 들어올 때의 동작을 검증합니다.
  3. 에러 처리 테스트: 잘못된 입력을 처리할 수 있도록 예외 처리를 점검합니다.
  4. 통합 테스트: GUI의 각 요소가 올바르게 상호작용하는지 테스트합니다.

2. 예외 처리 추가 (코드 개선)

python
import markdown def convert_markup_to_html(markup_code): """입력된 마크업 코드를 HTML로 변환합니다.""" try: return markdown.markdown(markup_code) except Exception as e: raise ValueError(f"마크업 변환 중 오류 발생: {str(e)}")

3. 테스트 케이스 작성

tests/test_markup.py에 복잡한 테스트 케이스를 추가합니다.

python
import unittest from converter import convert_markup_to_html class TestMarkupToHTML(unittest.TestCase): def test_basic_conversion(self): """정상적인 마크업 변환 테스트""" markup = "# Hello" expected_html = "<h1>Hello</h1>" self.assertEqual(convert_markup_to_html(markup), expected_html) def test_empty_input(self): """빈 입력 테스트""" markup = "" expected_html = "" self.assertEqual(convert_markup_to_html(markup), expected_html) def test_special_characters(self): """특수 문자 입력 테스트""" markup = "Hello <World> & Everyone" expected_html = "<p>Hello &lt;World&gt; &amp; Everyone</p>" self.assertEqual(convert_markup_to_html(markup), expected_html) def test_invalid_markup(self): """잘못된 마크업 처리 테스트""" with self.assertRaises(ValueError): convert_markup_to_html(None) # None 입력은 에러 발생 def test_html_injection(self): """HTML 인젝션 방어 테스트""" markup = "<script>alert('XSS')</script>" expected_html = "<p>&lt;script&gt;alert('XSS')&lt;/script&gt;</p>" self.assertEqual(convert_markup_to_html(markup), expected_html) if __name__ == "__main__": unittest.main()

테스트 케이스 설명

  1. 기본 변환 테스트: # Hello<h1>Hello</h1>로 변환되는지 검증합니다.
  2. 빈 입력 테스트: 입력이 없을 때 빈 HTML이 반환되는지 확인합니다.
  3. 특수 문자 테스트: 특수 문자가 안전하게 HTML 인코딩되는지 점검합니다.
  4. 잘못된 입력 처리 테스트: None과 같은 잘못된 입력이 발생할 때 예외를 발생시키는지 테스트합니다.
  5. HTML 인젝션 방어 테스트: 악성 스크립트가 HTML 인젝션으로부터 안전하게 처리되는지 확인합니다.

4. 통합 테스트 작성 (GUI 상호작용)

tests/test_gui.py 파일을 추가해 GUI와 함수의 상호작용을 테스트합니다.

python
import unittest import tkinter as tk from converter import convert_markup_to_html class TestGUI(unittest.TestCase): def setUp(self): """GUI 테스트를 위한 초기화""" self.root = tk.Tk() self.input_text = tk.Text(self.root) self.output_text = tk.Text(self.root) def test_gui_interaction(self): """GUI에서 입력한 텍스트가 변환되는지 테스트""" self.input_text.insert(tk.END, "# Hello") markup = self.input_text.get("1.0", tk.END).strip() html = convert_markup_to_html(markup) self.output_text.insert(tk.END, html) self.assertEqual(self.output_text.get("1.0", tk.END).strip(), "<h1>Hello</h1>") def tearDown(self): """테스트 후 자원 해제""" self.root.destroy() if __name__ == "__main__": unittest.main()

통합 테스트 설명

  • setUp()tearDown() 메서드를 사용해 테스트 환경을 초기화하고 해제합니다.
  • GUI 상호작용을 통해 입력된 마크업이 올바르게 변환되는지 검증합니다.

5. GitHub Actions에 통합

python-app.yml에 통합 테스트 실행을 위한 명령을 추가합니다.

yaml
- name: Run GUI Tests run: | python -m unittest discover tests

6. 요약

이제 더 복잡한 테스트 케이스와 GUI 통합 테스트가 준비되었습니다. 이를 통해:

  1. 다양한 입력 시 발생할 수 있는 예외를 처리할 수 있습니다.
  2. GUI의 상호작용이 올바르게 동작하는지 보장할 수 있습니다.
  3. GitHub Actions와 연계하여 코드 푸시 시마다 자동으로 테스트가 실행됩니다.

댓글 쓰기