본문 바로가기
프로그래밍 놀이터/Tips

[실용주의 프로그래머] 가차 없는 테스트

by 돼지왕 왕돼지 2018. 11. 15.
반응형

[실용주의 프로그래머] 가차 없는 테스트


[실용주의 프로그래머] 가차 없는 테스트, 검증, 단위 테스트, 사용편의성 테스트, 상태 커버리지, 성능 테스트, 스트레스 테스트, 유닛 테스트, 유효성 평가, 유효성 평가와 검증, 일찍 테스트하라, 자동으로 테스트하라, 자원 고갈 에러 복구, 자주 테스트하라, 코드 조금 테스트 조금, 코드 커버리지, 테스트, 통합 테스트, 파괴자 테스트


-

개발자 대부분은 테스트를 싫어한다.

코드가 어디에서 깨지는지 무의식적으로 알고 약한 지점을 피해 다니면서, 살살 테스트하려 한다.

실용주의 프로그래머들은 다르다.

우리는 당장 버그를 찾아 나서도록 내몰리지만, 그 대신 나중에 다른 사람이 자기 버그를 발견하게 되는 수치를 피할 수 있다.



-

일찍 테스트하고, 자주 테스트하라. 자동으로 테스트하라.



-

코드를 작성하자마자 테스트해야 한다.



-

버그가 빨리 발견될수록 고치는 비용이 적어진다.

코드 조금, 테스트 조금은 스몰토크 세계에서는 유명한 격언이다.

우리는 제품 코드를 만드는 것과 동시에(혹은 이전에) 테스트 코드를 만듦으로써 그 주문을 우리것으로 할 수 있다.



-

사실 훌륭한 프로젝트에는 제품 코드보다도 테스트 코드가 더 많을지 모른다.

테스트 코드를 만들기 위해 소요되는 시간에는 그 노력만큼의 가치가 있다.

길게 보면 이쪽이 훨씬 더 싸게 들며, 결함이 영에 가까운 제품을 만드는 꿈이 정말 이루어지기도 한다.


이 외에도 테스트를 통과했다는 것은 그 코드가 “완료되었다”고 말할 수 있는 높은 수준의 확신을 갖게 하는 것이다.



-

모든 테스트가 통과하기 전엔 코딩이 다 된 게 아니다.



-

코드가 모든 가능한 테스트를 통과하기 전까지는 누구에게건 사용가능하다고 주장할 수 없다는 것이다.



-

우리는 프로젝트 범위에서 이루어지는 테스트의 세 가지 주요 면모를 살펴보아야 한다.

무엇을 테스트할지, 어떻게 테스트할지, 그리고 언제 테스트할지.



-

수행해야할 소프트웨어 테스트에는 대여섯 가지 주요 유형이 있다.


단위 테스트

통합 테스트

유효성 평가와 검증

자원 고갈, 에러, 그리고 복구

성능 테스트

사용편의성 테스트



-

단위테스트는 하나의 모듈을 테스트하는 코드다.

사용하는 모든 모듈을 갖고 진행하기 전에 단위 테스트를 통과해야만 한다.



-

통합 테스트는 프로젝트를 구성하는 주요 서브시스템이 다른 부분과 제대로 작동하는지 보여준다.

계약이 제대로 되어 있고 테스트가 잘 되어 있다면, 어떤 통합 문제건 쉽게 발견할 수 있다.



-

사용자들은 무엇이 필요한지 이야기해 줬지만, 그게 정말 사용자들이 필요로 하는 것인가?(유효성 평가)

시스템의 기능적 요구사항을 충족하는가? (검증)



-

메모리, 디스크 공간, CPU 대역폭, 벽시계 시간, 디스크 대역폭, 네트워크 대역폭, 칼라 팔레트, 비디오 해상도 등의 여러 제한 사항에 마딱뜨린다.



-

