Move iOS tests to XCTest from gtest.

This enables tighter integration with XCode tooling and is a prereq
for adding UI tests.

BUG=webrtc:7150

Review-Url: https://codereview.webrtc.org/2697603002
Cr-Commit-Position: refs/heads/master@{#16609}
This commit is contained in:
kthelgason
2017-02-14 04:58:56 -08:00
committed by Commit bot
parent e374e0139b
commit 4065a5762b
6 changed files with 157 additions and 321 deletions

View File

@ -11,108 +11,19 @@
#import <Foundation/Foundation.h>
#import <OCMock/OCMock.h>
#import <QuartzCore/CoreAnimation.h>
#import <XCTest/XCTest.h>
#include "webrtc/base/gunit.h"
#include "webrtc/base/ssladapter.h"
#import "WebRTC/RTCMediaConstraints.h"
#import "WebRTC/RTCPeerConnectionFactory.h"
#import "WebRTC/RTCSessionDescription.h"
#import "ARDAppClient+Internal.h"
#import "ARDJoinResponse+Internal.h"
#import "ARDMessageResponse+Internal.h"
#import "ARDSDPUtils.h"
static NSString *kARDAppClientTestsDomain = @"org.webrtc.ARDAppClientTests";
static NSInteger kARDAppClientTestsExpectationTimeoutError = 100;
// These classes mimic XCTest APIs, to make eventual conversion to XCTest
// easier. Conversion will happen once XCTest is supported well on build bots.
@interface ARDTestExpectation : NSObject
@property(nonatomic, readonly) NSString *description;
@property(nonatomic, readonly) BOOL isFulfilled;
- (instancetype)initWithDescription:(NSString *)description;
- (void)fulfill;
@end
@implementation ARDTestExpectation
@synthesize description = _description;
@synthesize isFulfilled = _isFulfilled;
- (instancetype)initWithDescription:(NSString *)description {
if (self = [super init]) {
_description = description;
}
return self;
}
- (void)fulfill {
_isFulfilled = YES;
}
@end
@interface ARDTestCase : NSObject
- (ARDTestExpectation *)expectationWithDescription:(NSString *)description;
- (void)waitForExpectationsWithTimeout:(NSTimeInterval)timeout
handler:(void (^)(NSError *error))handler;
@end
@implementation ARDTestCase {
NSMutableArray *_expectations;
}
- (instancetype)init {
if (self = [super init]) {
_expectations = [NSMutableArray array];
}
return self;
}
- (ARDTestExpectation *)expectationWithDescription:(NSString *)description {
ARDTestExpectation *expectation =
[[ARDTestExpectation alloc] initWithDescription:description];
[_expectations addObject:expectation];
return expectation;
}
- (void)waitForExpectationsWithTimeout:(NSTimeInterval)timeout
handler:(void (^)(NSError *error))handler {
CFTimeInterval startTime = CACurrentMediaTime();
NSError *error = nil;
while (![self areExpectationsFulfilled]) {
CFTimeInterval duration = CACurrentMediaTime() - startTime;
if (duration > timeout) {
error = [NSError errorWithDomain:kARDAppClientTestsDomain
code:kARDAppClientTestsExpectationTimeoutError
userInfo:@{}];
break;
}
[[NSRunLoop currentRunLoop]
runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
}
handler(error);
}
- (BOOL)areExpectationsFulfilled {
for (ARDTestExpectation *expectation in _expectations) {
if (!expectation.isFulfilled) {
return NO;
}
}
return YES;
}
@end
@interface ARDAppClientTest : ARDTestCase
@interface ARDAppClientTest : XCTestCase
@end
@implementation ARDAppClientTest
@ -255,9 +166,9 @@ static NSInteger kARDAppClientTestsExpectationTimeoutError = 100;
NSString *callerId = @"testCallerId";
NSString *answererId = @"testAnswererId";
ARDTestExpectation *callerConnectionExpectation =
XCTestExpectation *callerConnectionExpectation =
[self expectationWithDescription:@"Caller PC connected."];
ARDTestExpectation *answererConnectionExpectation =
XCTestExpectation *answererConnectionExpectation =
[self expectationWithDescription:@"Answerer PC connected."];
caller = [self createAppClientForRoomId:roomId
@ -309,7 +220,7 @@ static NSInteger kARDAppClientTestsExpectationTimeoutError = 100;
shouldUseLevelControl:NO];
[self waitForExpectationsWithTimeout:20 handler:^(NSError *error) {
if (error) {
EXPECT_TRUE(0);
XCTFail(@"Expectation failed with error %@.", error);
}
}];
}
@ -317,23 +228,22 @@ static NSInteger kARDAppClientTestsExpectationTimeoutError = 100;
// Test to see that we get a local video connection
// Note this will currently pass even when no camera is connected as a local
// video track is created regardless (Perhaps there should be a test for that...)
#if !TARGET_IPHONE_SIMULATOR // Expect to fail on simulator due to no camera support
- (void)testSessionShouldGetLocalVideoTrackCallback {
ARDAppClient *caller = nil;
NSString *roomId = @"testRoom";
NSString *callerId = @"testCallerId";
ARDTestExpectation *localVideoTrackExpectation =
XCTestExpectation *localVideoTrackExpectation =
[self expectationWithDescription:@"Caller got local video."];
caller = [self createAppClientForRoomId:roomId
clientId:callerId
isInitiator:YES
messages:[NSArray array]
messageHandler:^(ARDSignalingMessage *message) {
} connectedHandler:^{
} localVideoTrackHandler:^{
[localVideoTrackExpectation fulfill];
}];
messageHandler:^(ARDSignalingMessage *message) {}
connectedHandler:^{}
localVideoTrackHandler:^{ [localVideoTrackExpectation fulfill]; }];
caller.defaultPeerConnectionConstraints =
[[RTCMediaConstraints alloc] initWithMandatoryConstraints:nil
optionalConstraints:nil];
@ -346,112 +256,10 @@ static NSInteger kARDAppClientTestsExpectationTimeoutError = 100;
shouldUseLevelControl:NO];
[self waitForExpectationsWithTimeout:20 handler:^(NSError *error) {
if (error) {
EXPECT_TRUE(0);
XCTFail("Expectation timed out with error: %@.", error);
}
}];
}
@end
@interface ARDSDPUtilsTest : ARDTestCase
- (void)testPreferVideoCodec:(NSString *)codec
sdp:(NSString *)sdp
expectedSdp:(NSString *)expectedSdp;
@end
@implementation ARDSDPUtilsTest
- (void)testPreferVideoCodec:(NSString *)codec
sdp:(NSString *)sdp
expectedSdp:(NSString *)expectedSdp {
RTCSessionDescription* desc =
[[RTCSessionDescription alloc] initWithType:RTCSdpTypeOffer sdp:sdp];
RTCSessionDescription *outputDesc =
[ARDSDPUtils descriptionForDescription:desc
preferredVideoCodec:codec];
EXPECT_TRUE([outputDesc.description rangeOfString:expectedSdp].location !=
NSNotFound);
}
@end
class SignalingTest : public ::testing::Test {
protected:
static void SetUpTestCase() {
rtc::InitializeSSL();
}
static void TearDownTestCase() {
rtc::CleanupSSL();
}
};
TEST_F(SignalingTest, SessionTest) {
@autoreleasepool {
ARDAppClientTest *test = [[ARDAppClientTest alloc] init];
[test testSession];
}
}
#if !TARGET_IPHONE_SIMULATOR
// Expected fail on iOS Simulator due to no camera support
TEST_F(SignalingTest, SessionLocalVideoCallbackTest) {
@autoreleasepool {
ARDAppClientTest *test = [[ARDAppClientTest alloc] init];
[test testSessionShouldGetLocalVideoTrackCallback];
}
}
#endif
TEST_F(SignalingTest, SdpH264Test) {
@autoreleasepool {
ARDSDPUtilsTest *test = [[ARDSDPUtilsTest alloc] init];
NSString *sdp = @("m=video 9 RTP/SAVPF 100 116 117 96 120 97\n"
"a=rtpmap:120 H264/90000\n"
"a=rtpmap:97 H264/90000\n");
NSString *expectedSdp = @("m=video 9 RTP/SAVPF 120 97 100 116 117 96\n"
"a=rtpmap:120 H264/90000\n"
"a=rtpmap:97 H264/90000\n");
[test testPreferVideoCodec:@"H264"
sdp:sdp
expectedSdp:expectedSdp];
}
}
TEST_F(SignalingTest, SdpVp8Test) {
@autoreleasepool {
ARDSDPUtilsTest *test = [[ARDSDPUtilsTest alloc] init];
NSString *sdp = @("m=video 9 RTP/SAVPF 100 116 117 96 120 97\n"
"a=rtpmap:116 VP8/90000\n");
NSString *expectedSdp = @("m=video 9 RTP/SAVPF 116 100 117 96 120 97\n"
"a=rtpmap:116 VP8/90000\n");
[test testPreferVideoCodec:@"VP8"
sdp:sdp
expectedSdp:expectedSdp];
}
}
TEST_F(SignalingTest, SdpNoMLineTest) {
@autoreleasepool {
ARDSDPUtilsTest *test = [[ARDSDPUtilsTest alloc] init];
NSString *sdp = @("a=rtpmap:116 VP8/90000\n");
[test testPreferVideoCodec:@"VP8"
sdp:sdp
expectedSdp:sdp];
}
}
TEST_F(SignalingTest, SdpMissingCodecTest) {
@autoreleasepool {
ARDSDPUtilsTest *test = [[ARDSDPUtilsTest alloc] init];
NSString *sdp = @("m=video 9 RTP/SAVPF 100 116 117 96 120 97\n"
"a=rtpmap:116 VP8/90000\n");
[test testPreferVideoCodec:@"foo"
sdp:sdp
expectedSdp:sdp];
}
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
@end

View File

@ -0,0 +1,64 @@
/*
* Copyright 2017 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#import <Foundation/Foundation.h>
#import <XCTest/XCTest.h>
#import "WebRTC/RTCSessionDescription.h"
#import "ARDSDPUtils.h"
@interface ARDSDPUtilsTest : XCTestCase
@end
@implementation ARDSDPUtilsTest
- (void)testPreferVideoCodecH264 {
NSString *sdp = @("m=video 9 RTP/SAVPF 100 116 117 96 120 97\n"
"a=rtpmap:120 H264/90000\n"
"a=rtpmap:97 H264/90000\n");
NSString *expectedSdp = @("m=video 9 RTP/SAVPF 120 97 100 116 117 96\n"
"a=rtpmap:120 H264/90000\n"
"a=rtpmap:97 H264/90000\n");
[self preferVideoCodec:@"H264" sdp:sdp expected:expectedSdp];
}
- (void)testPreferVideoCodecVP8 {
NSString *sdp = @("m=video 9 RTP/SAVPF 100 116 117 96 120 97\n"
"a=rtpmap:116 VP8/90000\n");
NSString *expectedSdp = @("m=video 9 RTP/SAVPF 116 100 117 96 120 97\n"
"a=rtpmap:116 VP8/90000\n");
[self preferVideoCodec:@"VP8" sdp:sdp expected:expectedSdp];
}
- (void)testNoMLine {
NSString *sdp = @("a=rtpmap:116 VP8/90000\n");
[self preferVideoCodec:@"VP8" sdp:sdp expected:sdp];
}
- (void)testMissingCodec {
NSString *sdp = @("m=video 9 RTP/SAVPF 100 116 117 96 120 97\n"
"a=rtpmap:116 VP8/90000\n");
[self preferVideoCodec:@"foo" sdp:sdp expected:sdp];
}
#pragma mark - Helpers
- (void)preferVideoCodec:(NSString *)codec
sdp:(NSString *)sdp
expected:(NSString *)expectedSdp{
RTCSessionDescription* desc =
[[RTCSessionDescription alloc] initWithType:RTCSdpTypeOffer sdp:sdp];
RTCSessionDescription *outputDesc =
[ARDSDPUtils descriptionForDescription:desc
preferredVideoCodec:codec];
XCTAssertTrue([outputDesc.description rangeOfString:expectedSdp].location != NSNotFound);
}
@end

View File

@ -10,33 +10,21 @@
#import <Foundation/Foundation.h>
#import <OCMock/OCMock.h>
#import <XCTest/XCTest.h>
#import "WebRTC/RTCMediaConstraints.h"
#import "ARDSettingsModel+Private.h"
#import "ARDSettingsStore.h"
#import "WebRTC/RTCMediaConstraints.h"
#include "webrtc/base/gunit.h"
@interface ARDSettingsModelTests : NSObject {
@interface ARDSettingsModelTests : XCTestCase {
ARDSettingsModel *_model;
}
- (void)testStoringInavlidConstraintReturnsNo;
- (void)testDefaultMediaFromStore;
- (void)testWidthConstraintFromStore;
- (void)testHeightConstraintFromStore;
@end
@implementation ARDSettingsModelTests
- (instancetype)init {
self = [super init];
if (self) {
_model = [[ARDSettingsModel alloc] init];
}
return self;
}
- (id)setupMockStoreWithMediaConstraintString:(NSString *)constraintString {
id storeMock = [OCMockObject mockForClass:[ARDSettingsStore class]];
[([[storeMock stub] andReturn:constraintString]) videoResolutionConstraints];
@ -47,113 +35,50 @@
return storeMock;
}
- (void)testDefaultMediaFromStore {
// given
id storeMock = [self setupMockStoreWithMediaConstraintString:nil];
- (void)setUp {
_model = [[ARDSettingsModel alloc] init];
}
- (void)testDefaultMediaFromStore {
id storeMock = [self setupMockStoreWithMediaConstraintString:nil];
[[storeMock expect] setVideoResolutionConstraints:@"640x480"];
// when
NSString *string = [_model currentVideoResoultionConstraintFromStore];
// then
EXPECT_TRUE([string isEqualToString:@"640x480"]);
XCTAssertEqualObjects(string, @"640x480");
[storeMock verify];
}
- (void)testStoringInavlidConstraintReturnsNo {
// given
id storeMock = [self setupMockStoreWithMediaConstraintString:@"960x480"];
// when
BOOL result = [_model storeVideoResoultionConstraint:@"960x480"];
// then
EXPECT_FALSE(result);
- (void)testStoringInvalidConstraintReturnsNo {
__unused id storeMock = [self setupMockStoreWithMediaConstraintString:@"960x480"];
XCTAssertFalse([_model storeVideoResoultionConstraint:@"960x480"]);
}
- (void)testWidthConstraintFromStore {
// given
[self setupMockStoreWithMediaConstraintString:@"1270x480"];
// when
NSString *width = [_model currentVideoResolutionWidthFromStore];
// then
EXPECT_TRUE([width isEqualToString:@"1270"]);
XCTAssertEqualObjects(width, @"1270");
}
- (void)testHeightConstraintFromStore {
// given
[self setupMockStoreWithMediaConstraintString:@"960x540"];
// when
NSString *height = [_model currentVideoResolutionHeightFromStore];
// then
EXPECT_TRUE([height isEqualToString:@"540"]);
XCTAssertEqualObjects(height, @"540");
}
- (void)testConstraintComponentIsNilWhenInvalidConstraintString {
// given
[self setupMockStoreWithMediaConstraintString:@"invalid"];
// when
NSString *width = [_model currentVideoResolutionWidthFromStore];
// then
EXPECT_TRUE(width == nil);
XCTAssertNil(width);
}
- (void)testConstraintsDictionaryIsNilWhenInvalidConstraintString {
// given
[self setupMockStoreWithMediaConstraintString:@"invalid"];
// when
NSDictionary *constraintsDictionary = [_model currentMediaConstraintFromStoreAsRTCDictionary];
// then
EXPECT_TRUE(constraintsDictionary == nil);
XCTAssertNil(constraintsDictionary);
}
@end
class ARDSettingsModelTest : public ::testing::Test {
protected:
ARDSettingsModelTests *test;
ARDSettingsModelTest() { test = [[ARDSettingsModelTests alloc] init]; }
};
TEST_F(ARDSettingsModelTest, DefaultMediaFromStore) {
@autoreleasepool {
[test testDefaultMediaFromStore];
}
}
TEST_F(ARDSettingsModelTest, StoringInvalidConstraintsReturnsNo) {
@autoreleasepool {
[test testStoringInavlidConstraintReturnsNo];
}
}
TEST_F(ARDSettingsModelTest, WidthConstraintFromStore) {
@autoreleasepool {
[test testWidthConstraintFromStore];
}
}
TEST_F(ARDSettingsModelTest, HeightConstraintFromStore) {
@autoreleasepool {
[test testHeightConstraintFromStore];
}
}
TEST_F(ARDSettingsModelTest, ConstratintIsNil) {
@autoreleasepool {
[test testConstraintComponentIsNilWhenInvalidConstraintString];
}
}
TEST_F(ARDSettingsModelTest, DictionaryIsNil) {
@autoreleasepool {
[test testConstraintsDictionaryIsNilWhenInvalidConstraintString];
}
}