Overview
오늘 포스팅은 코드리뷰를 진행하면서 몇 차례 피드백을 받았던 내용을 다루고자 한다.
조금 더 섬세하게, 깊이 생각했다면 이런 부분까지 놓치지 않았을 부분인데,
종종 마음이 급할 때 이런 부분을 놓치는 것 같다.
테스트 코드를 작성하는 과정에서 python unit test 에서 string의 count 내장함수를 통한 결과 확인이 필요했고,
그 확인하는 과정에서의 경험을 나누고자 한다.
아래 내용은 비단, python 에 만 한정되어 적용되는 내용이 아니며, 모든 코드에서 이런 로직은 조심해야 할 내용이다.
What's count?
count 는 단순하다. python 에서 iterable 한 자료형에서 특정 항목의 갯수를 파악해 주는 내장함수다.
다만, 오늘 얘기하고자 하는 내용은 string class의 count 이다.
사용 방법은 아래와 같다.
문자열의 범위 내에서 찾고자 하는 내용이 얼마나 들어있는 지 갯수를 카운트 해 준다.
아래는 단순한 예시이다.
my_string = "Hello world"
print( my_string.count("l") )
출력은 다음과 같다.
$ python3 str_count_01.py
3
정말 단순한 사용방법이고, 그냥 원하는 문자열을 입력하면 문자열 변수에 몇개나 있는지 카운트를 해 준다.
사실 그냥 카운트를 세고 싶은게 목적이었다면, 달리 조심해야 될 부분은 없다. 몇 개인지 파악하고 끝이기 때문이다.
count의 기능에 대해서는 어느정도 이해했으리라 본다. 정말 단어 그대로이기 때문에 어렵지 않을 것이다.
그러면 이제 count를 이용해 문자열 갯수를 파악할 때 주의해야 할 부분을 알아보자
Be careful to use count with string not specific.
앞서 언급은 했지만 python 코드 작성 부분에 대한 내용이었던 터라 python 카테고리로 뽑았을 뿐이지,
사실은 어느 언어에서나 조심해야 할 내용이다.
테스트가 필요한 기능과 내가 하려고 했던 확인사항은 다음과 같다.
- 특정 함수를 호출하면 abc0_, abc1_ , ... , abcN_ 과 같이 헤더를 만들어 주는 기능이 있다.
- 특정 헤더가 몇 개나 출력이 되었는지 아래 코드처럼 확인하고 싶었다.
# 여기서 header는 하드코딩하였으나, 실제로는 요청에 따른 응답 데이터이다.
headers="abc0_qweasdzcx\nabc0_123qwert\nabc1_123qwewer\nabc1_dfdf"
nh = headers.count("abc0")
s.assertEqual( nh, 2, headers )
결국 내가 보고싶었던 것은 headers라는 긴 문자열에서 abc0 이 몇 개나 있는지 확인하고, 내가 예상했 던 count대로 수행이 되는지 확인하고 싶었던 상황 이었다. ( 예: 특정 함수를 2번 호출 시 abc0이 2번 나와야 한다. )
그런데 이렇게 비교를 하게되면, abc0인 경우는 괜찮을 지 몰라도 아래와 같은 상황에서 문제가 발생한다.
# 여기서 header는 하드코딩하였으나, 실제로는 요청에 따른 응답 데이터이다.
headers="abc0_qweasdzcx\nabc0_123qwert\nabc1_123qwewer\nabc1_dfdf\nabc11_dfd124002f\nabc12_dddddfdf"
nh = headers.count("abc1")
s.assertEqual( nh, 2, headers )
이런 방식으로 비교를 하게되면, abc1 이 abc10이 모두 카운트 되어서 원하는 테스트 수행이 아니게 된다..
( 당장은 테스트에 문제가 없더라도, 추후에 원하지 않는 결과임에도 테스트가 pass될 수 있다. )
그러므로 아래와 같이 정확하게 count를 비교 함으로써 더 정확한 테스트가 필요하며, 테스트 뿐만 아니라 실제 코드(headers를 만들어 내는 코드) 또한, 추후 정확한 테스트를 위해서는 정확하게 구분이 되는 header를 만들어 내야 할 필요가 생긴다.
아래처럼 테스트 코드를 작성한다면, 좀 더 안전하게 테스트가 가능하다.
헤더는 '_'를 가지고 있기 때문에, abc뒤의 숫자를 정확하게 포함해서 count가 가능할 것이다.
# 여기서 header는 하드코딩하였으나, 실제로는 요청에 따른 응답 데이터이다.
headers="abc0_qweasdzcx\nabc0_123qwert\nabc1_123qwewer\nabc1_dfdf\nabc11_dfd124002f\nabc12_dddddfdf"
# 처음 목적이었던 abc1_ 만 count하며, abc10 or abc11~1xxxx 등을 카운트 하지 않는다.
# 그리고 headers 를 생성하는 프로그램도 이런 테스트를 위해 구분자 '_' 를 반드시 두어야 할 것이다.
nh = headers.count("abc1_")
s.assertEqual( nh, 2, headers )
무심코 넘어갈 수 있지만 실수하기에 너무나 좋은 부분이라서 정리 해 보았다..
'CS > Python' 카테고리의 다른 글
[python/string] 문자열 앞 f, r 의 의미 - formatter string과 raw string (0) | 2021.11.19 |
---|---|
[python] positional argument 의 개념, 의미 (0) | 2021.11.17 |
[python] map 함수(map function) 의 사용방법 및 예시 (0) | 2021.11.13 |
[python] 오류출력은 에러로 보내주세요 ! - print 함수의 출력을 stderr 로 보내기 (2) | 2021.10.06 |
[python] python에서 객체를 string으로 출력하는 방법 (0) | 2021.10.04 |