एंड्रॉइड स्टूडियो यूनिट परीक्षण: डेटा (इनपुट) फ़ाइल पढ़ें


96

एक इकाई परीक्षण में, मैं अपने डेस्कटॉप (डेस्कटॉप) फ़ाइल सिस्टम पर एक जेसन फ़ाइल से पथ को हार्डकोड किए बिना कैसे पढ़ सकता हूं?

मैं स्टैटिक स्ट्रिंग्स बनाने के बजाय एक फ़ाइल से टेस्ट इनपुट (मेरे पार्सिंग विधियों के लिए) पढ़ना चाहूंगा।

फ़ाइल मेरे इकाई परीक्षण कोड के समान स्थान पर है, लेकिन यदि आवश्यक हो तो मैं इसे परियोजना में कहीं और रख सकता हूं। मैं एंड्रॉइड स्टूडियो का उपयोग कर रहा हूं।


3
मैंने IOUtils.toString (this.getClass ()। GetResourceAsStream ("test_documents.json"), "UTF-8") के साथ लगभग हर संयोजन की कोशिश की, यह हमेशा अशक्त देता है। शायद क्योंकि फाइलें जार में शामिल नहीं होंगी।
फ्रैंक

क्या हम एंड्रॉइड एमुलेटर / डिवाइस से जुड़े यूनिट परीक्षणों के बारे में बात कर रहे हैं?
AndroidEx

@ Android777 मुझे लगता है कि हम नए स्टूडियो टेस्ट सपोर्ट के बारे में बात कर रहे हैं जो Android Studio tools.android.com/tech-docs/unit-testing-support
akhy

@ फ्रेंक तुम कहाँ हो test_documents.json? संपत्ति निर्देशिका?
akhy

हाँ, हम एमुलेटर / डिवाइस को शामिल नहीं करते हुए नई इकाई परीक्षण सहायता के बारे में बात कर रहे हैं। मैंने इसे आस्तियों में जगह नहीं दी, क्योंकि तब इसे लाइव एपीके के साथ पैक किया जाता है। मैंने इसे परीक्षण (जावा) फ़ाइलों के समान फ़ोल्डर में रखा।
फ्रैंक

जवाबों:


149

android-gradle-pluginसंस्करण पर निर्भर करता है :

1. संस्करण 1.5 और उच्चतर:

बस के रूप में json फ़ाइल डाल दिया src/test/resources/test.jsonऔर इसे संदर्भ दें

classLoader.getResource("test.json"). 

किसी भी प्रकार के संशोधन की आवश्यकता नहीं है।

2. संस्करण 1.5 से नीचे : (या यदि किसी कारण से ऊपर समाधान काम नहीं करता है)

  1. सुनिश्चित करें कि आप कम से कम Android ग्रेडल प्लगिन संस्करण 1.1 का उपयोग कर रहे हैं । Android Studio को सही तरीके से सेट करने के लिए लिंक का अनुसरण करें।

  2. testनिर्देशिका बनाएँ । इकाई परीक्षण कक्षाओं को javaनिर्देशिका में रखें और अपनी संसाधन फ़ाइल को resनिर्देशिका में रखें। Android Studio को उनका अनुसरण करना चाहिए:

    यहां छवि विवरण दर्ज करें

  3. gradleउन्हें दिखाने के लिए कक्षाओं निर्देशिका में संसाधनों की प्रतिलिपि बनाने के लिए कार्य बनाएँ classloader:

    android{
       ...
    }
    
    task copyResDirectoryToClasses(type: Copy){
        from "${projectDir}/src/test/res"
        into "${buildDir}/intermediates/classes/test/debug/res"
    }
    
    assembleDebug.dependsOn(copyResDirectoryToClasses)
    
  4. अब आप Fileफ़ाइल संसाधन के लिए संदर्भ प्राप्त करने के लिए इस विधि का उपयोग कर सकते हैं :

    private static File getFileFromPath(Object obj, String fileName) {
        ClassLoader classLoader = obj.getClass().getClassLoader();
        URL resource = classLoader.getResource(fileName);
        return new File(resource.getPath());
    }
    
    @Test
    public void fileObjectShouldNotBeNull() throws Exception {
        File file = getFileFromPath(this, "res/test.json");
        assertThat(file, notNullValue());
    }
    
  5. पूरे क्लास या स्पेसिफिक टेस्ट पद्धति पर Ctrl+ Shift+ द्वारा यूनिट टेस्ट चलाएं F10

1
बहुत बढ़िया! आपका एडिट, बिना इंस्ट्रूमेंट के, एक आकर्षण की तरह काम करता है, धन्यवाद!
फ्रैंक

