글

라벨이 테스트자동화인 게시물 표시

셀레니움 암시적 대기와 명시적 대기를 같이 쓰면 몇 초 걸릴까?

이미지
3줄 요약 암시적과 명시적 대기를 섞으면 대기 시간은 어떻게 될까요? 암시적 대기가 길면 명시적 5초 제한이 소용없습니다. 사라짐을 기다리는 대기는 암시적 값만큼 늘어나니 0으로 내립니다.

MCP 서버 만들기, 파이썬으로 테스트 실패만 읽어 주는 도구 붙이기

이미지
3줄 요약 튜토리얼의 FastMCP 코드는 mcp 2.3.0에서 import부터 막힙니다. MCPServer로 바꾸고 stdio로 부르면 도구 하나가 바로 돌아갑니다. 서버 쪽 print 한 줄이 연결을 끊으니 로그는 stderr로 보냅니다. pip install mcp 를 하고 FastMCP 를 쓰는 튜토리얼 코드를 돌려 봤더니 import 줄에서 바로 멈췄습니다. 한국어 튜토리얼 중에는 위키독스 「나만의 MCP 서버 만들기」 처럼 이 이름을 쓰는 글이 있습니다. 에러 문구에 원인이 그대로 적혀 있었는데요, 2.x부터 FastMCP 가 MCPServer 로 이름이 바뀌었다는 내용입니다. 새 이름으로 서버를 만들고 도구를 하나 붙여 호출까지 해 봤습니다. 도구는 JUnit 결과 파일에서 실패한 테스트만 골라 줍니다. 실행은 Linux 컨테이너(Python 3.13.16)에서 했고, 예제 결과 파일은 테스트 5개짜리로 제가 직접 만들었습니다. Claude Code에 붙이는 마지막 부분은 직접 돌리지 않고 공식 문서의 명령을 옮겼습니다. pip install mcp 다음에 만나는 에러 설치된 버전부터 봅니다 PyPI의 mcp 최신 버전은 2.3.0이고, 한국 시간 10월 3일 오전 7시에 올라왔습니다. 가상환경을 새로 만들어 설치하면 이 버전을 받게 됩니다. # 가상환경을 만들고 mcp 를 설치합니다 python3 -m venv v && . v/bin/activate pip install mcp pip list | grep -E '^mcp ' # mcp 2.3.0 옛 튜토리얼의 import는 에러가 납니다 1.x 시절 코드는 from mcp.server.fastmcp import FastMCP 로 시작합니다. 2.3.0에서 이 줄을 실행하면 아래 에러가 나옵니다. ModuleNotFoundError: No module named 'mcp.server.fastmcp'. This is m...

회귀 테스트를 바뀐 코드에만 돌리면 무엇을 놓칠까?

이미지
3줄 요약 동작이 바뀌는 코드를 고치면 테스트 3~28개만 다시 돕니다. JSON 설정을 바꾸면 0개를 골라 실패 2건을 놓칩니다. 설정 파일은 env 옵션에 넣고 야간에 전체를 돌립니다.

AI가 쓴 코드, 테스트 통과율만 믿어도 될까?

이미지
3줄 요약 테스트 통과율이 높아도 릴리스가 안전하다는 보장은 없습니다. 통과율 94.2%에서 40만 달러가 환불됐다는 발표 사례가 있었습니다. 통과율 옆에 결함 유출률과 미검증 비율을 같이 적으십시오.

flaky test 관리법, 재시도를 측정 도구로 바꾸는 순서

이미지
3줄 요약 플래키는 재시도 설정으로 정리되는 작은 문제로 여기기 쉽습니다. Bitrise 집계로 플래키를 겪는 팀은 10%에서 26%로 늘었습니다. 재시도는 측정에만 쓰고 집계와 격리 레인부터 두십시오.

버그리포트 작성 예시, 개발자가 다시 묻지 않게 쓰는 법

이미지
3줄 요약 개발자가 리포트를 보고 되묻는 이유는 대개 재현이 안 돼서입니다 재현 절차와 기대·실제 결과, 버전만 제대로 써도 되묻는 일이 줄어듭니다 가끔만 재현되는 버그라면 절차와 함께 빈도와 조건을 꼭 적어야 합니다

Pact contract testing, 계약 테스트 도입 판단 기준

이미지
3줄 요약 계약 테스트를 이번 분기에 넣어야 하는가 — 같은 주에 나온 일간 QA 리포트 4건이 서로 다르게 답했습니다. 9월 18일자는 "MSA 전환 후 2단계 과제로 보류 권장", 9월 21일자는 "1순위 도입"이었고, 나흘 사이에 움직인 칸은 도구 평가가 아니라 유지보수 비용 한 칸이었습니다. 이 답이 뒤집히는 조건으로 두 건이 함께 든 숫자는 서비스 경계 3개입니다. 19일자는 "3개 이상 분리 시 ROI 최상"이라는 도입 조건으로, 20일자는 "3개 이상 + 팀 간 배포 독립성 문제"라는 재검토 조건으로 각각 다르게 적었습니다.

