साझा एसिंक्रोनस फिक्स्चर तैयारी को स्विफ्ट टेस्टिंग सुइट के init() async throws में रखें। स्विफ्ट टेस्टिंग उस इनिशियलाइज़र को इंस्टेंस टेस्ट मेथड को कॉल करने से पहले पूरा करता है, इसलिए मेथड को उपयोग-के-लिए-तैयार स्थिति मिलती है। XCTest में, इसके बजाय setUp() async throws का उपयोग करें।
यह गाइड Xcode में स्थानीय यूनिट-टेस्ट डेटा तैयार करने वाले मैक डेवलपर के लिए है। कार्य यह है कि दावे शुरू होने से पहले एसिंक्रोनस इनिशियलाइज़ेशन को पूरा किया जाए, सिंथेटिक इनपुट के साथ निश्चित गणनाओं का उपयोग करके। ऐप्पल इनिशियलाइज़र दृष्टिकोण को XCTest से टेस्ट माइग्रेट करना में दस्तावेज़ करता है।
स्विफ्ट टेस्टिंग फिक्स्चर इनिशियलाइज़ेशन की प्रतीक्षा कैसे करता है?
एक इंस्टेंस टेस्ट मेथड के लिए, स्विफ्ट टेस्टिंग समाहित सुइट प्रकार को इनिशियलाइज़ करता है और फिर उस इंस्टेंस पर मेथड को कॉल करता है। सुइट में एक इनिशियलाइज़र होना चाहिए जिसे बिना आर्गुमेंट के कॉल किया जा सके; वह इनिशियलाइज़र एसिंक्रोनस, थ्रोइंग, या दोनों हो सकता है। प्रत्येक इंस्टेंस टेस्ट मेथड एक अलग इंस्टेंस पर चलता है। ये सुइट प्रकारों के साथ टेस्ट फ़ंक्शन व्यवस्थित करना में दस्तावेज़ित लाइफसाइकल नियम हैं।
परिणामी निर्भरता सीधी है: फिक्स्चर तैयारी लौटती है, इनिशियलाइज़र समाप्त होता है, और टेस्ट मेथड शुरू होता है। आपके इनिशियलाइज़र को वास्तव में तैयारी ऑपरेशन की प्रतीक्षा करनी चाहिए। केवल इसके अंदर काम शुरू करना उस निर्भरता को स्थापित नहीं करता।
निम्न निर्णय सहायता का उपयोग करके चुनें कि तैयारी कहाँ होनी चाहिए:
| स्थिति | तैयारी स्थान | क्या तत्परता स्थापित करता है? |
|---|---|---|
| कई इंस्टेंस टेस्ट को उसी फिक्स्चर रेसिपी की आवश्यकता है | सुइट init() async throws |
प्रतीक्षित इनिशियलाइज़र प्रत्येक मेथड से पहले पूरा होता है |
| केवल एक टेस्ट को फिक्स्चर की आवश्यकता है | एक async throws टेस्ट बॉडी |
दावों से पहले एक स्पष्ट try await |
एक मौजूदा टेस्ट XCTestCase का सबक्लास है |
setUp() async throws |
XCTest मेथड से पहले एसिंक्रोनस सेटअप पूरा करता है |
एक स्विफ्ट टेस्टिंग टेस्ट static या ग्लोबल है |
टेस्ट बॉडी या स्पष्ट रूप से कॉल किया गया हेल्पर | टेस्ट स्पष्ट रूप से तैयारी की प्रतीक्षा करता है |
यह तालिका फ्रेमवर्क के दस्तावेज़ित लाइफसाइकल नियमों को फिक्स्चर प्लेसमेंट पर लागू करती है। विशेष रूप से, एक सुइट इनिशियलाइज़र एक प्रति-इंस्टेंस तैयारी बिंदु है; इसका मतलब यह नहीं है कि तैयारी पूरे सुइट के लिए एक बार होती है। ऐप्पल के सुइट इनिशियलाइज़ेशन नियम और XCTest सेटअप अनुक्रम देखें।
Xcode में पूर्ण एसिंक्रोनस फिक्स्चर उदाहरण जोड़ें
अपने बंडल्ड स्विफ्ट टेस्टिंग समर्थन के साथ Xcode 16 या बाद का उपयोग करें। स्विफ्ट प्रोजेक्ट दस्तावेज़ करता है कि स्विफ्ट टेस्टिंग स्विफ्ट 6 और Xcode 16 के साथ शामिल है, और एक अतिरिक्त पैकेज निर्भरता अनावश्यक है। आधिकारिक स्विफ्ट टेस्टिंग README देखें।
मौजूदा यूनिट-टेस्ट टार्गेट में, File > New > New File From Template चुनें, फिर Swift Testing Unit Test चुनें। जनरेट की गई फ़ाइल सामग्री को नीचे दिए गए पूर्ण उदाहरण से बदलें। एक मौजूदा XCTest यूनिट-टेस्ट बंडल में भी स्विफ्ट टेस्टिंग टेस्ट हो सकते हैं; एक अलग बंडल अनावश्यक है। ये चरण ऐप्पल के अपने Xcode प्रोजेक्ट में टेस्ट जोड़ना का पालन करते हैं।
import Testing
enum FixtureError: Error {
case invalidInput
}
private actor SquareCalculator {
let values: [Int]
init(values: [Int]) {
self.values = values
}
func squares() -> [Int] {
values.map { $0 * $0 }
}
}
struct CalculationFixture {
let squares: [Int]
let total: Int
static func make(values: [Int]) async throws -> Self {
guard !values.isEmpty,
values.count <= 100,
values.allSatisfy({ (0...100).contains($0) }) else {
throw FixtureError.invalidInput
}
let calculator = SquareCalculator(values: values)
let squares = await calculator.squares()
return Self(
squares: squares,
total: squares.reduce(0, +)
)
}
}
@Suite
struct CalculationTests {
let fixture: CalculationFixture
init() async throws {
fixture = try await CalculationFixture.make(values: [2, 4, 6])
}
@Test
func squaresAreReady() {
#expect(fixture.squares == [4, 16, 36])
}
@Test
func totalIsReady() {
#expect(fixture.total == 56)
}
}
नमूना गणना करने के लिए एक वास्तविक लोकल एक्टर का उपयोग करता है। एक्टर के बाहर से इसकी आइसोलेटेड मेथड को कॉल करने के लिए await की आवश्यकता होती है। कोई देरी, रैंडम इनपुट, बाहरी निर्भरता, या पृष्ठभूमि ऑपरेशन नहीं है जो सही समय पर समाप्त होने के लिए होना चाहिए। आउटपुट निश्चित रहता है चाहे निष्पादन वास्तव में सस्पेंड हो या नहीं।
फिक्स्चर फैक्टरी खाली इनपुट, 100 से अधिक मानों, और 0...100 के बाहर के मानों को अस्वीकार करती है। ये चित्रात्मक सीमाएँ अंकगणित को छोटा रखती हैं: प्रत्येक वर्ग अधिकतम 10,000 और कुल अधिकतम 1,000,000 होता है। अवैध मान चुपचाप हटाए या बदले जाने के बजाय एक त्रुटि उत्पन्न करते हैं।
प्रदान किए गए इनपुट के लिए, अपेक्षित गणना 2² + 4² + 6² = 4 + 16 + 36 = 56 है। इनिशियलाइज़र पूर्ण फिक्स्चर को एक नॉनऑप्शनल let प्रॉपर्टी में संग्रहीत करता है। इसलिए टेस्ट मेथड्स को न तो रेडीनेस फ्लैग की आवश्यकता होती है और न ही ऑप्शनल अनरैपिंग की।
मेथड्स स्वयं सिंक्रोनस रह सकते हैं क्योंकि उनकी एसिंक्रोनस पूर्वापेक्षा इनिशियलाइज़र में पहले ही पूरी हो चुकी है। जब एसिंक्रोनस कार्य टेस्ट बॉडी के अंदर होता है, तो ऐप्पल का दस्तावेज़ित पैटर्न उस फ़ंक्शन को async से चिह्नित करना और ऑपरेशन की सीधे प्रतीक्षा करना है। एसिंक्रोनस कोड टेस्ट करना देखें।
सिंथेटिक अंकगणित को स्थानीय रूप से पायथन से जांचा गया था। इस शोध वातावरण में स्विफ्ट अनुपलब्ध है, इसलिए स्विफ्ट उदाहरणों का निरीक्षण किया गया था लेकिन उन्हें यहाँ संकलित या निष्पादित नहीं किया गया था। उपरोक्त अपेक्षित परिणाम नमूने की गणना का वर्णन करते हैं, न कि रिपोर्ट किए गए Xcode टेस्ट रन का।
टास्क शुरू करने से सेटअप पूरा क्यों नहीं होता?
एक सामान्य गलती है एक सिंक्रोनस इनिशियलाइज़र से Task { ... } लॉन्च करना और तुरंत वापस लौटना। इनिशियलाइज़र ने तब काम लॉन्च करना समाप्त कर दिया है, लेकिन वह काम तब भी चल रहा हो सकता है जब टेस्ट मेथड शुरू होता है।
स्विफ्ट की भाषा गाइड Task { ... } को अनस्ट्रक्चर्ड टास्क बनाने के रूप में वर्णित करती है। इसका लौटाया गया हैंडल await handle.value के माध्यम से परिणाम की प्रतीक्षा करने के लिए उपयोग किया जा सकता है। हैंडल को त्यागने से वह स्पष्ट प्रतीक्षा बिंदु हट जाता है। आधिकारिक स्विफ्ट बुक का अनस्ट्रक्चर्ड कॉनकरेंसी सेक्शन देखें।
फिक्स्चर इनिशियलाइज़ेशन के लिए, एसिंक्रोनस इनिशियलाइज़र में फैक्टरी की सीधे प्रतीक्षा करना आमतौर पर निर्भरता की सबसे स्पष्ट अभिव्यक्ति है। यदि कोई मौजूदा हेल्पर आंतरिक रूप से काम लॉन्च करता है और उस काम के समाप्त होने से पहले लौटता है, तो हेल्पर की प्रतीक्षा केवल उसके लौटने की प्रतीक्षा करती है। इसके पूर्णता अनुबंध को बदलें ताकि लौटने का मतलब हो कि फिक्स्चर तैयार है, या एक टास्क परिणाम उजागर करें जिसे कॉलर प्रतीक्षा कर सके।
एक निश्चित स्लीप जोड़ना उस निर्भरता को व्यक्त नहीं करता। यह समय बीतने की प्रतीक्षा करता है, जिससे तत्परता इस पर निर्भर रहती है कि तैयारी उस अंतराल के भीतर समाप्त होती है या नहीं। इसी तरह, टेस्ट मेथड को async बनाना केवल एसिंक्रोनस कॉल सक्षम करता है; मेथड को अभी भी उस ऑपरेशन की प्रतीक्षा करनी होगी जिस पर वह निर्भर करता है।
XCTest में समकक्ष सेटअप क्या है?
XCTest एक समर्पित एसिंक्रोनस सेटअप हुक प्रदान करता है। प्रत्येक टेस्ट मेथड से पहले इसका दस्तावेज़ित क्रम setUp() async throws, फिर setUpWithError(), फिर सिंक्रोनस setUp() है। टेस्ट मेथड उन हुक का अनुसरण करता है। अपने टेस्ट में स्टेट सेट अप और टियर डाउन करें देखें।
XCTest के तहत उसी फिक्स्चर की तुलना करने के लिए, निम्न पूर्ण साथी फ़ाइल को पहले उदाहरण के समान यूनिट-टेस्ट टार्गेट में जोड़ें। यह XCTest आयात करता है और पहले से परिभाषित, मॉड्यूल-दृश्य CalculationFixture का उपयोग करता है। हेल्पर परिभाषाओं को पहली फ़ाइल में रखें; उन्हें डुप्लिकेट न करें।
import XCTest
final class CalculationXCTests: XCTestCase {
private var fixture: CalculationFixture?
override func setUp() async throws {
try await super.setUp()
fixture = try await CalculationFixture.make(values: [2, 4, 6])
}
func testTotalIsReady() throws {
let readyFixture = try XCTUnwrap(fixture)
XCTAssertEqual(readyFixture.squares, [4, 16, 36])
XCTAssertEqual(readyFixture.total, 56)
}
}
XCTest मेथड भी सिंक्रोनस हो सकता है: एसिंक्रोनस तैयारी सेटअप में होती है। ऑप्शनल प्रॉपर्टी XCTest के अलग सेटअप चरण को समायोजित करती है, और XCTUnwrap एक लापता फिक्स्चर को स्पष्ट विफलता बनाता है। ऐप्पल उस अनरैपिंग पैटर्न को अपने माइग्रेशन गाइड में दस्तावेज़ करता है।
इस टेस्ट को स्विफ्ट टेस्टिंग में परिवर्तित करते समय, तैयारी को सुइट इनिशियलाइज़र में ले जाएँ और import Testing, @Test, और स्विफ्ट टेस्टिंग अपेक्षाओं का उपयोग करें। एक सामान्य स्विफ्ट टेस्टिंग सुइट में केवल setUp नाम का मेथड दस्तावेज़ित सेटअप तंत्र नहीं है; ऐप्पल का माइग्रेशन पथ सेटअप परिवार को इनिशियलाइज़ेशन से बदल देता है।
जब इनिशियलाइज़ेशन अभी भी जल्दी दिखाई दे तो इन सीमाओं की जांच करें
पहले, जांचें कि टेस्ट इंस्टेंस मेथड है या नहीं। एक static टेस्ट को सुइट इंस्टेंस की आवश्यकता नहीं होती, इसलिए यह स्वचालित इंस्टेंस इनिशियलाइज़ेशन पर निर्भर नहीं हो सकता। एक ग्लोबल टेस्ट का भी कोई समाहित इंस्टेंस नहीं होता। किसी भी रूप के लिए, टेस्ट बॉडी में फिक्स्चर का निर्माण और प्रतीक्षा करें। समर्थित टेस्ट फॉर्म XCTest से टेस्ट माइग्रेट करना में वर्णित हैं।
दूसरा, पूर्ण तैयारी कॉल चेन का निरीक्षण करें। उस ऑपरेशन को ढूंढें जो वास्तव में तैयार स्थिति उत्पन्न करता है और सुनिश्चित करें कि प्रत्येक कॉलर उसकी प्रतीक्षा करता है। उदाहरण में, एक्टर गणना फैक्टरी के लौटने से पहले समाप्त होती है, और फैक्टरी इनिशियलाइज़र के समाप्त होने से पहले लौटती है। दावों के लिए आवश्यक कोई कार्य उस अनुक्रम से बाहर नहीं निकलता।
तीसरा, सेटअप त्रुटियों को प्रसारित होने दें। यदि CalculationFixture.make थ्रो करता है, तो सुइट इंस्टेंस इनिशियलाइज़ेशन समाप्त नहीं कर सकता, इसलिए उसका इंस्टेंस टेस्ट मेथड उस इंस्टेंस पर आगे नहीं बढ़ सकता। try? और फॉलबैक के माध्यम से विफल तैयारी को खाली फिक्स्चर से बदलने से बचें जब तक कि वह फॉलबैक स्पष्ट रूप से टेस्ट के तहत व्यवहार न हो। उदाहरण की अमान्य-इनपुट त्रुटि जानबूझकर एक स्पष्ट रूप से उपयोग योग्य फिक्स्चर को बनने से रोकती है।
अंत में, इनिशियलाइज़ेशन क्रम को टेस्ट शेड्यूलिंग से अलग करें। स्विफ्ट टेस्टिंग डिफ़ॉल्ट रूप से टेस्ट को समानांतर में चलाता है। एक सुइट का .serialized ट्रेट उसके समाहित टेस्ट को क्रमिक रूप से चला सकता है, लेकिन सीरियलाइज़ेशन एक अनप्रतीक्षित टास्क को प्रतीक्षित तैयारी में नहीं बदलता, न ही यह सुइट इनिशियलाइज़र को केवल एक बार चलाता है। ऐप्पल ट्रेट के स्कोप को टेस्ट को क्रमिक या समानांतर में चलाना में दस्तावेज़ करता है।
इस स्थानीय गणना के लिए, फिक्स्चर को अपरिवर्तनीय रखें और प्रत्येक इंस्टेंस टेस्ट के लिए स्वतंत्र रूप से तैयार करें। आवश्यक जांच निर्भरता श्रृंखला है: तैयारी ऑपरेशन एक पूर्ण फिक्स्चर लौटाता है, इनिशियलाइज़र उस परिणाम की प्रतीक्षा करता है, और टेस्ट इनिशियलाइज़्ड प्रॉपर्टी को पढ़ता है। यह टेस्ट को टाइमिंग धारणाओं के बिना एक ठोस तत्परता स्थिति देता है।
स्रोत
- सुइट प्रकारों के साथ टेस्ट फ़ंक्शन व्यवस्थित करना — Apple
- XCTest से टेस्ट माइग्रेट करना — Apple
- अपने टेस्ट में स्टेट सेट अप और टियर डाउन करें — Apple
- स्विफ्ट टेस्टिंग README — स्विफ्ट प्रोजेक्ट
- अपने Xcode प्रोजेक्ट में टेस्ट जोड़ना — Apple
- एसिंक्रोनस कोड टेस्ट करना — Apple
- द स्विफ्ट प्रोग्रामिंग लैंग्वेज: कॉनकरेंसी — स्विफ्ट प्रोजेक्ट
- टेस्ट को क्रमिक या समानांतर में चलाना — Apple