Skip to content

test: 런타임 테스트를 XCTest 에서 swift-testing 으로 마이그레이션#26

Open
DevVenusK wants to merge 1 commit into
daangn:mainfrom
DevVenusK:test/migrate-to-swift-testing
Open

test: 런타임 테스트를 XCTest 에서 swift-testing 으로 마이그레이션#26
DevVenusK wants to merge 1 commit into
daangn:mainfrom
DevVenusK:test/migrate-to-swift-testing

Conversation

@DevVenusK

Copy link
Copy Markdown

배경

테스트 스위트가 두 프레임워크로 나뉘어 있었습니다: XCTest 42개 + swift-testing 26개. 진행 중이던 이관을 마무리해 런타임 테스트가 단일 프레임워크(swift-testing)를 쓰도록 통일합니다.

이전 · 총 68 파일                              이후 · 총 68 파일
┌───────────────────────────┐                 ┌───────────────────────────┐
│ XCTest         42          │ ──30 파일 이관─▶ │ swift-testing   56         │
│ swift-testing  26          │ ───────────────▶ │ XCTest          12         │ (매크로 확장 전용)
└───────────────────────────┘                 └───────────────────────────┘
                               └12 파일 유지─────▶ (assertMacroExpansion)

변경사항

순수 런타임 XCTest 30개 파일을 swift-testing 으로 이관합니다. 매크로 확장 테스트 12개SwiftSyntaxMacrosTestSupport.assertMacroExpansion 이 XCTest 기반이라 의도적으로 유지합니다.

변환 규칙(1:1):

XCTest swift-testing
import XCTest import Testing (+ 필요 시 import Foundation)
final class X: XCTestCase { struct X {
func testFoo() @Test func testFoo()
XCTAssertEqual(a, b) #expect(a == b)
XCTAssertEqual(a, b, accuracy: t) #expect(abs(a - b) < t)
XCTAssertNil(a) / XCTAssertTrue(a) #expect(a == nil) / #expect(a)
XCTAssertThrowsError(try f()) #expect(throws: (any Error).self) { try f() }
try XCTUnwrap(x) try #require(x)
XCTFail("msg") Issue.record("msg")

실제 변환 예시:

// before
import XCTest
import KarrotCodableKit

final class DefaultTrueTests: XCTestCase {
  func testDecodingKeyNotPresentDefaultsToTrue() throws {
    let jsonData = #"{}"#.data(using: .utf8)!
    let fixture = try JSONDecoder().decode(Fixture.self, from: jsonData)
    XCTAssertEqual(fixture.truthy, true)
  }
}
// after
import Testing
import Foundation
import KarrotCodableKit

struct DefaultTrueTests {
  @Test func testDecodingKeyNotPresentDefaultsToTrue() throws {
    let jsonData = #"{}"#.data(using: .utf8)!
    let fixture = try JSONDecoder().decode(Fixture.self, from: jsonData)
    #expect(fixture.truthy == true)
  }
}

import Foundation 은 XCTest 가 암묵 재노출하던 Data/JSONDecoder 를 위해 필요한 파일에만 명시적으로 추가했습니다.

변경 파일 (30개, 그룹별)

  • AnyCodable(3): AnyCodableTests, AnyDecodableTests, AnyEncodableTests
  • BetterCodable/Defaults(9): DefaulEmptyDictionaryTests, DefaultCodableTests, DefaultEmptyArrayTests, DefaultEmptyStringTests, DefaultFalseTests, DefaultTrueTests, DefaultZeroDoubleTests, DefaultZeroFloatTests, DefaultZeroIntTests
  • BetterCodable/LosslessValue(3): LosslessArrayTests, LosslessCustomValueTests, LosslessValueTests
  • BetterCodable/LossyValue(3): LossyArrayTests, LossyDictionaryTests, LossyOptionalTests
  • BetterCodable/DateValue·DataValue(3): DateValueTests, OptionalDateValueTests, DataValueTests
  • PolymorphicCodable(6): DefaultEmptyPolymorphicArrayValueTests, PolymorphicLossyArrayValueTests, PolymorphicEnumCodableTests, PolymorphicEnumDecodableTests, LossyOptionalPolymorphicValueTests, PolymorphicValueTests
  • 기타(3): RawRepresentableTests, Encodable+ToDictionaryTests, StringSnakeCaseTests

30 files changed, +475 / −454

변경했을 때의 트레이드 오프

