2011-09-01 34 views
28

我想在不啓動模擬器的情況下使用OCUnit在Xcode 4中運行測試。請不要試圖說服我,我正在做單元測試錯誤或類似的事情。我喜歡以傳統的方式進行TDD:在測試中爲類編寫API,然後讓類通過測試。我將編寫單獨的測試,這些測試是在模擬器中運行的端到端測試。在沒有啓動模擬器的情況下在Xcode 4中運行邏輯測試

如果沒有辦法做到這一點,那麼請有人告訴我如何讓測試工具不實例化整個應用程序?我的應用程序是事件驅動的,當它啓動時,我的測試混亂了,它發送了一堆事件。

回答

3

在你的情況,我假設你有一個單獨的邏輯測試和應用程序測試目標(如果沒有 - 你需要)。在您的方案配置中,您可以定義爲「測試」方案構建的目標。如果您的應用程序測試沒有運行,模擬器將不會啓動。

我懷疑你可能試圖在「應用程序測試」目標(例如Xcode默認創建的目標)中運行'邏輯測試'。查看更多關於這個區別here(以及如何設置)。

0

我用GHUnit來創建兼容osx/ios的測試套件。有幾個問題,但我發現它比OCUnit更可靠/兼容/直接。

GHUnit爲OS X和iOS提供了基本的模板項目,使初始設置變得簡單。

注:我通常只使用我自己的套件進行大多數測試。

28

請有人能告訴我如何讓測試工具不實例化整個應用程序?我的應用程序是事件驅動的,當它啓動時,我的測試混亂了,它發送了一堆事件。

我使用Xcode 4的內置測試。應用程序實例化可能看起來很痛苦,但是當我在Xcode Unit Testing: The Good, the Bad, the Ugly上編寫時,它可以在不區分邏輯測試和應用程序測試的情況下編寫測試。具體來說,它允許我爲視圖控制器編寫單元測試。

這就是我做,以避免我的全部啓動順序:

編輯方案

  • 選擇測試動作
  • 在「測試」中選擇參數選項卡
  • 禁用「使用運行操作的選項「
  • 添加環境變量,將runningTests設置爲YES

編輯應用程序委託

  • 以下內容添加到-application:didFinishLaunchingWithOptions:只要是有意義的:

    #if DEBUG 
        if (getenv("runningTests")) 
         return YES; 
    #endif 
    
  • 執行相同的-applicationDidBecomeActive:而只是return

更新:我改變了我的方法。請參閱How to Easily Switch Your App Delegate for Testing

+0

感謝您的提示!使用和完美的工作。 – yonel

+1

我想這隻適用於加載他們的GUI在應用程序:didFinishLaunchingWithOptions:的應用程序。如果您正在構建使用故事板的應用程序,該怎麼辦? – ABeanSits

+0

我應該在哪裏放這段代碼?我目前的目標根本沒有AppDelegate。如果我將它添加到我的UnitTest目標中,它不會改變任何內容。 (我正在使用XCode 4.6) –

2

在之前的回答中指出,邏輯測試對於這種情況是正確的。我在使用XCode 4.3.2(4E2002)進行邏輯測試方面非常艱難。看着Apple's sample unit test project幫助我理解了如何以明確的分離方式做到這一點。在那個例子中,邏輯測試來自庫目標的測試文件,而不是應用程序目標。該模型被封裝成一個庫,然後與主要目標和邏輯測試目標鏈接。應用程序目標僅包含視圖和控制器。

基於這種模式,這是我做了讓我的邏輯測試正常工作。創建一個新的目標(Cocoa Touch靜態庫),並將所有文件移動到這個新目標進行邏輯測試(通常是所有模型)。 「Build Phases」設置在「Link Binary With Libraries」您的應用程序目標和邏輯測試目標中添加此新庫。

我可以想象這些說明有點混亂。如果你剖析上面提到的示例項目,你會得到一個更好的主意。

2

注意,在Xcode的5

未經測試我使用@喬恩 - 裏德的答案時,卻發現Xcode中加環境變量XcodeProjects的xcuserstated部分,而這些用戶特定的,而不是通常承諾存儲庫。因此,我調酒我的AppDelegate覆蓋其裝載:

@implementation MyAppDelegate (Testing) 

+ (void)initialize { 
    SEL new = @selector(application:didFinishLaunchingWithOptions:); 
    SEL orig = @selector(swizzled_application:didFinishLaunchingWithOptions:); 
    Class c = [self class]; 
    Method origMethod = class_getInstanceMethod(c, orig); 
    Method newMethod = class_getInstanceMethod(c, new); 

    if (class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) { 
     class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod)); 
    } else { 
     method_exchangeImplementations(origMethod, newMethod); 
    } 
} 

- (BOOL)swizzled_application:(id)app didFinishLaunchingWithOptions:(id)opts { 
    return YES; 
} 

@end 

注意的是,以下是簡單的和仍然有效,但我不知道它是可靠的:

@implementation MyAppDelegate (Testing) 

- (BOOL)application:(id)app didFinishLaunchingWithOptions:(id)opts { 
    return YES; 
} 

@end 

這工作,因爲類別動態加載組件中的方法(如測試包)優先。雖然Swizzling感覺更安全。

+0

我應該在哪裏放置這段代碼?我目前的目標根本沒有AppDelegate。如果我將它添加到我的UnitTest目標中,它不會改變任何內容。 (我正在使用XCode 4.6) –

+0

你把它放在測試目標中,並且你將'MyAppDelegate'重命名爲你的AppDelegate的類名在你的主目標中。您的測試目標沒有應用程序委託,但這就是這個問題的要點,來自主目標的應用程序委託*仍然*執行。 – mxcl

+1

在Xcode 5中不起作用xcunit測試 – user170317

5

在上一個xcode版本(5.0.2)中,您可以非常簡單地完成此操作。選擇你的測試目標,「常規」選項卡。在「目標」欄中設置「無」。然後點擊「構建階段」標籤並從「目標依賴項」中移除主目標。

+2

你確定夠了嗎?我試過報告的步驟,但它仍然啓動模擬器。非常感謝 –

+0

我嘗試這個,但得到編譯錯誤。 – jolestar

+0

要修復編譯錯誤,請確保所有框架都鏈接到測試用例需要的位置(通常與.app鏈接的位置相同),並確保構建階段也編譯測試用例所需的所有源文件。 – mxcl

0

使用XCODE 7和xctool

xctool能夠執行單元測試而不模擬器。

得到這個工作,

1。更新沒有主機應用程序的目標設置。

選擇您的項目 - >然後測試目標 - >將主機應用程序設置爲無。

enter image description here

2.安裝xctool,如果你沒有它。

brew install xctool 

3.執行使用終端與xctool測試。

xctool -workspace yourWorkspace.xcworkspace -scheme yourScheme run-tests -sdk iphonesimulator 
相關問題