4
यह एक अच्छा समाधान है, लेकिन यह हमेशा काम नहीं करता है। यदि आप क्लीन टास्क चलाते हैं, और फिर टेस्टडबग रन करते हैं तो यह विफल हो जाता है। मूल रूप से डेवलपर को यह जानने की जरूरत है कि उसे टेस्टडबग से पहले असेंबडबग कार्य चलाना होगा। क्या आप लोगों के पास इसे सुधारने का कोई सुझाव है?
joaoprudencio

18
Android प्लगइन के साथ AndroidStudio 1.5 के साथ 1.5.0 अपनी json फ़ाइल को यहाँ रखें src/test/resources/test.jsonऔर इसे संदर्भ दें classLoader.getResource("test.json")। किसी भी प्रकार के संशोधन की आवश्यकता नहीं है। अंदर नेस्टेड फ़ोल्डर resourcesभी काम कर रहे हैं।
सेर्गेई पेचेनिस्की

6
अधूरा जवाब। क्या है classLoader? कोड की इस पंक्ति को कहां रखें? आप वापसी परिणाम के साथ क्या कर सकते हैं? कृपया अधिक पूर्ण कोड प्रदान करें। -1
वोगदेव 13

3
./src/test/resources/file.txtकोटलिन में पढ़ने के लिए :TestClassName::class.java.getResource("/file.txt")!!.readText()
एरिक

76

स्थानीय इकाई परीक्षणों (बनाम इंस्ट्रूमेंटेशन टेस्ट) के लिए, आप फाइलों को नीचे रख सकते हैं src/test/resourcesऔर उन्हें क्लासरूम का उपयोग करके पढ़ सकते हैं। उदाहरण के लिए, myFile.txtसंसाधन निर्देशिका में निम्न कोड फ़ाइल खोलता है ।

InputStream in = this.getClass().getClassLoader().getResourceAsStream("myFile.txt");

इसके साथ काम किया

  • एंड्रॉइड स्टूडियो 1.5.1
  • ढाल प्लगइन 1.3.1

यह काम नहीं कर रहा मुझे यहाँ मेरे सवाल को देखने के लिए कृपया के लिए stackoverflow.com/questions/36295824/...
टायलर फाफ

5
यह मेरे लिए काम करता है, जब मैं "src / test / res" से बदलकर "src / test / Resources" हो जाता हूं। एंड्रॉइड स्टूडियो 2.0 आरसी 3, ग्रेडेल का उपयोग करना: 2.0.0-आरसी 3
एलेक्स ब्रावो

उम्मीद के मुताबिक काम किया। लेकिन परीक्षण पास हो रहा है भले ही फ़ाइल "src / test / resource /" उदा: "rules.xml" के तहत उपलब्ध न हो, लेकिन InputStream इस मामले में अशक्त होता है।
अनंद कृष

4
kotlin:val myFile = ClassLoader.getSystemResource("myFile.txt").readText()
जे जे।

आकर्षण की तरह काम किया!
अमित भंडारी

15

मेरे मामले में, समाधान को फ़ाइल में जोड़ना था

sourceSets {
    test.resources.srcDirs += 'src/unitTests/resources'
  } 

इसके बाद एएस 2.3.1 द्वारा सब कुछ पाया गया

javaClass.classLoader.getResourceAsStream("countries.txt")

मैंने कुछ इसी तरह (कोटलिन) किया था: 1. फोल्डर और फ़ाइल बनाएं: root/app/src/test/resources/test.json 2. इस तरह डेटा पढ़ें:val jsonFile = ClassLoader.getSystemResource("test.json").readText()
जे जे।

8

मुझे एंड्रॉइड स्टूडियो में परीक्षण संसाधनों के साथ बहुत सारी समस्याएं हैं इसलिए मैंने स्पष्टता के लिए कुछ परीक्षण स्थापित किए। मेरी mobile(Android Application) परियोजना में मैंने निम्नलिखित फाइलें जोड़ीं:

mobile/src/test/java/test/ResourceTest.java
mobile/src/test/resources/test.txt
mobile/src/test/resources/test/samePackage.txt

परीक्षण वर्ग (सभी परीक्षण पास):

assertTrue(getClass().getResource("test.txt") == null);
assertTrue(getClass().getResource("/test.txt").getPath().endsWith("test.txt"));
assertTrue(getClass().getResource("samePackage.txt").getPath().endsWith("test/samePackage.txt"));
assertTrue(getClass().getResource("/test/samePackage.txt").getPath().endsWith("test/samePackage.txt"));
assertTrue(getClass().getClassLoader().getResource("test.txt").getPath().endsWith("test.txt"));
assertTrue(getClass().getClassLoader().getResource("test/samePackage.txt").getPath().endsWith("test/samePackage.txt"));

उसी रूट प्रोजेक्ट में मेरे पास एक जावा (एंड्रॉइड नहीं) प्रोजेक्ट है data। यदि मैं डेटा प्रोजेक्ट में समान फ़ाइलें जोड़ता हूं:

data/src/test/java/test/ResourceTest.java
data/src/test/resources/test.txt
data/src/test/resources/test/samePackage.txt

