美文网首页
ios技巧 -- 单元测试

ios技巧 -- 单元测试

作者: Mjs | 来源:发表于2021-03-21 17:24 被阅读0次

    单元测试:是检查是否每个代码单元(例如类或函数)是否能产⽣预期
    的结果。
    单元测试是独⽴运⾏的,不依赖于其他模块或组件。

    FIRST

    1. Fast:测试模块应该是快速⾼效的;
    2. Independent/Isolated:测试模块应该是独⽴相互不影响的;
    3. Repeatable :测试实例应该是可以重复使⽤的,测试结果应该是相同的;
    4. Self-validating:测试应完全⾃动化。输出结果要么是“成功”,要么是“失败”;
    5. Timely:理想情况下,应该在编写要测试的⽣产代码之前编写测试(测试驱动开发)。

    单元测试需要启动APP。所以每次都会进行加载,产生耗时操作,所以这个时候就需要在测试的启动自己的FakeAppDelegate
    这个时候我们可以从main函数中进行调试

    int main(int argc, char * argv[]) {
        NSString * appDelegateClassName;
        @autoreleasepool {
            // Setup code that might create autoreleased objects goes here.
    
            appDelegateClassName = NSStringFromClass([AppDelegate class]);
        }
        return UIApplicationMain(argc, argv, nil, appDelegateClassName);
    }
    

    原理只要将appDelegateClassName换成我们自己的测试FakeAppDelegate就可以了,但是会将自己整成的程序污染,这个时候就需要NSStringFromClass,NSStringFromClass只有被编译的类才会查找到,而UnitTest类只有测试时才会参与编译,所以我们可以改成

    int main(int argc, char * argv[]) {
        NSString * appDelegateClassName;
        @autoreleasepool {
            // 方法 字符串->class
            id cls = NSClassFromString(@"XCTest");
            appDelegateClassName = cls ?  @"FakeAppDelgate" : NSStringFromClass([AppDelegate class]);
        }
        // 进行单元测试的时候 FakeAppDelgate
        return UIApplicationMain(argc, argv, nil, appDelegateClassName);
    }
    

    swift中也是同理
    新建main.swift

    
    let cls = NSClassFromString("XCTest") != nil
    let appDelegateClassName = cls ? NSStringFromClass(LGFakeAppDelegate.self) : NSStringFromClass(AppDelegate.self)
    
    UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, appDelegateClassName)
    
    

    编译完成之后我们我们打开app包所在位置,除了我们应用的app包还有个测试包

    测试包.png
    里面有几个动态库,我们的单元测试是不是有个方法进入,我们引入这个库,位置是 /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks
    我们通过xcconfig来引入
    // 1. header
    HEADER_SEARCH_PATHS = $(inherited) "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks/XCTest.framework/Headers"
    //2.链接动态库
    
    // 传统方式
    OTHER_LDFLAGS = $(inherited) -F"/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks" -framework "XCTest"
    
    LD_RUNPATH_SEARCH_PATHS = $(inherited) "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks"
    

    这个时候我们只要导入#import <XCTest/XCTest.h>就可以在项目中直接使用单元测试,我们把test.m中的内容拷贝进入。

        XCTestSuite *suite = [XCTestSuite defaultTestSuite];
        // 初始化 testCase
        LoginAppUITests *testCase = [LoginAppUITests new];
        // testCase -》 suite
        [suite addTest:testCase];
        for (XCTest *test in suite.tests) {
            [test runTest];
        }
    

    如果直接创建就相当于执行一个单元测试,测试完就会崩溃,主要是[XCTestSuite defaultTestSuite]只能执行一次。

    //起个别名
        XCTestSuite *suite = [XCTestSuite testSuiteWithName:@"MyTest"];
    //指定某个方法
        [suite addTest:[LoginAppUITests testCaseWithSelector:@selector(testExample)]];
        
        for (XCTest *test in suite.tests) {
            [test runTest];
        }
    }
    

    OC&swift测试

    swiftTest调用OC方法

    新建一个测试文件swiftTest,会自动创建UnitTest工程的桥接文件,再在主工程创建swift类生成主工程的桥接文件,在主工程桥接文件中导入创建的类,在swiftTest导入主工程模块,就可以直接使用了。

    导入主模块.png

    如果要测试swift代码就需要@testable import "testApp",这样就可以支持测试open,public, internal权限的代码

    OC调用swift方法

    直接#import "testApp-Swift.h"会提示无法找到,这时候需要在TARGET找到单元测试的target,在buildsetting中的Header Search Path中将路径添加进去$CONFIGURATION_TEMP_DIR/testApp.build/DerivedSources,注意修改自己的项目名称

    相关文章

      网友评论

          本文标题:ios技巧 -- 单元测试

          本文链接:https://www.haomeiwen.com/subject/nkrbqltx.html