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줄 요약 계약 테스트를 이번 분기에 넣어야 하는가 — 같은 주에 나온 일간 QA 리포트 4건이 서로 다르게 답했습니다. 9월 18일자는 "MSA 전환 후 2단계 과제로 보류 권장", 9월 21일자는 "1순위 도입"이었고, 나흘 사이에 움직인 칸은 도구 평가가 아니라 유지보수 비용 한 칸이었습니다. 이 답이 뒤집히는 조건으로 두 건이 함께 든 숫자는 서비스 경계 3개입니다. 19일자는 "3개 이상 분리 시 ROI 최상"이라는 도입 조건으로, 20일자는 "3개 이상 + 팀 간 배포 독립성 문제"라는 재검토 조건으로 각각 다르게 적었습니다.
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초였습니다.
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초로 붙습니다.
3줄 요약 AI 테스트 에이전트를 붙이면 자동화 커버리지가 오른다는 말은 이번 주 리포트에서도 반복됐습니다. 다만 Wopee.io가 에이전트 5종을 비교한 조사에서 커버리지는 과거 상한이던 약 25%에서 51~60%로 올랐는데, 같은 조사의 완전 자율 자동화 만족도는 5점 만점에 2.2점이었고 무감독 운영을 실제로 지원하는 도구는 5종 중 하나도 없었습니다. 그러니 에이전트를 검토할 때 볼 값은 "자동화율이 몇 퍼센트까지 오르는가"가 아니라 "사람 검토 게이트가 주당 몇 건을 받아 내는가"입니다.
3줄 요약 합성 스위트(테스트 200개)에서 맵을 만드는 값은 전체 실행 대비 +19.7%이고, 잎 모듈 하나를 고쳤을 때 남는 실행은 25.1%입니다. 같은 맵이 conftest 변경·데이터 파일 변경·새 테스트 파일·아무 테스트도 안 닿은 파일 네 자리에서 0개 를 고릅니다. 데이터 파일 한 줄을 바꾼 경우 실제로는 40개가 깨졌는데 맵은 "돌릴 것 없음"을 냈습니다. 맵에 없는 경로가 변경 목록에 하나라도 섞이면 전체 실행으로 되돌리는 20줄짜리 가드를 먼저 붙이고, 그다음에 선택 실행을 1차 피드백 자리에만 두는 순서입니다.
3줄 요약 테스트마다 붙여 둔 Issue: QA-1042 태그를 7.5의 [Metadata] 로 옮겨도 되는지가 이 글의 질문입니다. 옮기면 태그 통계 표가 557행에서 0행으로 줄지만, --include 필터와 파일 단위 일괄 지정과 --tagstatlink 이슈 링크를 함께 잃습니다. 다만 이 판단보다 먼저 확인할 것이 있습니다. 리포트를 만드는 rebot 이 7.4.2 이하면 exit 252로 멈추고 파일을 한 개도 남기지 않습니다.
3줄 요약 예제 기반 테스트 12개가 모두 통과하고 coverage.py 분기 커버리지가 100%인 모듈에 속성 기반 테스트 4개를 붙였더니 3개가 즉시 반례를 냈습니다. 반례 탐지에 필요한 max_examples 는 25면 충분했고(세 속성 모두 시드 30개 중 30개 탐지), 비용은 속성 4개 기준 0.311초로 예제 12개의 0.132초 대비 0.179초 증가였습니다. 오늘 붙일 계획이라면 속성을 늘리기 전에 CI 환경변수가 있을 때 기본값 다섯 개가 한꺼번에 바뀐다는 것부터 확인하시면 됩니다.
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 으로 예외 처리하시면 됩니다.
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 부터 정해 두시면 됩니다.
3줄 요약 pytest-randomly 5.0.0이 pytest_collection_modifyitems 를 평범한 tryfirst 에서 훅 래퍼로 바꿔, 다른 플러그인보다 항상 먼저 셔플하도록 만들었습니다. 그룹 정렬 플러그인이 없으면 같은 시드가 4.1.0과 똑같은 순서를 냅니다. 있으면 40칸이 전부 달라지고, 그룹 경계를 넘는 순서 의존성 탐지율이 시드 60개 기준 56.7%에서 0%로 떨어졌습니다. 정렬 플러그인을 함께 쓰신다면 셔플 잡을 -p no:그룹플러그인 조합으로 따로 하나 더 돌리시면 됩니다.
3줄 요약 줄 커버리지 100%, 테스트 11개 전부 통과인 모듈에 mutmut 3.7.0을 걸었더니 뮤턴트 99개 중 35개가 살아남았습니다. 뮤테이션 스코어 64.6%입니다. 어서션을 정확한 값으로 바꾸는 네 라운드로 98.0%까지 올렸고, 그 과정에서 무료배송 경계값과 등급 문자열 오타를 조용히 통과시키는 설계 결함을 찾았습니다. 커버리지 지표를 뮤테이션으로 바꾸지 말고, 결제·정산처럼 금액을 계산하는 모듈 하나에만 걸어 mutmut export-cicd-stats 로 생존 수를 세어 보시면 됩니다.
3줄 요약 같은 이름의 테스트 파일이 두 개 생기면 그 파일만 실패하는 것이 아니라 수집 자체가 중단됩니다. pytest 9.1.1로 재현하니 파일 3개에 오류 2건, exit 2, 실행된 테스트 0건이었습니다. 처방은 __init__.py 와 --import-mode=importlib 두 가지이고 수집 시간 차이는 없었습니다(테스트 300개 기준 0.03초 대 0.04초). 갈리는 지점은 테스트 디렉터리 안에 헬퍼 모듈을 두고 있는지입니다. 지금 저장소에서 중복 파일명 탐지 스크립트를 한 번 돌려 보시면 됩니다. 아직 안 터졌더라도 파일 하나만 더 추가되면 그날 CI가 멈춥니다.
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초짜리 관문부터 만드시면 됩니다
3줄 요약 테스트를 잡으로 쪼개면 파이프라인이 빨라지지만, 어느 지점부터는 벽시계가 거의 안 줄고 청구 분만 늘어납니다. 200개·232초짜리 스위트를 실측한 결과 잡 4개에서 벽시계 120초, 8개에서 90초였고 청구는 8분에서 16분으로 정확히 2배였습니다. 잡 고정비를 60초로 잡았을 때입니다. 잡 수 상한을 전체 테스트 시간 ÷ 잡 고정비 로 먼저 계산하시고, 그 값을 넘기지 않는 선에서 --splitting-algorithm least_duration 을 붙이시면 됩니다.