फिर उपरोक्त सभी परीक्षण विफल हो जाएंगे यदि मैं उन्हें एंड्रॉइड स्टूडियो से निष्पादित करता हूं, लेकिन वे कमांड लाइन पर गुजरते हैं ./gradlew data:test। इसके आसपास जाने के लिए मैं इस हैक का उपयोग करता हूं (ग्रूवी में)

def resource(String path) {
    getClass().getResource(path) ?:
            // Hack to load test resources when executing tests from Android Studio
            new File(getClass().getClassLoader().getResource('.').path
                    .replace('/build/classes/test/', "/build/resources/test$path"))
}

उपयोग: resource('/test.txt')

एंड्रॉइड स्टूडियो 2.3, ग्रैडल 3.3


शानदार उत्तर (खोज के 45 मिनट के बाद min)। यह कई मुद्दों के दिल में उतर जाता है और स्वयं परीक्षणों का उपयोग करके परिणामों को दोहराने में आसान बनाता है। Fwiw, के रूप में 2.3.1, ग्रेडेल 2.3.1 में, getClassLoader()संस्करण अपेक्षित रूप से काम करते हैं। यानी वे फाइलें ढूंढते हैं, दोनों एंड्रॉइड स्टूडियो और कमांड लाइन से मेरे macOS मशीन पर और लिनक्स CI सर्वर (सर्किलसीआई) पर चलते हैं। तो मैं उस के साथ जा रहा हूँ और उम्मीद है कि ग्रेड 3 3.3 बाद में इसे नहीं तोड़ देगा ...
mm2001

अच्छा! मैं यहाँ वही संसाधन लोडिंग समस्या देख रहा हूँ। २.३.२, ग्रेड ३.३ के रूप में। build/resources/testइंटरएक्टिव क्लासपाथ में शामिल नहीं होने के कारण परीक्षण कमांड लाइन से नहीं बल्कि एएस के माध्यम से काम करते हैं ।
मार्क मैककेना

6

यदि आप रन -> एडिटिंग कंफिगरेशन -> जुनाइट पर जाते हैं और फिर अपने यूनिट टेस्ट के लिए रन कॉन्फ़िगरेशन का चयन करते हैं, तो एक 'वर्किंग डायरेक्टरी' सेटिंग होती है। यह इंगित करना चाहिए कि आपकी json फ़ाइल जहाँ भी है। ध्यान रखें कि इससे अन्य परीक्षण टूट सकते हैं।


और इस का उपयोग करने से .getClass ()। getResourceAsStream (test.json)? मैंने वहां फाइलों को जोड़ा, परियोजना की जड़ में, यह अभी भी फाइलें नहीं ढूंढता है।
फ्रैंक

इसका उपयोग करके new File()या इसी तरह की फ़ाइलों को लोड करने के लिए किया जा सकता है , लेकिन यह ऊपर वर्णित क्लासपैथ लोडिंग विधि के साथ सीधे काम नहीं करता है। यह थोड़ा मुश्किल भी है क्योंकि प्रत्येक नए रन कॉन्फ़िगरेशन को काम करने वाले डायर को सेट करने की आवश्यकता होती है, और डिफ़ॉल्ट रूप से एएस और ग्रैडल कमांड लाइन अलग-अलग काम करने वाले डायर का उपयोग करना पसंद करती है ... ऐसा दर्द
मार्क मैककेना

4

हालाँकि मुझे अपने निष्कर्ष यहाँ जोड़ने चाहिए। मुझे पता है कि यह थोड़ा पुराना है, लेकिन ग्रैडल के नए संस्करणों के लिए, जहां NO src / test / resource directory है, लेकिन पूरे प्रोजेक्ट के लिए केवल एक ही संसाधन निर्देशिका है, आपको इस लाइन को अपनी Gradle फ़ाइल में जोड़ना होगा।

android {
   testOptions {
      unitTests {
         includeAndroidResources = true
      }
    }
}

ऐसा करने से आप अपने संसाधन तक पहुँच सकते हैं:

 this.getClass().getClassLoader().getResourceAsStream(fileName);

मैं इसके लिए खोज कर रहा हूं और मुझे इसका जवाब नहीं मिला, इसलिए मैंने यहां दूसरों की मदद करने का फैसला किया।


1

वास्तव में, यह मेरे लिए इंस्ट्रूमेंटेशन टेस्ट (रनिंग एंड्रॉइड स्टूडियो संस्करण 3.5.3 , एंड्रॉइड ग्रैगल प्लगिन संस्करण 3.5.3 , ग्रेड संस्करण 6.0.1 ) के साथ काम किया है:

  1. अपनी फ़ाइलों को src/androidTest/assetsफ़ोल्डर में रखें
  2. आपकी परीक्षण फ़ाइल में:

InputStream is = InstrumentationRegistry.getInstrumentation().getContext().getAssets().open("filename.txt");

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