  • 대형 단일 PR(30 파일) → 리뷰 부담은 크지만 프레임워크 통일 이득이 큽니다. (서브시스템별 분할 커밋도 가능하나 기계적 변환이라 단일 커밋으로 진행)
  • 완전 단일화는 아닙니다 — 매크로 확장 테스트 12개는 XCTest 로 남습니다(assertMacroExpansion 제약). 추후 SwiftSyntaxMacrosGenericTestSupport 로의 이관은 별건 후속 과제.
  • test 접두사 유지 — swift-testing 은 접두사가 불필요하지만, diff/네이밍 변경 리스크를 줄이기 위해 이름은 그대로 두고 @Test 만 부착했습니다.
  • 부동소수 비교accuracy: 가 swift-testing 에 없어 #expect(abs(a - b) < t) 로 옮겼습니다 — 허용 오차 의미를 보존합니다.

테스트 방법

  • swift test -c debug / swift test -c release — 전부 통과(실패 0).
  • 전체 테스트 수 360개로 보존: 기준 166 swift-testing + 194 XCTest → 286 swift-testing + 74 XCTest. 유실 0.
  • 이관 후 import XCTest 잔존 파일은 정확히 12개이며 전부 assertMacroExpansion 사용(매크로 확장 스위트)임을 확인.

기타

  • 기계적·동작 보존 마이그레이션이라 각 테스트의 assertion 의미는 그대로입니다.
  • 파일명 오타(DefaulEmptyDictionaryTests, 디렉터리 Extenstions/)는 범위를 넘지 않도록 이 PR 에서 건드리지 않았습니다(별건).

순수 런타임 테스트 30개 파일을 swift-testing 으로 이관한다
(#expect/#require, @test, struct suite). 매크로 확장 테스트 12개 파일은
SwiftSyntaxMacrosTestSupport 의 assertMacroExpansion 이 XCTest 기반이므로 유지한다.

전체 테스트 수는 360개로 동일하며(유실 없음), XCTest 는 이제 매크로 확장 스위트만 담당한다.
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@DevVenusK, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 59 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 21cc6c9a-229d-4c08-b1d3-1001aa47ad63

📥 Commits

Reviewing files that changed from the base of the PR and between 088c813 and 2f2385c.

📒 Files selected for processing (30)
  • Tests/KarrotCodableKitTests/AnyCodable/AnyCodableTests.swift
  • Tests/KarrotCodableKitTests/AnyCodable/AnyDecodableTests.swift
  • Tests/KarrotCodableKitTests/AnyCodable/AnyEncodableTests.swift
  • Tests/KarrotCodableKitTests/BetterCodable/DataValue/DataValueTests.swift
  • Tests/KarrotCodableKitTests/BetterCodable/DateValue/DateValueTests.swift
  • Tests/KarrotCodableKitTests/BetterCodable/DateValue/OptionalDateValueTests.swift
  • Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaulEmptyDictionaryTests.swift
  • Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultCodableTests.swift
  • Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultEmptyArrayTests.swift
  • Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultEmptyStringTests.swift
  • Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultFalseTests.swift
  • Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultTrueTests.swift
  • Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultZeroDoubleTests.swift
  • Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultZeroFloatTests.swift
  • Tests/KarrotCodableKitTests/BetterCodable/Defaults/DefaultZeroIntTests.swift
  • Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessArrayTests.swift
  • Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessCustomValueTests.swift
  • Tests/KarrotCodableKitTests/BetterCodable/LosslessValue/LosslessValueTests.swift
  • Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyArrayTests.swift
  • Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyDictionaryTests.swift
  • Tests/KarrotCodableKitTests/BetterCodable/LossyValue/LossyOptionalTests.swift
  • Tests/KarrotCodableKitTests/BetterCodable/RawRepresentableTests.swift
  • Tests/KarrotCodableKitTests/Encodable+ToDictionaryTests.swift
  • Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/DefaultEmptyPolymorphicArrayValueTests.swift
  • Tests/KarrotCodableKitTests/PolymorphicCodable/ArrayValue/PolymorphicLossyArrayValueTests.swift
  • Tests/KarrotCodableKitTests/PolymorphicCodable/Enum/PolymorphicEnumCodableTests.swift
  • Tests/KarrotCodableKitTests/PolymorphicCodable/Enum/PolymorphicEnumDecodableTests.swift
  • Tests/KarrotCodableKitTests/PolymorphicCodable/OptionalValue/LossyOptionalPolymorphicValueTests.swift
  • Tests/KarrotCodableKitTests/PolymorphicCodable/Value/PolymorphicValueTests.swift
  • Tests/KarrotCodableMacrosTests/Extenstions/StringSnakeCaseTests.swift
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants