이전부터 안건을 진행하면서, API응답값에 대해서도 체크를 한다던지, 검색기능 같은 경우에는 UI확인을 하지 않고 API테스트 하고 비정기배포를 진행했던 경험이 있는데요, 이번에 회사에서 2개 안건에서 별도의 API 테스트 기간을 정하고 API를 수행하였습니다.
API 테스트를 수행하면서 느낀점을 기록으로 남깁니다..
API 테스트도 UI테스트와 개념적으로는 큰 차이는 없었습니다.
합니다.
이렇게 기재해놓으니 참 쉬워보이긴 하는데..ㅎ..ㅎㅎ..
이론과 실전은 역시 다른 것을 다시 한 번 느꼈습니다.
일단 개발되는 API에 대해, 기본적으로는 요구사항 문서에 기재되어있는 것들에 대해서 검증을 시작했습니다. (명세기반 테스트) 저는 진행을 하면서 아래 3가지에 대해서 준비를 하고, 테스트를 진행하였습니다.
UI테스트할 때와 똑같이, 어떤 입력값(파라미터, 바디값)에 대해 출력값(response)이 어떤지를 확인을 진행했습니다.
등을 확인하면서, 비정상적, 허용하지 않는 파라미터들과 같은, 요구사항에 명시되지 않은 동작이 발생할만한 파라미터들을 찾아 호출해봅니다.
기본적으로 블랙박스 테스팅과 같다고 생각하면, 생각하기가 쉽습니다.
여기서 참조문서는 요구사항 정의서 뿐만 아니라 API문서도 확인해가며, 구현이 문서와 동일한지를 체크해주어야했습니다.
근데 위 내용은 테스트를 해야하는, 하나의 API 엔드포인트 자체에 대한 테스트입니다. 보통 API를 테스트하는 것에 대해서는, 위 내용에 대해서만 생각하시는 분들이 많을텐데요, 이것은 맞으면서도 틀립니다.
API를 테스트한다는 것은 사실 GUI만 없다할 뿐이지, 백엔드에서의 내부 시스템은 모두 통합되어있다고 이해하는 것이 더 좋습니다. 따라서 유저 시나리오를 상정한 호출흐름을 작성해야합니다.
이것도 사실 UI테스트를 할 때와 마찬가지입니다. end-to-end 테스트를 할 때도, 유저의 시나리오를 상정한 테스트를 수행하는데요, API도 할 수 있습니다.
저도 유저 시나리오를 상정해서 진행을 했습니다.
예를 들어, 좋아요 API에 대해 테스트를 한다고 해봅시다.
위 기능들 모두 좋아요 와 관련되어있는 기능입니다.
그렇다면 아래와 같은 하나의 유저 시나리오를 상정해볼 수 있을 것 입니다.
위 흐름에 대해, 각각의 API를 차례대로 호출하면서 어떤 하나의 유저 시나리오를 확인해볼 수 있습니다. 시나리오에 따라서는 좋아요 API와 관련없는 API를 호출해야하는 경우도 있습니다.
그런데 이런 기능을 하는 API가 여러개가 있다면 어떨까요? 예를 들어 이 좋아요 API가 웹용 / 앱용 API가 나뉘어져있다고 해봅시다.
그렇다면 웹과 앱 API를 번갈아가며 등록/해제/조회 를 해보아야할 것 입니다. 예를 들어, 웹에서 좋아요를 누른 상품이, 앱에서 조회했을 때 잘 등록되어있는지, 좋아요 갯수는 잘 증가해있는지 등을,
등등의 흐름으로 체크해줘야 할 것 입니다.
혹은, API가 버전업을 한다고 해봅시다. (v1 -> v2) 그런데 앱의 경우에는 이미 릴리즈나간 앱에 대해서는 강제업데이트를 하지 않는 한, v1 api에 대해서도 트래픽이 발생하므로 하위버전의 API도 유지를 해줘야합니다.
버전업이 되면서 내부 리팩토링뿐만 아니라 다른 기능이 추가된다거나, 데이터를 얻어오는 데이터베이스가 달라진다고 한다면, 다시 v1과 v2 엔드포인트에 대해서도 번갈아가며 체크해줘야합니다.
등등등..
위 시나리오 2번, 3번이 혼재되어있는 경우입니다.
등등..
이런 경우라면 조건들에 대해 페어와이즈하게 조건을 도출해서 간추리는 것도 방법일 것 같습니다.
작성하다보면 어떤 시나리오는 어쩌면 보편적인 유저의 사용 시나리오와는 거리가 멀지도 모릅니다. 따라서 어떤 시나리오를 봐야할지, 어떤 시나리오는 보지않아도 될지에 대해 이해관계자와 팀원들에게 시나리오에 대한 리뷰를 요청해서 누락되는 케이스는 없을지를 꼭 챙겨야합니다.
저 또한 팀원들과 관계자들에게 테스트케이스 리뷰를 부탁하긴 했었습니다만... 안건 종료 후에 누락된 동작들과 시나리오가 있었어서 많이 아쉬웠습니다. 😵
정해진 테스트들을 다 수행한 후에, 애드혹 테스트를 수행하였습니다. API테스트는 사실 스크립트를 작성하고, assertion을 통해 빠르게 검증하는 이점이 있습니다만, 개발이 진행되면서 API문서가 갱신이 안된다던지 해서 문서에는 기재되어있지 않지만, 응답값에 포함되어있는 필드값들이 존재할 수 있습니다. 또한 관계자들끼리 논의 후에 필드값이 추가된다거나, 응답값의 구조가 바뀔 수도 있는데, 이것을 테스트담당자가 파악을 못했다면, 잉이미 작성해놓은 스크립트로는 걸러낼 수가 없습니다.
이러한 값들은 이미 작성되어있는 assertion 으로만으로는 체크할 수 없기 때문에 직접 API응답값을 훑어보면서 체크를 해야합니다.
필수 파라미터 및 옵셔널 파라미터의 조합에 대한 조합패턴 확인
이 파라미터에 이것저것 집어넣어가면서 호출하며, 동작을 확인합니다.
또한 파라미터뿐만 아니라, 어떤 데이터의 상태에 따른 동작도 확인해볼 수도 있을 것입니다. 예를 들어, 좋아요 기능처럼 로그인이 필요한 경우라면, 유저의 계정 상태라던지, 좋아요 에 등록하는 상품의 상태 (휴면처리된 상품이라던지, 팔지 않는 상품이라던지, 판매완료 상품 등등) 등도 고려해가면서 테스트를 해볼 수 있을 것 같습니다.
안건을 진행하면서 구체적으로 어떤 점들을 진행했었는지, 위에 기재해보았는데요, 진행하면서 여러가지 느낀 점들이 있어서 좀 더 기재해보겠습니다.
테스트들은 안건에서 백엔드 개발완료 1~2주 전에 테스트를 진행했습니다.
API테스트를 수행하면서, UI테스트 이전에 비즈니스 로직에 대한 이슈에 대해 좀 더 빠른 시기에 확인하고, 이해관계자들과 논의를 할 수 있었고, 결론적으로 수정할 수 있는 시간을 벌 수 있었습니다.
end-to-end 테스트때 비즈니스 로직에서 이슈를 확인하게 된다면, 릴리즈가 얼마남지 않은 상황에서 다들 부랴부랴 논의하고 정리하느라 급박해지는데요, 조금이라도 릴리즈 예정일이 넉넉하게 남은 상황에서 비즈니스 로직, 정책적인 이슈를 확인하게 되어 그만큼 논의해서 수정 방향을 정하고, 로직을 수정할 수 있는 기간을 벌 수 있었습니다.
그리고 프론트엔드 / 클라이언트에서도 수정이 필요한 이슈라면, 대부분 백엔드가 개발 후반인 상황이라면, 프론트엔드의 경우에는 한창 개발중인 단계일 것이기 때문에 개발단계에서 빠르게 수정을 할 수 있게 됩니다.
end-to-end 테스트를 하게 되면, 일단 기본적으로
이 과정에서 커뮤니케이션 코스트가 상당히 많이 발생하게 됩니다.
그러나 API테스트를 하게 된다면, 프론트엔드 / 클라이언트 개발자를 거치지 않게 되므로 이슈 해결을 위한 커뮤니케이션에 대해 리소스가 많이 줄어들게 됩니다.
API 테스트 스크립트에 대해서, 일단 작성이 되면 계속해서 재사용할 수 있어서 좋았습니다. 이슈를 확인했던 파라미터 패턴에 대해서, 이슈가 수정되면 assertion 조건을 추가/수정 해서 버튼 한 번만 눌러주면 되었으니까요.
약 500여개의 테스트 케이스에 대해, 9초면 확인을 할 수 있었고, 이것을 반복적으로 실행할 수 있었습니다.
여기서 테스트환경이 아닌 실제 Production / Stage에서 사용할 수 있는 케이스들을 걸러내서, CI flow와 연계해서 해당 기능이 배포될때마다 테스트를 실행시켜줄 수도 있게 되었습니다.
이것은 UI 테스트 자동화 코드도 마찬가지입니다만, 유지보수 측면에서 효율이 크게 다가왔습니다. UI가 바뀌어도 API는 그대로 사용하는 경우도 많이 있기 때문에, 유지보수성이 훨씬 좋은 것이죠. UI 테스트 자동화 코드라면, UI가 바뀐다면 거의 처음부터 새로 만들어야할 것입니다.
API 테스트를 하려면, 응답값에 포함된 필드들을 확인하고 assertion을 수행하는 스크립트를 작성해야합니다.
빠른 개발을 위해 일단 백엔드 개발자가 mockup response를 문서와 함께 만들어서 프론트엔드 개발자에게 공유를 해주는데요, 저도 이 목업을 보고 스크립트를 작성했습니다.
문제는
등으로 인해 response구조들이 빈번하게 자주 바뀌다보니, 그만큼 스크립트도 빈번하게 수정을 해주어야해서 생각보다 스크립트 작성 및 수정에 공수가 많이 들었습니다.
특히나, 이번 API테스트에서는 Postman을 사용하였는데, postman에서는 어떤 동일한 검증을 하는 스크립트에 대해서도, 다른 리퀘스트들과 공유가 안되다보니, 예를 들어 100개의 리퀘스트를 작성했다고 가정하면, 그 중 1개의 assertion 스크립트가 수정된다고하면 100개 전부 수정해야하는 경우가 발생할 수 있던 것입니다..😇
이번 테스트에서는 스크립트 작성을 안건 초기에 목업과 함께 시작하였는데요, 위와 같은 이슈때문에 스크립트를 작성하는 타이밍을 개발완료 직전에 진행해야지만 좀 더 수월하게 할 수 있겠다~ 라고 생각했습니다.
기존의 테스트는 아무래도 인터렉션이 가능한, GUI가 있는 어플리케이션에 대해서 테스트를 진행했었는데요, API 테스트는 눈에 보이는 것이 없기 때문에 (없다라기보단 json형태의 텍스트들...) 테스트하기에 난이도가 조금 있었습니다.
특히 assertion으로 체크하지 못한, 누락되는 부분을 확인하기 위해 애드혹 테스트를 진행하게 되면, 눈으로 보이는 부분이 없다보니 테스트 수행 시의 집중도도 떨어지게 되어서 테스트를 수행할 때 꽤나 어려움이 있었습니다.
(호기심으로 인해 가능한 업무 몰입이 쉽지 않았습니다..)
API가 다 개발이 완료된 상태에서 진행하는 것이 아니라, 후반이긴 하지만 개발중인 상태에서 진행을 하였는데요, 그럼에도 불구하고 제품 릴리즈 속도가 빨라졌냐하면 약간 갸우뚱🧐 하는 느낌입니다.
API테스트를 수행한 후에, 다시 UI테스트를 수행하였는데요, UI테스트는 UI테스트만의 테스트 플랜에 따라, 테스트 수행기간을 정합니다. API테스트를 수행완료했다고 해서 UI테스트 기간을 짧게 가져가도 되느냐? 에 대해서는 물음표가 떠오를 수 밖에 없는거죠.
물론, 기존에 존재하던 기능 API에 대해서 테스트를 한다면, 굳이 UI테스트를 수행하지 않고 릴리즈하면 조금은 빨라질 수도 있겠지만, (최소한의 UI동작만 확인) 신규 기능이라면 UI는 UI대로 테스트를 해야하기 때문에, 릴리즈속도를 단축시킬 수는 없는 것입니다.
하물며 신규기능이라 사용성 및 디자인도 확인해야하는 것이죠.
게다가 위에도 말씀드렸지만, UI테스트를 하면서도 API의 수정사항이 발생하기도 했으니..
API테스트를 수행하면서, 이번에는 포스트맨을 사용했습니다. 아무래도 json파일을 표현할때에 응답값에 대한 folding & expanding 처리를 지원해주다보니 테스트를 하면서 응답값을 직접 확인하기가 편했습니다.
뭔가 파이썬이나 자바를 이용해서 직접 API 테스트 코드를 작성했다면, 물론 공통체크 로직을 수정한다거나, 유지보수하기에는 좀 더 편했겠지만 응답값을 좀 더 편하게 확인할 수가 없어서 애드혹테스트를 하기에는 조금 부적절하지 않았을까 싶습니다.
안건 2개를 진행하면서, API테스트를 수행하였어도, UI테스트를 진행하면, 생각지도 못한 입력값이나 혹은 동작들로 인해서 API의 수정이 발생하였습니다.
그러면 왜 굳이 API 테스트를 진행했나 라고 현타가 오기도 했습니다.
사실 안건들에서의 API 테스트는, UI테스트 수행하고 나서 돌아보니 많은 시나리오가 누락이 되어있었고, 시나리오 리뷰어들도 누락한 상황이라, API테스트 후에도 적지않은 수정사항이 나왔습니다.
근데 사실, API테스트를 진행함으로 인해서, UI 테스트만 해서는 못찾아낼 수도 있었던 이슈들을 찾아내기도 했으니까.. 품질이 올라간거라며 만족...해보기도 합니다.
2개 안건에서 시범적으로 진행하긴 했지만, 여러가지 효과를 느낄 수 있었고, 또 안좋은 점이라던지 개선해야할 점들도 있었습니다. 쉽게 끝날 줄 알았던 API 테스트도, 사실은 유저시나리오에서 챙겨야할 부분들을 많이 놓쳤기 때문 에 UI테스트를 진행하면서도 많은 수정사항이 발생하였어서, 다음에 진행할때에는 시나리오를 좀 더 잘 구상하고, 리뷰프로세스도 어떻게하면 더 강화할 수 있을지를 궁리하게 되었습니다.
이런것들을 잘 빌드업해서 사내에서 하나의 테스트 프로세스로 만들어보고 싶다는 생각도 들기도 했습니다.
후기 끝!
ref
정말 정말 잘 읽고 갑니다!