JUnit परीक्षण के गतिशील संख्या के साथ परीक्षण


95

हमारी परियोजना में मेरे पास कई JUnit परीक्षण हैं जो उदाहरण के लिए प्रत्येक फ़ाइल को एक निर्देशिका से लेते हैं और उस पर एक परीक्षण चलाते हैं। अगर मैं इसमें एक testEveryFileInDirectoryविधि लागू करता हूं तो TestCaseकेवल एक परीक्षण के रूप में पता चलता है जो विफल या सफल हो सकता है। लेकिन मैं प्रत्येक व्यक्तिगत फ़ाइल पर परिणामों में रुचि रखता हूं। मैं एक TestCase/ TestSuiteऐसी कैसे लिख सकता हूं कि प्रत्येक फ़ाइल एक अलग परीक्षण के रूप में दिखती है जैसे कि ग्रहण के ग्राफिकल टेस्टरनर में? (प्रत्येक फ़ाइल के लिए एक स्पष्ट परीक्षण विधि कोडिंग एक विकल्प नहीं है।)

एक्लिप्स टेस्टरनर में एक नाम के साथ ParameterizedTest प्रश्न की तुलना करें ।


जवाबों:


102

JUnit 4 में Parameterized टेस्ट पर एक नज़र डालें ।

दरअसल मैंने कुछ दिन पहले ऐसा किया था। मैं समझाने की कोशिश करूँगा ...

सबसे पहले अपने टेस्ट क्लास को सामान्य रूप से बनाएं, जैसे कि आप सिर्फ एक इनपुट फाइल के साथ टेस्ट कर रहे हैं। अपनी कक्षा को इसके साथ सजाएँ:

@RunWith(Parameterized.class)

प्रत्येक परीक्षण कॉल में परिवर्तन करने वाला इनपुट लेने वाला एक निर्माता बनाएँ (इस मामले में यह फ़ाइल ही हो सकती है)

फिर, एक स्थिर विधि का निर्माण करें जो Collectionएरे की वापसी करेगा । संग्रह में प्रत्येक सरणी में आपके क्लास कंस्ट्रक्टर जैसे फ़ाइल के लिए इनपुट तर्क होंगे। इस विधि से सजाएँ:

@Parameters

यहाँ एक नमूना वर्ग है।

@RunWith(Parameterized.class)
public class ParameterizedTest {

    private File file;

    public ParameterizedTest(File file) {
        this.file = file;
    }

    @Test
    public void test1() throws Exception {  }

    @Test
    public void test2() throws Exception {  }

    @Parameters
    public static Collection<Object[]> data() {
        // load the files as you want
        Object[] fileArg1 = new Object[] { new File("path1") };
        Object[] fileArg2 = new Object[] { new File("path2") };

        Collection<Object[]> data = new ArrayList<Object[]>();
        data.add(fileArg1);
        data.add(fileArg2);
        return data;
    }
}

इस उदाहरण को भी देखें


1
धन्यवाद! JUnit 4 मेथड दूसरे उत्तर में दिए गए JUnit 3 मेथड से बेहतर है, क्योंकि JUnit 3 एक्लिप्स टेस्ट रनर को भ्रमित करता है और JUnit 4 मेथड के साथ आप टेस्ट आदि को फिर से निष्पादित कर सकते हैं। मैं केवल यह सोच रहा हूं कि मैं कैसे ग्रहण कर सकता हूं। परीक्षण के लिए नाम - यह केवल दिखाता है [०], [१] आदि
हंस-पीटर स्टॉर

@hstoerr, लगता है कि यह JUnit :-) की अगली रिलीज में होगा। github.com/KentBeck/junit/commit/…
rescdsk

यदि आप प्रत्येक रन [एक अलग डेटा संयोजन के साथ] चाहते थे, तो आप इसे कैसे बदलेंगे? [Ie Path1 फ़ाइल का परीक्षण इस प्रकार किया जाएगा: test1Path1, test2Path?
7


27

JUnit 3

public class XTest extends TestCase {

    public File file;

    public XTest(File file) {
        super(file.toString());
        this.file = file;
    }

    public void testX() {
        fail("Failed: " + file);
    }

}

public class XTestSuite extends TestSuite {

    public static Test suite() {
        TestSuite suite = new TestSuite("XTestSuite");
        File[] files = new File(".").listFiles();
        for (File file : files) {
            suite.addTest(new XTest(file));
        }
        return suite;
    }

}

JUnit 4

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class TestY {

    @Parameters
    public static Collection<Object[]> getFiles() {
        Collection<Object[]> params = new ArrayList<Object[]>();
        for (File f : new File(".").listFiles()) {
            Object[] arr = new Object[] { f };
            params.add(arr);
        }
        return params;
    }

    private File file;

    public TestY(File file) {
        this.file = file;
    }

    @Test
    public void testY() {
        fail(file.toString());
    }

}

11

जूनित 5 परिमार्जित परीक्षण

JUnit 5 पैरामीटराइज्ड परीक्षण डेटा स्रोत के रूप में एक विधि के उपयोग की अनुमति देकर इसका समर्थन करते हैं :

@ParameterizedTest
@MethodSource("fileProvider")
void testFile(File f) {
    // Your test comes here
}

static Stream<File> fileProvider() {
    return Arrays.asList(new File(".").list()).stream();
}

JUnit 5 डायनामिकटेस्ट

JUnit 5 भी एक की धारणा के माध्यम से इसका समर्थन करता है DynamicTest, जिसे @TestFactoryस्थैतिक विधि के द्वारा एक में उत्पन्न किया जाना है dynamicTest

import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import static org.junit.jupiter.api.DynamicTest.dynamicTest;

import java.util.stream.Stream;

@TestFactory
public Stream<DynamicTest> testFiles() {
    return Arrays.asList(new File(".").list())
            .stream()
            .map((file) -> dynamicTest(
                    "Test for file: " + file,
                    () -> { /* Your test comes here */ }));
}

आपके आईडीई (यहां IntelliJ) में चलाए गए परीक्षण इस तरह प्रदर्शित किए जाएंगे:

IntelliJ में आउटपुट


3

JUnit 3 में फ़ाइलों को सूचीबद्ध करने के लिए विधि से TestSuiteओवरराइड करके tests()और प्रत्येक के लिए संभव हो सकता है कि प्रत्येक उप-वर्ग के एक उदाहरण के TestCaseलिए फ़ाइल नाम को निर्माता पैरामीटर के रूप में लेता है और एक परीक्षण विधि है जो निर्माणकर्ता में दी गई फ़ाइल का परीक्षण करता है।

JUnit 4 में यह और भी आसान हो सकता है।


2

आप JUnitParams लाइब्रेरी का उपयोग करने पर विचार कर सकते हैं , इसलिए आपके पास कुछ और (क्लीनर) विकल्प होंगे:

@org.junit.runner.RunWith(junitparams.JUnitParamsRunner.class)
public class ParameterizedTest {

    @org.junit.Test
    @junitparams.Parameters(method = "data")
    public void test1(File file) throws Exception {  }

    @org.junit.Test
    @junitparams.Parameters(method = "data")
    public void test2(File file) throws Exception {  }

    public static File[] data() {
        return new File[] { new File("path1"), new File("path2") };
    }
}

@org.junit.runner.RunWith(junitparams.JUnitParamsRunner.class)
public class ParameterizedTest {

    @org.junit.Test
    @junitparams.Parameters(value = { "path1", "path2" })
    public void test1(String path) throws Exception {
        File file = new File(path);
    }

    @org.junit.Test
    @junitparams.Parameters(value = { "path1", "path2" })
    public void test2(String path) throws Exception {
        File file = new File(path);
    }
}

आप उपयोग के अधिक नमूने यहां देख सकते हैं ।

JUnitParams के बारे में, इसके साथ पैरामीटर परीक्षण को आसान और अधिक पठनीय क्यों बनाना है :

JUnitParams प्रोजेक्ट JUnit में एक नया धावक जोड़ता है और JUnit> = 4.6 के लिए बहुत आसान और पठनीय परिमाणित परीक्षण प्रदान करता है।

मानक JUnit पैरामीटर धावक के लिए मुख्य अंतर:

  • और अधिक स्पष्ट - परीक्षा पद्धति में परीक्षाएं होती हैं, वर्ग फ़ील्ड नहीं
  • कम कोड - आपको पैरामीटर सेट करने के लिए कंस्ट्रक्टर की आवश्यकता नहीं है
  • आप एक वर्ग में गैर-पैरामीट्रिक तरीकों से पैराट्राइज्ड मिश्रण कर सकते हैं
  • params को CSV स्ट्रिंग के रूप में या पैरामीटर प्रदाता वर्ग से पारित किया जा सकता है
  • पैरामीटर प्रदाता वर्ग में आपके द्वारा दिए गए तरीकों के रूप में कई पैरामीटर हो सकते हैं, ताकि आप विभिन्न मामलों को समूह बना सकें
  • आपके पास एक परीक्षण विधि हो सकती है जो पैरामीटर प्रदान करती है (अब कोई बाहरी कक्षाएं या स्टैटिक्स नहीं)
  • आप अपने IDE में वास्तविक पैरामीटर मान देख सकते हैं (JUnit के पैरामीटर में यह केवल मापदंडों की लगातार संख्या है)

1

यदि TestNG एक विकल्प है, तो आप DataProviders के साथ पैरामीटर का उपयोग कर सकते हैं ।

प्रत्येक व्यक्ति की फ़ाइल के परीक्षण का परिणाम पाठ-आधारित रिपोर्ट या एक्लिप्स के TestNG प्लगइन UI में दिखाया जाएगा। कुल चलाए जाने वाले परीक्षणों की संख्या आपकी प्रत्येक फ़ाइल को व्यक्तिगत रूप से गिनेंगी।

यह व्यवहार JUnit सिद्धांतों से भिन्न होता है , जिसमें सभी परिणाम एक "सिद्धांत" प्रविष्टि के तहत लुम्प होते हैं और केवल 1 परीक्षण के रूप में गिना जाता है। यदि आप JUnit में अलग रिजल्ट रिपोर्टिंग चाहते हैं, तो आप Parameterized टेस्ट की कोशिश कर सकते हैं ।

परीक्षण और इनपुट

public class FileTest {

    @DataProvider(name="files")
    public File[][] getFiles(){
        return new File[][] {
            { new File("file1") },
            { new File("file2") }
        };
        // or scan a directory
    }

    @Test(dataProvider="files")
    public void testFile(File file){
        //run tests on file
    }
}

उदाहरण आउटपुट

PASSED: testFile(file1)
PASSED: testFile(file2)

===============================================
    Default test
    Tests run: 2, Failures: 0, Skips: 0
===============================================

मैं सिद्धांतों के बारे में नहीं जानता, लेकिन JUnit में पैरामीटर किए गए परीक्षणों को ग्रहण में अलग-अलग दिखाया गया है, एक साथ नहीं।
हंस-पीटर स्टॉर्र

0

मुझे एक समान समस्या थी और एक साधारण JUnit 4 रनर लिखना समाप्त कर दिया, जो कि गतिशील रूप से परीक्षणों को उत्पन्न करने की अनुमति देता है।

https://github.com/kimble/junit-test-factory

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.