2015-12-17 8 views
25

मैं अपने आईओएस प्रोजेक्ट में यूआई परीक्षणों को शामिल करने की कोशिश कर रहा हूं, लेकिन एक चीज जो मुझे पकड़ती रहती है वह तथ्य यह है कि ऐसा लगता है कि आपके द्वारा लिखे गए सभी परीक्षणों की शुरुआत शुरुआत से ही होनी चाहिए ऐप और उनके माध्यम से काम करते हैं। उदाहरण के लिए, यदि मैं एक लॉगिन स्क्रीन के पीछे एक दृश्य का परीक्षण करना चाहता हूं, तो मेरे परीक्षण पहले लॉगिन स्क्रीन पर चलाना चाहिए, उपयोगकर्ता नाम/पासवर्ड दर्ज करें, लॉगिन पर क्लिक करें, फिर उस दृश्य पर जाएं जिसे मैं परीक्षण करना चाहता हूं। आदर्श रूप से, लॉगिन दृश्य और अगले के लिए परीक्षण पूरी तरह से अलग हो जाएगा। क्या ऐसा करने का कोई तरीका है, या क्या मैं यूआई परीक्षणों के पीछे दर्शन खो रहा हूं?आईओएस यूआई परीक्षण एक अलग दृश्य पर

+0

मैं वास्तव में वास्तव में वास्तव में यह अच्छा काम करना चाहते हैं ly: ऐप साफ शुरू होता है, परीक्षण कोड वीसी पेश करने का निर्णय लेता है, और परीक्षण कोड यूआई के साथ बातचीत करने के लिए स्वचालन का उपयोग करता है। यह यूआई यूनिट परीक्षण है। इस विषय पर मेरे सभी शोध यहां https://gist.github.com/fulldecent/529849bc5dd4464bbde2 हो सकता है कि कोई और मशाल उठा सकता है। –

उत्तर

-1

दुर्भाग्यवश, यूआई परीक्षण के साथ आप जिस परिदृश्य का वर्णन करते हैं, वह संभव नहीं है।

एक दृष्टिकोण जो मैं इसका मुकाबला करने के लिए लेता हूं वह है कि मेरे परीक्षणों को "प्रवाह" में शामिल किया जाए। उदाहरण के लिए, मान लीजिए कि मैं फ़ीचर ए, फीचर बी और फ़ीचर सी का परीक्षण करना चाहता हूं। मुझे तीनों काम करने के लिए लॉग इन करने की आवश्यकता है।

प्रत्येक परीक्षण के लिए मैं ऐप लॉन्च नहीं करता हूं, लॉग इन करता हूं, फिर अंत में वास्तविक परीक्षण चलाता हूं। इसके बजाय, मैं ऐप लॉन्च करता हूं और एक बार लॉगिन करता हूं। फिर मैं अपने परीक्षण को तीन निजी सहायक विधियों, testFeatureA(), testFeatureB(), और testFeatureC() में समूहित करता हूं।

एकल प्रवाह बनाकर परीक्षण सूट चलाने के लिए बहुत कम समय लगेगा। बड़ा नकारात्मक पक्ष यह है कि यदि फ़ीचर ए विफल रहता है तो फ़ीचर बी का परीक्षण कभी नहीं किया जाएगा। इस दृष्टिकोण का उपयोग केवल तभी किया जाना चाहिए जब आप अपने परीक्षणों के सभी पर ध्यान दें या नहीं।

XCTest helper का उपयोग __LINE__ और __FILE__ पैरामीटर के साथ बोनस अंक डिफ़ॉल्ट रूप से डिफॉल्ट किया गया। फिर आप उन्हें पर विफलता रेखा दिखाने के लिए अपने XCTFail() कॉल में पास कर सकते हैं।

+0

वास्तव में संभव है क्योंकि यह वास्तव में संभव है (quellish उत्तर देखें) –

19

बिल्कुल!

आपको एक साफ एप्लिकेशन वातावरण की आवश्यकता है जिसमें आप अपने परीक्षण चला सकते हैं - एक खाली स्लेट।

सभी अनुप्रयोगों में एक एप्लिकेशन प्रतिनिधि होता है जो एप्लिकेशन की प्रारंभिक स्थिति सेट करता है और लॉन्च पर रूट व्यू कंट्रोलर प्रदान करता है। परीक्षण के प्रयोजनों के लिए आप ऐसा नहीं करना चाहते हैं - आपको उन सभी चीजों के बिना अलगाव में परीक्षण करने में सक्षम होना चाहिए। आदर्श रूप में आप स्क्रीन को पूरा करने में सक्षम होना चाहते हैं और केवल उस स्क्रीन को लोड करना चाहते हैं, और कोई अन्य राज्य परिवर्तन नहीं होता है।

ऐसा करने के लिए आप केवल UIApplicationDelegate लागू करने के परीक्षण के लिए ऑब्जेक्ट बना सकते हैं। आप एप्लिकेशन को "परीक्षण मोड" में चलाने के लिए बता सकते हैं और लॉन्च तर्क का उपयोग कर परीक्षण-विशिष्ट एप्लिकेशन प्रतिनिधि का उपयोग कर सकते हैं।

ऑब्जेक्टिव-सी: main.m:

int main(int argc, char * argv[]) { 
NSString * const kUITestingLaunchArgument = @"org.quellish.UITestingEnabled"; 

    @autoreleasepool { 
     if ([[NSUserDefaults standardUserDefaults] valueForKey:kUITestingLaunchArgument] != nil){ 
      return UIApplicationMain(argc, argv, nil, NSStringFromClass([TestingApplicationDelegate class])); 
     } else { 
      return UIApplicationMain(argc, argv, nil, NSStringFromClass([ProductionApplicationDelegate class])); 
     } 
    } 
} 

स्विफ्ट: main.swift:

let kUITestingLaunchArgument = "org.quellish.UITestingEnabled" 

if (NSUserDefaults.standardUserDefaults().valueForKey(kUITestingLaunchArgument) != nil){ 
    UIApplicationMain(Process.argc, Process.unsafeArgv, NSStringFromClass(UIApplication), NSStringFromClass(TestingApplicationDelegate)) 

} else { 
    UIApplicationMain(Process.argc, Process.unsafeArgv, NSStringFromClass(UIApplication), NSStringFromClass(AppDelegate)) 
} 

आप अपने स्विफ्ट वर्गों से किसी भी @UIApplicationMain टिप्पणी निकालने में होगा।

"आवेदन परीक्षण" लांच तर्क प्रदान करने के लिए Xcode में इस योजना का "टेस्ट" कार्रवाई सेट करना सुनिश्चित करें के लिए:

Xcode Scheme editor

यूआई परीक्षण के लिए आप के हिस्से के रूप लांच तर्क सेट कर सकते हैं परीक्षण:

ऑब्जेक्टिव-सी:

XCUIApplication *app = [[XCUIApplication alloc] init]; 
[app setLaunchArguments:@[@"org.quellish.UITestingEnabled"] ]; 
[app launch]; 

स्विफ्ट:

012,
let app = XCUIApplication() 
app.launchArguments = [ "org.quellish.UITestingEnabled" ] 
app.launch() 

यह परीक्षण परीक्षण के लिए विशेष रूप से एक आवेदन प्रतिनिधि का उपयोग करने की अनुमति देता है। यह आपको बहुत अधिक नियंत्रण प्रदान करता है - अब आपके पास परीक्षण के लिए काम करने के लिए एक खाली स्लेट है। परीक्षण अनुप्रयोग प्रतिनिधि एक विशिष्ट स्टोरीबोर्ड लोड कर सकता है या एक खाली UIViewController डाल सकता है। अपने यूआई परीक्षणों के भाग के रूप में आप दृश्य नियंत्रक को परीक्षण के तहत तत्काल कर सकते हैं और इसे keyWindow के रूट व्यू कंट्रोलर के रूप में सेट कर सकते हैं या इसे सामान्य रूप से प्रस्तुत कर सकते हैं। एक बार इसे जोड़ने या प्रस्तुत करने के बाद आपके परीक्षण निष्पादित हो सकते हैं, और जब इसे हटा दें या इसे खारिज कर दें।

+4

यह समाधान वास्तव में अच्छा लगता है! हालांकि, 'NSUserDefaults.standardUserDefaults()। ValueForKey (kUITestingLaunchArgument)! = Nil' मेरे लिए काम नहीं किया। मैंने इसे काम करने के लिए इसे NSProcessInfo.processInfo()। Arguments.contains (kUITestingLaunchArgument) में बदल दिया। –

+0

@FyodorVolchyok मैं दृढ़ता से एक रडार दाखिल करने का सुझाव दूंगा, क्योंकि उपयोगकर्ता डिफ़ॉल्ट काम करना चाहिए। लॉन्च तर्क अन्य डिफ़ॉल्ट को अलग करते हैं क्योंकि वे तर्क डोमेन में हैं। – quellish

+0

@quellish आप परीक्षण में आसानी से एक यूआईएसटीरीबोर्ड लोड नहीं कर सकते हैं (जब तक कि आप अपनी पोस्ट में एक निजी var का खुलासा न करें http://quellish.tumblr.com/post/135415677047/ios-plplication-and-ui-testing-in-isolation)। मैं जो करता हूं वह अतिरिक्त तर्कों का उपयोग करता है ताकि TestAppDelegate जानता है कि UIStoryboard और UIViewController को तुरंत चालू करने के लिए। –

4

आप मूल यूआई लोड हो रहा है कोई आपत्ति नहीं है, बस के साथ लक्ष्य यूआई के लिए कूद:

override func setUp() { 
    super.setUp() 
    continueAfterFailure = false 
    XCUIApplication().launch() 
    let storyboard = UIStoryboard(name: "MainStoryboard", bundle: NSBundle.mainBundle()) 
    let controller = storyboard.instantiateViewControllerWithIdentifier("LanguageSelectController") 
    UIApplication.sharedApplication().keyWindow?.rootViewController = controller 
} 

आप नहीं करते मूल यूआई के नीचे अपने परीक्षण से भी तो लोड इस में पास करना चाहते हैं:

app.launchArguments.append("skipEntryViewController") 

और फिर didFinishLaunchingWithOptions में, आप देख सकते हैं:

if NSProcessInfo.processInfo().arguments.contains("skipEntryViewController") { 
    // then do NOT call makeKeyAndVisible 
} 
+0

सवाल यह निर्दिष्ट करता है कि एक साफ और पृथक परीक्षण की आवश्यकता है, यह नहीं है। –

+0

यह आवश्यकता कैसे पूरा नहीं कर रही है? –

+0

एक ही ऐप प्रतिनिधि को रखना और मूल यूआई लोडिंग कुछ ऐसा काम कर सकती है जो हस्तक्षेप कर सकती है। –

संबंधित मुद्दे