pytest snapshot 테스트 syrupy, 병렬 실행 주의점

이미지
3줄 요약 스냅샷을 처음 만들 때도 -n auto 를 붙여 시간을 아끼는 것이 습관이 돼 있었습니다. syrupy 6.1.1과 pytest-xdist 3.8.0 조합에서 20개를 만들면 4워커는 15~16개, 8워커는 최악 2개만 파일에 남았습니다. 그런데 화면에는 20 snapshots generated 가 찍히고 종료 코드는 0이었습니다. 6.1.1에 새로 들어온 --snapshot-file-lock 을 붙이면 10회 실행에서 전부 20개가 남았고, 8워커 기준 실행 시간 차이는 0.001초였습니다.

pytest caplog not capturing logs 해결법

이미지
3줄 요약 pytest 9.1.0(2026-06-13 릴리스)부터 caplog 가 propagate=False 로거에도 핸들러를 직접 답니다. 그동안 캡처를 포기하고 우회책을 넣어 둔 스위트가 영향을 받습니다. monkeypatch.setattr(log, "propagate", True) 우회책을 쓰던 테스트는 같은 로그 한 줄에서 레코드가 1개에서 2개로 늘었고, 같은 스위트의 --log-file 출력은 0줄에서 10줄(440B)이 됐습니다. 업그레이드 전에 propagate 를 손대는 자리부터 찾아 지우십시오. 로거 5,000개 환경에서는 스캔 비용도 300테스트당 0.16초에서 0.53초로 붙습니다.

AI 테스트 자동화 솔루션 비교, 에이전트 5종의 한계

이미지
3줄 요약 AI 테스트 에이전트를 붙이면 자동화 커버리지가 오른다는 말은 이번 주 리포트에서도 반복됐습니다. 다만 Wopee.io가 에이전트 5종을 비교한 조사에서 커버리지는 과거 상한이던 약 25%에서 51~60%로 올랐는데, 같은 조사의 완전 자율 자동화 만족도는 5점 만점에 2.2점이었고 무감독 운영을 실제로 지원하는 도구는 5종 중 하나도 없었습니다. 그러니 에이전트를 검토할 때 볼 값은 "자동화율이 몇 퍼센트까지 오르는가"가 아니라 "사람 검토 게이트가 주당 몇 건을 받아 내는가"입니다.

Test Impact Analysis, 변경분만 테스트할 때 놓치는 것

이미지
3줄 요약 합성 스위트(테스트 200개)에서 맵을 만드는 값은 전체 실행 대비 +19.7%이고, 잎 모듈 하나를 고쳤을 때 남는 실행은 25.1%입니다. 같은 맵이 conftest 변경·데이터 파일 변경·새 테스트 파일·아무 테스트도 안 닿은 파일 네 자리에서 0개 를 고릅니다. 데이터 파일 한 줄을 바꾼 경우 실제로는 40개가 깨졌는데 맵은 "돌릴 것 없음"을 냈습니다. 맵에 없는 경로가 변경 목록에 하나라도 섞이면 전체 실행으로 되돌리는 20줄짜리 가드를 먼저 붙이고, 그다음에 선택 실행을 1차 피드백 자리에만 두는 순서입니다.

Robot Framework tags와 테스트 메타데이터 차이

이미지
3줄 요약 테스트마다 붙여 둔 Issue: QA-1042 태그를 7.5의 [Metadata] 로 옮겨도 되는지가 이 글의 질문입니다. 옮기면 태그 통계 표가 557행에서 0행으로 줄지만, --include 필터와 파일 단위 일괄 지정과 --tagstatlink 이슈 링크를 함께 잃습니다. 다만 이 판단보다 먼저 확인할 것이 있습니다. 리포트를 만드는 rebot 이 7.4.2 이하면 exit 252로 멈추고 파일을 한 개도 남기지 않습니다.

python hypothesis 사용법, 속성 기반 테스트로 찾은 반례

이미지
3줄 요약 예제 기반 테스트 12개가 모두 통과하고 coverage.py 분기 커버리지가 100%인 모듈에 속성 기반 테스트 4개를 붙였더니 3개가 즉시 반례를 냈습니다. 반례 탐지에 필요한 max_examples 는 25면 충분했고(세 속성 모두 시드 30개 중 30개 탐지), 비용은 속성 4개 기준 0.311초로 예제 12개의 0.132초 대비 0.179초 증가였습니다. 오늘 붙일 계획이라면 속성을 늘리기 전에 CI 환경변수가 있을 때 기본값 다섯 개가 한꺼번에 바뀐다는 것부터 확인하시면 됩니다.

pytest timeout, signal과 thread 방식 차이 정리

