파이썬 디버깅 - 03 나의 첫 테스트 코드

핏자·2023년 4월 8일
0

인공지능사관학교

목록 보기
11/31
post-thumbnail
  • 왜 테스트 코드가 필요한가요?

- 왜 테스트 코드가 필요할까요?

def average(numbers):
	return sum(numbers) / len(numbers)

- 여기서 드는 의문

맞게 짠 코드일까요?

- 왜 테스트 코드가 필요할까요?

def average(numbers):
	if len(numbers) > 0:
		return sum(numbers) / len(numbers)
	print("No numbers!")

def average(numbers):
	try:
		return sum(numbers) / len(numbers)
	except ZeroDivisionError:
    	print("No numbers!")

- 여기서 드는 의문

둘은 정말 같은 코드일까요?


- 테스트 코드로 알 수 있는것

코드가 설계된 대로 작동하는지

코드를 수정한 후에도 동일하게 작동하는지




  • 유닛 테스트

- 유닛 테스트

Unit(가장 작은 단위 = 함수 1개) Test


주어진 입력(인자)에 대해

예상된 출력(리턴 값)을 내놓는가?

def is_palindrome(text):
	if text[0] == text[-1]:
    	...

def test_is_palindrome_level():
	assert(is_palindrome("level") == True)
def test_is_palindrome_lever():
	assert(is_palindrome("lever") == False)    	

def test_is_palindrome_empty():
	assert(is_palindrome("")) # ??
def test_is_palindrome_sentence():
	assert(is_palindrome("Mr. Owl ate my metal worm")) # ??    	

테스트 작성을 어떻게 작성하느냐에 따라

어떤 출력을 의도하는지가 결정됨


즉, 테스트 == 설계




  • 유닛 테스트의 조건

- 읽기 쉽다

# Bad
def test1():
	assert(is_palindrome("level") == True)
# Good
def test_is_palindrome_level():
	assert(is_palindrome("level") == True)

- 독립적이다

heater = Heater()
def test_control_heater_when_cold():
	heater.current_temperature = -5.0
    heater.preferred_temperature = 18.0
    control_heater(heater)
    assert(heater.is_turned_on == True)
...
...
def test_control_heater_when_hot():
	heater.current_temperature = 25.0
    heater.preferred_temperature = 18.0
    control_heater(heater)
    assert(heater.is_turned_on == False)
# Case 1
test_control_heater_when_cold() # PASS
test_control_heater_when_hot() # PASS

# Case 2
test_control_heater_when_hot() # FAIL
test_control_heater_when_cold() # PASS
# 뒤집어서 실행하니 안되는 일정하지 않은 테스트 결과 출력(heater 때문에)
# 따라서 각 함수에 heater = Heater()선언
# 테스트 코드간에 공유하는 객체가 있으

- 충분히 작다

# Bad
def test_heater():
	heater = Heater()
    ...
    assert(heater.is_turned_on == True)
    assert(read_temperature(heater) == "..")
# 두가지를 테스트하여 하나만 오류가 있을시 찾기 힘들다
# Good
def test_heater():
	
    ...
    assert(heater.is_turned_on == True)
def test_red_temperature():
	...
    assert(read_temperature(heater) == "..")

- 충분히 넓다

들어올 수 있는 다양한 입력들을 충분히 고려해야 한다

즉, edge case를 고려해야 한다

# 설정 온도와 현재 온도가 같은 경우
def test_control_heater_temperature_same():
	heater.current_temperature = 18.0
    heater.preferred_temperature = 18.0
    control_heater(heater)
    assert(???)
# 현재 온도를 측정할 수 없는 경우
def test_control_heater_temperature_none():
	heater.current_temperature = none
    heater.preferred_temperature = 18.0
    control_heater(heater)
    assert(???)

# 빈 문자열
def test_is_palindrome_empty():
	assert(is_palindrome("") == ???)
# 특수기호로만 이루어진 문자열
def test_is_palindrome_empty():
	assert(is_palindrome("./!@#:?") == ???)



  • 파이썬의 unittest

- unittest

import unittest

class IsPalindromeTests(unittest.TestCase):
	def test_level(self):
    	self.assertTrue(is_palindrome("level"))
	def test_level(self):
    	self.assertFals(is_palindrome("lever"))

import unittest

class IsPalindromeTests(unittest.TestCase):
	...

unittest.main()
# True
test_level (__main__.IsPalindromeTests) ... ok
test_lever (__main__.IsPalindromeTests) ... ok
---------------------------------------
Ran 2 tests in 0.000s
OK
# False
test_level (__main__.IsPalindromeTests) ... FAIL
test_lever (__main__.IsPalindromeTests) ... ok
=======================================
FAIL: test_level (__main__.IsPalindromeTests)
---------------------------------------
Ran 2 tests in 0.000s
FAILED (failures=1)
profile
개발자 핏자의 로그들

0개의 댓글