성능 테스트, 스트레스 테스트 혹은 부하가 걸린 상태에서의 테스트 역시 프로젝트의 중요한 부분이다.






-

사용편의성 테스트는 실제 사용자들이 시행한다.

인간적 요소라는 측면에서 사용편의성을 바라보라.


유효성 평가와 검증과 마찬가지로, 사용편의성 테스트는 보정할 시간이 있을 때에 되도록 일찍 시행해야 한다.



-

회귀 테스트, 테스트 데이터, GUI 시스템 구동, 테스트를 테스트하기, 철저히 테스트 하기 등이 있다.



-

GUI 테스트를 할 때는 결합도가 낮은 코드를 작성하는 것이 좋다.

좀 더 모듈화된 테스트가 가능하고, GUI 가 표시되지 않은 상태에서도 앱 로직을 테스트할 수도 있다.



-

어떤 버그를 감지해내는 테스트를 작성한 후에, 그 버그가 의도적으로 생기도록 한 다음 테스트가 불평을 해대는지 확인하라. 이렇게 하면 실제로 버그가 생겼을 때 테스트가 그걸 잡아낼 것이라고 확신할 수 있다.


파괴자를 써서 테스트를 테스트하라.



-

정말 테스트에 대해 심각하게 생각한다면, 프로젝트 파괴자를 임명할 수 있다.

파괴자의 역할은 소스 트리의 카피를 별도로 만들어 취한 다음, 고의로 버그를 심고 테스트가 잡아낼지 검증하는 것이다.

테스트를 작성할 땐 알람이 제때 울리는지 확인하라.



-

테스트가 올바르다는 확신이 들고, 버그도 찾아낸다면, 코드 베이스를 충분히 철저하게 테스트했다는 것을 어떻게 알 수 있을까?

한마디로 답하자면 알 수 없다.

그리고 앞으로도 알 수 없다.

하지만 커버리지 분석 도구는 코드의 어느 라인이 실행되지 않았는지 기억한다.

테스트가 얼마나 포괄적인지에 대한 대체적인 느낌을 가질 수 있다.

하지만 100% 커버리지를 기대하지는 마라.



-

코드의 모든 라인이 실행될지라도, 그게 전부가 아니다. 정말로 중요한 것은 상태의 개수다.

상태는 코드 라인들과 동등하지 않다.

코드가 이 줄을 실행했다는 것을 아는 것만으로는 상태가 모두 커버되었는지 드러나지 않는다.



-

코드 커버리지보다 상태 커버리지를 테스트하라.



-

많은 프로젝트에서 사람들은 테스트를 마지막 일 분까지 미룬다.

데드라인의 날카로운 모서리에 닿는 순간까지.

그것보다는 훨씬 일찍 시작해야 한다.

실제 제품에 들어갈 모든 코드는 나오자마자 테스트해야 한다.

테스트는 대부분 자동화되어야 한다.



-

우리는 될 수 있으면 자주, 그리고 소스 저장소에 코드를 체크인하기 전에는 반드시 테스트하길 좋아한다.



-

필요한 만큼 자주 모든 개별 단위 테스트와 통합 테스트를 회귀 테스트하는 것은 문제가 아니다.



-

어떤 테스트들은 그렇게 자주 실행하기 쉽지 않다.

하지만 이 테스트들은 주기적으로 일정에 따라 실행되게 하는 것이 중요하다.



-

현존하는 테스트의 그물을 빠져 나가는 버그가 있으면, 다음번에는 그걸 잡아낼 수 있도록 새 테스트를 추가해야 한다.



-

버그는 한 번만 잡아라.


인간 테스터가 버그를 찾아내면, 그 때가 인간 테스터가 그 버그를 찾는 마지막 순간이 되어야 한다.

그 순간 이후로부터는 무조건, 매번, 예외 없이, 아무리 사소한 것일지라도, 자동화 테스트들을 수정해야 한다.




반응형

댓글