You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XCTest:如何禁用抽象基类的测试执行

问题描述

我的测试目标包含以下类:

class AbstractBaseClass: XCTestCase {
    var sut: SystemInterface!

    func test1(){}
    func test2(){}
    func test3(){}
}

另外还有两个子类:

final class TestSystem1: AbstractBaseClass {
    override func setUp() {
        super.setUp()
        sut = System1()
    }
}
final class TestSystem2: AbstractBaseClass {
    override func setUp() {
        super.setUp()
        sut = System2()
    }
}

我希望让System1和System2共享同一套测试逻辑,但不想让AbstractBaseClass本身的测试套件被执行。目前子类的测试运行正常,但AbstractBaseClass的测试会因为sut为nil而报错,请问有什么解决办法?


解决方法

方法1:标记基类为不可实例化,阻止XCTest识别它为测试类

给基类添加@available标记,明确它仅用于继承,不能直接实例化,这样XCTest就会自动忽略这个类的测试:

@available(*, unavailable, message: "仅作为测试基类使用,禁止直接实例化")
class AbstractBaseClass: XCTestCase {
    var sut: SystemInterface!

    func test1(){}
    func test2(){}
    func test3(){}
}

方法2:在基类测试方法中跳过自身实例的执行

如果不想修改基类的可用性标记,可以在每个测试方法开头添加判断,若当前实例是基类本身则直接跳过:

class AbstractBaseClass: XCTestCase {
    var sut: SystemInterface!

    func test1(){
        guard type(of: self) != AbstractBaseClass.self else { return }
        // 原有测试逻辑
    }

    func test2(){
        guard type(of: self) != AbstractBaseClass.self else { return }
        // 原有测试逻辑
    }

    func test3(){
        guard type(of: self) != AbstractBaseClass.self else { return }
        // 原有测试逻辑
    }
}

方法3:改用协议+扩展共享测试逻辑

把测试逻辑抽离到协议扩展中,让子类直接继承XCTestCase并实现协议,彻底避免基类作为测试类被执行:

// 定义协议,要求实现sut属性
protocol SystemTestable {
    var sut: SystemInterface! { get set }
}

// 协议扩展中实现共享测试逻辑
extension SystemTestable where Self: XCTestCase {
    func test1(){
        // 原有测试逻辑
    }

    func test2(){
        // 原有测试逻辑
    }

    func test3(){
        // 原有测试逻辑
    }
}

// 子类实现协议并初始化sut
final class TestSystem1: XCTestCase, SystemTestable {
    var sut: SystemInterface!

    override func setUp() {
        super.setUp()
        sut = System1()
    }
}

final class TestSystem2: XCTestCase, SystemTestable {
    var sut: SystemInterface!

    override func setUp() {
        super.setUp()
        sut = System2()
    }
}

内容的提问来源于stack exchange,提问作者Richard Topchii

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 08:23:20