2013-06-23 17 views
5

Belirli bir işlemin bir modal izleme denetleyicisinin görüntülenmesiyle sonuçlandığını gösteren bir entegrasyon testi oluşturmak istiyorum. Hikaye panosu, 2 adet Viewcontroller, bir tane özel ViewController sınıfı ile ikinci bir UIViewController sınıfı ve "second" başlığı ile ayarlanır. Segue, tanımlayıcı "modalsegue" ile modal olmaya ayarlanmıştır. Uygulamayı simülatörde çalıştırmak harika bir şekilde çalışıyor, ancak doğru bir testi tanımlamakta çok fazla sorun yaşıyorum.Otomatik testlerin testi

ViewController.m:

@implementation ViewController 

- (IBAction)handleActionByPerformingModalSegue { 
    [self performSegueWithIdentifier:@"modalsegue" sender:self]; 
} 
@end 

Testi:

- (void)testActionCausesDisplayOfSecondViewController { 
    ViewController * vc = 
     [[UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil] 
      instantiateViewControllerWithIdentifier:@"ViewController"]; 

    [vc handleActionByPerformingModalSegue]; 
    STAssertEquals(vc.presentedViewController.title, @"second", 
     @"Title of presented view controller should be second but is %@", 
     vc.presentedViewController.title, nil); 
} 

aşağıdaki çıktıda test sonuçlarını Koşu: Neyi yanlış yapıyorum

2013-06-23 17:38:44.164 SeguesRUs[15291:c07] Warning: Attempt to present <UIViewController: 0x7561370> on <ViewController: 0x7566590> whose view is not in the window hierarchy! 
SeguesRUsTests.m:33: error: -[SeguesRUsTests testActionCausesDisplayOfSecondViewController] : '<00000000>' should be equal to '<9c210d07>': Title of presented view controller should be second but is (null) 

? İlk mesajdan kaçınmanın kolay bir yolu var mı?

+0

iyi, muhtemelen daha yüksek bir seviye çerçevesi geçmesi gereken aslında olacak bir test UI ve bazı iç yöntemler - frank-salatalık örneği Apple'ın UI Otomasyon. – Sulthan

cevap

0

İşte yaptığım şey. El ile tetiklenen segue (DocumentsDetailVC) bağlantılı DocumentsVC'ye sahip olduğumu varsayalım. Aşağıda benim kurulum ve sonra ben 1 için test ettik segue ve sonra 2. Ben kontrol etmek için denetleyici (benim durumumda bir bildirim göndermek) onun performSegueWithIdentifier tetiklemek ve her şeyi olup olmadığını görmek için prepareForSegue Yöntemi durdurmak için Yeni görünüm denetleyicisi (DocumentsDetailVC) kuruldu. Bu yöntem swizzling içerir.

OCHamcrest/OCMockito'yu birim testi için kullanmıyorum ve tüm hedeflerim, "Segue" ([self appDelegate] segueIdentifierForClass: [SomeClass class]]) tarafından eklenen hedef görüntü denetleyicisinden sonra adlandırılmıştır. Hata mesajı işaret ettiği gibi

- (void)setUp 
{ 
    [super setUp]; 

    _isPad = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad; 

    realPrepareForSegue = @selector(prepareForSegue:sender:); 
    testPrepareForSegue = @selector(documentsBrowserTest_prepareForSegue:sender:); 

    UIStoryboard *storyboard = nil; 
    if (_isPad) { 
    storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil]; 
    } 
    else { 
    storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPad" bundle:nil]; 
    } 
    UINavigationController *navController = [storyboard instantiateInitialViewController]; 
    self.sut = (DocumentsBrowserVC *)navController.topViewController; 
    [self.sut view]; 
} 


- (void)test_DocumentsDetailsVCSegueConnected 
{ 
    if (_isPad == FALSE) { 
    STAssertNoThrow([self.sut performSegueWithIdentifier:[[self appDelegate] segueIdentifierForClass:[DocumentsDetailVC class]] sender:self], @"DocumentsDetailVC should be connected"); 
    } 
} 


- (void)test_providerDidSelectPathLevelObject_triggersDocumentsDetailsVCSegueSectionIdFile 
{ 
    [DocumentsBrowserTest swapInstanceMethodsForClass:[DocumentsBrowserVC class] 
               selector:realPrepareForSegue 
              andSelector:testPrepareForSegue]; 

    [[NSNotificationCenter defaultCenter] addObserver:self.sut selector:@selector(providerDidSelectPathLevelObject:) name:ProviderDidSelectPathLevelObjectNotification object:nil]; 

    // when  
PathLevelObject *plo = self.pathLevelObjects[SectionIdFile][4]; 
NSDictionary *userInfo = @{OBJECT_KEY : plo , BROWSER_AREA_KEY : @(DocumentsFolder)}; 
[[NSNotificationCenter defaultCenter] postNotificationName:ProviderDidSelectPathLevelObjectNotification object:nil userInfo:userInfo]; 

    // then 
    if (_isPad == FALSE) { 
    assertThat(NSStringFromClass([objc_getAssociatedObject(self.sut, storyboardSegueKey) class]), is(equalTo(@"UIStoryboardPushSegue"))); 
    assertThatBool([[objc_getAssociatedObject(self.sut, storyboardSegueKey) destinationViewController] isKindOfClass:[DocumentsDetailVC class]], is(equalToBool(TRUE))); 
    assertThat(objc_getAssociatedObject(self.sut, senderKey), is(equalTo(self.sut))); 
    } 
    else { 
    assertThatInteger(self.sut.detailViewController.browsingArea, is(equalToInteger(DocumentsFolder))); 
    assertThat(self.sut.detailViewController.pathLevelObject, is(equalTo(plo))); 
    } 


    [[NSNotificationCenter defaultCenter] removeObserver:self.sut]; 

    [DocumentsBrowserTest swapInstanceMethodsForClass:[DocumentsBrowserVC class] 
               selector:realPrepareForSegue 
              andSelector:testPrepareForSegue]; 
} 
+0

Nispeten az doğrulamak için çok fazla test kodu var. Böyle bir testten çok değer aldığını söyleyebilir misin? – fatuhoku

1

, sorun kimin görünümü UIWindow hiyerarşi bulunmayan bir UIViewController üzerine sunmaya çalışıyoruz olmasıdır.

kolay yolu düzeltmek için:

- (void)testExample { 

    // 
    // Arrange 
    // Storyboard 
    // 
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; 

    // 
    // Arrange 
    // View Controller 
    // 
    UIViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"ViewController"]; 
    [UIApplication sharedApplication].keyWindow.rootViewController = viewController; 

    // 
    // Act 
    // 
    [viewController performSegueWithIdentifier:@"ModalSegue" sender:nil]; 

    // 
    // Assert 
    // 
    XCTAssertEqualObjects(viewController.presentedViewController.title, @"Second"); 

} 
+0

'[UIApplication sharedApplication]', ünite testinizin içinde bir UIApplication örneğini başlatır mı? Orada ne olur? – fatuhoku

+0

'rootWord 'işlevine erişmek için' keyWindow' öğesine erişmek için' UIApplication' adlı paylaşılan örneğini kullanıyorum. –

İlgili konular