JUnit भ्रम: 'TestCase का विस्तार' या '@ परीक्षण' का उपयोग करें?


152

मैंने JUnit का उचित उपयोग (या कम से कम प्रलेखन) बहुत भ्रामक पाया है। यह प्रश्न भविष्य के संदर्भ के रूप में और वास्तविक प्रश्न के रूप में दोनों कार्य करता है।

यदि मैंने सही ढंग से समझा है, तो JUnit परीक्षण बनाने और चलाने के लिए दो मुख्य दृष्टिकोण हैं:

दृष्टिकोण A (JUnit 3-शैली): एक क्लास बनाएं जो TestCase का विस्तार करता है, और शब्द के साथ परीक्षण विधियों को शुरू करें test। कक्षा को ज्यूनिट टेस्ट (ग्रहण में) के testरूप में चलाने पर , शब्द के साथ शुरू होने वाली सभी विधियाँ स्वचालित रूप से चलती हैं।

import junit.framework.TestCase;

public class DummyTestA extends TestCase {

    public void testSum() {
        int a = 5;
        int b = 10;
        int result = a + b;
        assertEquals(15, result);
    }
}

दृष्टिकोण बी (JUnit 4-शैली): एक 'सामान्य' वर्ग बनाएं और @Testविधि के लिए एनोटेशन प्रस्तुत करें। ध्यान दें कि आपको शब्द के साथ विधि शुरू करने की आवश्यकता नहीं है test

import org.junit.*;
import static org.junit.Assert.*;

public class DummyTestB {

    @Test
    public void Sum() {
        int a = 5;
        int b = 10;
        int result = a + b;
        assertEquals(15, result);
    }
}

दोनों को मिलाना एक अच्छा विचार नहीं है, उदाहरण के लिए देखें यह स्टैकओवरफ़्लो प्रश्न :

अब, मेरे प्रश्न:

  1. पसंदीदा तरीका क्या है , या आप एक के बजाय दूसरे का उपयोग कब करेंगे?
  2. दृष्टिकोण बी इस तरह @Test एनोटेशन का विस्तार करके अपवादों के परीक्षण के लिए अनुमति देता है @Test(expected = ArithmeticException.class)लेकिन दृष्टिकोण ए का उपयोग करते समय आप अपवादों के लिए कैसे परीक्षण करते हैं?
  3. दृष्टिकोण ए का उपयोग करते समय, आप एक परीक्षण सूट में कई परीक्षण कक्षाओं को इस तरह से समूहित कर सकते हैं:

    TestSuite suite = new TestSuite("All tests");
    suite.addTestSuite(DummyTestA.class);
    suite.addTestSuite(DummyTestAbis.class);

    लेकिन इसका उपयोग दृष्टिकोण बी के साथ नहीं किया जा सकता है (क्योंकि प्रत्येक टेस्टक्लास को टेस्टासैस को उपवर्ग करना चाहिए)। दृष्टिकोण बी के लिए समूह परीक्षणों का उचित तरीका क्या है?

संपादित करें: मैंने दोनों दृष्टिकोणों में JUnit संस्करण जोड़े हैं


मैंने देखा है extends TestCaseऔर फिर प्रत्येक परीक्षा को @Testकेवल चीजों को भ्रमित करने के लिए एनोटेट किया गया है। :)
ईएम-क्रिएशन

जवाबों:


119

भेद बल्कि आसान है:

  • विस्तार TestCaseकर रहा है जिस तरह से इकाई परीक्षण JUnit 3 में लिखा गया (बेशक यह अभी भी JUnit 4 में समर्थित है)
  • @Testएनोटेशन का उपयोग JUnit 4 द्वारा शुरू किया गया तरीका है

आम तौर पर आपको एनोटेशन पथ चुनना चाहिए, जब तक कि JUnit 3 (और / या जावा 5 से पहले के जावा संस्करण) के साथ संगतता की आवश्यकता न हो। नए तरीके के कई फायदे हैं:

  • @TestAnnotaton अधिक स्पष्ट है और उपकरणों में समर्थन करने के लिए आसान है (उदाहरण के लिए यह सब परीक्षण इस तरह के लिए खोज करने के लिए आसान है)
  • कई तरीकों से @Before/ @BeforeClassऔर @After/ और @AfterClassअधिक लचीलापन प्रदान करने के लिए एनोटेट किया जा सकता है
  • जैसी चीजों पर @Ruleटिप्पणी के लिए समर्थनExpectedException
  • @Ignoredएनोटेशन के लिए समर्थन
  • का उपयोग कर वैकल्पिक परीक्षण धावकों के लिए समर्थन @RunWith

JUnit 3 में अपेक्षित अपवादों का परीक्षण करने के लिए TestCaseआपको पाठ को स्पष्ट करना होगा।

public void testMyException() {
  try {
    objectUnderTest.myMethod(EVIL_ARGUMENT);
    fail("myMethod did not throw an Exception!");
  } catch (MyException e) {
    // ok!
    // check for properties of exception here, if desired
  }
}

JUnit 5 ने अभी तक एक और एपीआई परिवर्तन की शुरुआत की, लेकिन अभी भी एनोटेशन का उपयोग करता है। नया @Testएनोटेशन org.junit.jupiter.api.Test("पुराना" JUnit 4 एक था org.junit.Test) है, लेकिन यह JUnit 4 एक के समान ही काम करता है।


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

