Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to generate XCTest test methods #576

Open
onmyway133 opened this issue Jan 12, 2020 · 0 comments
Open

How to generate XCTest test methods #576

onmyway133 opened this issue Jan 12, 2020 · 0 comments

Comments

@onmyway133
Copy link
Owner

Code

See Spek

Override testInvocations to specify test methods

https://developer.apple.com/documentation/xctest/xctestcase/1496271-testinvocations

Returns an array of invocations representing each test method in the test case.

Because testInvocations is unavailable in Swift, we need to use ObjC

#import "include/SpekHelperTestCase.h"

@implementation SpekHelperTestCase

- (instancetype)init {
    self = [super initWithInvocation: nil];
    return self;
}

+ (NSArray<NSInvocation *> *)testInvocations {
    NSArray<NSString *> *selectorStrings = [self spekGenerateTestMethodNames];
    NSMutableArray<NSInvocation *> *invocations = [NSMutableArray arrayWithCapacity:selectorStrings.count];

    for (NSString *selectorString in selectorStrings) {
        SEL selector = NSSelectorFromString(selectorString);
        NSMethodSignature *signature = [self instanceMethodSignatureForSelector:selector];
        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
        invocation.selector = selector;

        [invocations addObject:invocation];
    }

    return invocations;
}

+ (NSArray<NSString *> *)spekGenerateTestMethodNames {
    return @[];
}

@end

Generate test methods

Calculate based on Describe and It, and use Objc runtime class_addMethod to add instance methods

open class SpekTestCase: SpekHelperTestCase {
    open class func makeDescribe() -> Describe {
        return Describe("empty")
    }

    #if canImport(SpekHelper)

    override public class func spekGenerateTestMethodNames() -> [String] {
        let describe = Self.makeDescribe()

        var names: [String] = []
        generate(describe: describe, names: &names)
        return names
    }

    private static func addInstanceMethod(name: String, closure: @escaping () -> Void) -> String {
        let block: @convention(block) (SpekTestCase) -> Void = { spekTestCase in
            let _ = spekTestCase
            closure()
        }

        let implementation = imp_implementationWithBlock(block as Any)
        let selector = NSSelectorFromString(name)
        class_addMethod(self, selector, implementation, "v@:")

        return name
    }
}

Read more

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

No branches or pull requests

1 participant