이미지
3줄 요약 멈춘 테스트를 끊는 방법은 pytest-timeout의 signal · thread 와 pytest 내장 faulthandler 세 갈래인데, pytest-timeout 공식 문서는 thread를 "가장 확실한 방법"이라고 적고 있습니다. 행 11종을 상한 2초로 돌려 보니 signal 9/11, thread 10/11, faulthandler(exit=true) 11/11이었고 signal과 thread가 놓친 항목이 하나도 겹치지 않았습니다. 정규식 백트래킹은 thread만 놓쳤고, SIGALRM을 건드린 테스트는 signal만 놓쳤습니다. xdist로 병렬 실행 중이면 thread , 단일 프로세스면 signal 을 기본값으로 두고 느린 테스트만 @pytest.mark.timeout 으로 예외 처리하시면 됩니다.

freezegun vs time-machine, 시간대 주의점

이미지
3줄 요약 두 라이브러리는 고정하는 함수 목록이 다릅니다. freezegun은 time.monotonic() 까지 멈추고, time-machine은 그것만 실제 시각으로 남깁니다. 같은 datetime(2026, 3, 1, 12, 0) 을 넣어도 datetime.now() 가 12:00과 21:00으로 갈립니다. 진입·해제 비용은 923.63us 대 8.52us로 108.4배 차이입니다. 옮길 계획이 있다면 python -m time_machine migrate 를 돌리기 전에 conftest에 naive_mode 부터 정해 두시면 됩니다.

pytest 실행 순서 섞기, pytest-randomly 변경점 정리

이미지
3줄 요약 pytest-randomly 5.0.0이 pytest_collection_modifyitems 를 평범한 tryfirst 에서 훅 래퍼로 바꿔, 다른 플러그인보다 항상 먼저 셔플하도록 만들었습니다. 그룹 정렬 플러그인이 없으면 같은 시드가 4.1.0과 똑같은 순서를 냅니다. 있으면 40칸이 전부 달라지고, 그룹 경계를 넘는 순서 의존성 탐지율이 시드 60개 기준 56.7%에서 0%로 떨어졌습니다. 정렬 플러그인을 함께 쓰신다면 셔플 잡을 -p no:그룹플러그인 조합으로 따로 하나 더 돌리시면 됩니다.

뮤테이션 테스트 입문, 커버리지 100% 코드의 빈틈 찾기

이미지
3줄 요약 줄 커버리지 100%, 테스트 11개 전부 통과인 모듈에 mutmut 3.7.0을 걸었더니 뮤턴트 99개 중 35개가 살아남았습니다. 뮤테이션 스코어 64.6%입니다. 어서션을 정확한 값으로 바꾸는 네 라운드로 98.0%까지 올렸고, 그 과정에서 무료배송 경계값과 등급 문자열 오타를 조용히 통과시키는 설계 결함을 찾았습니다. 커버리지 지표를 뮤테이션으로 바꾸지 말고, 결제·정산처럼 금액을 계산하는 모듈 하나에만 걸어 mutmut export-cicd-stats 로 생존 수를 세어 보시면 됩니다.

pytest import error, file mismatch 해결법

이미지
3줄 요약 같은 이름의 테스트 파일이 두 개 생기면 그 파일만 실패하는 것이 아니라 수집 자체가 중단됩니다. pytest 9.1.1로 재현하니 파일 3개에 오류 2건, exit 2, 실행된 테스트 0건이었습니다. 처방은 __init__.py 와 --import-mode=importlib 두 가지이고 수집 시간 차이는 없었습니다(테스트 300개 기준 0.03초 대 0.04초). 갈리는 지점은 테스트 디렉터리 안에 헬퍼 모듈을 두고 있는지입니다. 지금 저장소에서 중복 파일명 탐지 스크립트를 한 번 돌려 보시면 됩니다. 아직 안 터졌더라도 파일 하나만 더 추가되면 그날 CI가 멈춥니다.

Schemathesis 첫 실행, 실패 결과 분류하는 법

이미지
3줄 요약 오퍼레이션 5개짜리 API에 Schemathesis 4.25.2를 처음 돌리니 2.5초 만에 667건을 만들어 실패 10건을 냈고, 그중 서버가 실제로 죽은 것은 2건이었습니다 나머지 8건은 코드가 아니라 스펙이 현실을 못 따라간 것이었고, 스펙을 정확하게 고치자 실패는 10건에서 3건으로 줄었지만 실행 시간은 2.5초에서 5.9초로 늘었습니다 처음 붙이신다면 --generation-deterministic 을 켜고 --phases coverage,fuzzing 으로 0.8초짜리 관문부터 만드시면 됩니다

pytest 병렬 실행, pytest-split 잡 개수 정하는 법

이미지
3줄 요약 테스트를 잡으로 쪼개면 파이프라인이 빨라지지만, 어느 지점부터는 벽시계가 거의 안 줄고 청구 분만 늘어납니다. 200개·232초짜리 스위트를 실측한 결과 잡 4개에서 벽시계 120초, 8개에서 90초였고 청구는 8분에서 16분으로 정확히 2배였습니다. 잡 고정비를 60초로 잡았을 때입니다. 잡 수 상한을 전체 테스트 시간 ÷ 잡 고정비 로 먼저 계산하시고, 그 값을 넘기지 않는 선에서 --splitting-algorithm least_duration 을 붙이시면 됩니다.