3
@thSoft: यह अक्सर ऐसा नहीं होता है कि इसका उपयोग किया जाता है, लेकिन कभी-कभी मैं यह सुनिश्चित करना चाहता हूं कि अपवाद विधि में आक्रामक क्षेत्र का उल्लेख है, उदाहरण के लिए। तब एक सरल assertTrue(e.getMessage().contains("foo"))उपयोगी हो सकता है।
जोकिम सॉयर

1
JUnit4 में भी यह एक महत्वपूर्ण मुहावरा है जब आपको संदेश या अपवाद की कुछ अन्य संपत्ति (जैसे कारण) की जांच करनी होती है। expectedविधि केवल प्रकार के लिए जाँच करता है।
यिशै

@Yishai: यह सच है, लेकिन ज्यादातर समय मैं पहले से ही संतुष्ट हूँ अगर विधि समस्याग्रस्त इनपुट पर सही प्रकार के अपवाद को फेंक देती है।
जोचिम सॉर

इस कारण से, JUnit 5 ने अपवाद परीक्षण में एक परिवर्तन किया। assertThrows () शानदार :-)
मार्कस के।

25

मेरे पास JUnit 4 (एनोटेशन अप्रोच) के लिए प्राथमिकता है क्योंकि मुझे यह अधिक लचीला लगता है।

यदि आप JUnit 4 में टेस्ट सूट बनाना चाहते हैं, तो आपको इस तरह के सभी परीक्षणों को समूहीकृत करते हुए एक वर्ग बनाना होगा:

import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;


@RunWith(Suite.class)
@SuiteClasses({
    Test1.class,
    Test2.class,
    Test3.class,
    Test4.class
})public class TestSuite
{
 /* empty class */
}

15

आपके प्रश्न का एक अनुत्तरित हिस्सा है, और वह है "दृष्टिकोण बी के लिए समूह परीक्षणों का उचित तरीका क्या है?"

आधिकारिक उत्तर यह है कि आप किसी कक्षा को @RunWith (Suite.class) के साथ एनोटेट करते हैं और फिर कक्षाओं को सूचीबद्ध करने के लिए @ Suite.SuiteClasses एनोटेशन का उपयोग करते हैं। यह कैसे JUnit डेवलपर्स इसे करते हैं (प्रत्येक वर्ग को एक सूट में मैन्युअल रूप से सूचीबद्ध करते हैं)। कई मायनों में यह दृष्टिकोण एक सुधार है, जिसमें सूट से पहले और सूट के व्यवहार के बाद जोड़ने के लिए यह तुच्छ और सहज है (बस एक @BeforeClass और @AfterClass विधि को वर्ग में @RunWith के साथ एनोटेट किया गया है - पुराने टेस्टफ़िक्सचर की तुलना में बेहतर है) )।

हालाँकि, यह एक कदम पीछे की ओर है, उस एनोटेशन में आप गतिशील रूप से कक्षाओं की सूची बनाने की अनुमति नहीं देते हैं, और उस समस्या के आसपास काम करना थोड़ा बदसूरत हो जाता है। आपको सुइट वर्ग को उप-वर्ग में रखना होगा और उप-वर्ग में गतिशील रूप से कक्षाओं की सरणी बनाना होगा और इसे सूट कंस्ट्रक्टर को पास करना होगा, लेकिन यह एक अधूरा समाधान है कि सूट के अन्य उप-वर्ग (जैसे श्रेणियाँ) इसके साथ और अनिवार्य रूप से काम नहीं करते हैं गतिशील टेस्ट क्लास संग्रह का समर्थन नहीं करते।


1
इसके लिए +1। टेस्टस्साइट में टेस्ट को जोड़ने के लिए एक गतिशील समाधान लिखने के लिए एक कार्य को शुरू करने के बाद, मुझे अपने प्रत्येक टेस्ट में टेस्टकेस का विस्तार करना पड़ा है। बदले में यह पहले से काम कर रहे यूनिट टेस्ट को तोड़ दिया है जिसमें अपेक्षित अपवादों को परिभाषित करने के लिए JUnit4 एनोटेशन का उपयोग किया गया था। टेस्ट सूट को गतिशील रूप से आबाद करने के तरीके के लिए मेरी खोज ने मुझे इस धागे तक
पहुंचा

4

आपको JUnit 4 का उपयोग करना चाहिए। यह बेहतर है।

JUnit 3.8 के समर्थन में बहुत सारी रूपरेखाएँ निकलना शुरू हो गई हैं।

यह स्प्रिंग 3.0 संदर्भ प्रलेखन से है:

[चेतावनी] विरासत JUnit 3.8 वर्ग पदानुक्रम पदावनत है

जब आप कुछ नया शुरू करते हैं, तो सामान्य तौर पर, आपको हमेशा एक फ्रेमवर्क के नवीनतम स्थिर रिलीज का उपयोग करने की कोशिश करनी चाहिए।


1
  1. "पसंदीदा" दृष्टिकोण एनोटेशन का उपयोग करना होगा जो जून 4 के बाद से पेश किए गए हैं। वे बहुत सारी चीजों को आसान बनाते हैं (दूसरी रिलीज देखें)

  2. आप इसके लिए एक सरल कोशिश / कैच ब्लॉक का उपयोग कर सकते हैं:


public void testForException() {
    try {
        Integer.parseInt("just a string");
        fail("Exception should have been thrown");
    } catch (final Exception e) {
        // expected
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.