मैं परीक्षण के दौरान एमुलेटर, या अपने डिवाइस पर कुछ मामलों में अपने ऐप को नष्ट करने के लिए अपने एंड्रॉइड ऐप में एस्सर कीवर्ड का उपयोग करना चाहता हूं । क्या यह संभव है?
ऐसा लगता है कि एमुलेटर सिर्फ मेरी बातों को नजरअंदाज करता है।
मैं परीक्षण के दौरान एमुलेटर, या अपने डिवाइस पर कुछ मामलों में अपने ऐप को नष्ट करने के लिए अपने एंड्रॉइड ऐप में एस्सर कीवर्ड का उपयोग करना चाहता हूं । क्या यह संभव है?
ऐसा लगता है कि एमुलेटर सिर्फ मेरी बातों को नजरअंदाज करता है।
जवाबों:
एपीआई JUnit मुखर प्रदान करता है ।
तुम कर सकते हो
import static junit.framework.Assert.*;
अब आप मुखर ढांचे में प्रदान किए गए सभी कार्यों जैसे कि मुखर, मुखर, मुखर का उपयोग कर सकते हैं।
ग्रहण के माध्यम से Junit4 ढांचे को आयात न करने के लिए सावधान रहें, यह org.junit पैकेज होगा। एंड्रॉइड डिवाइस या एमुलेटर पर काम करने के लिए आपको junit.framework पैकेज का उपयोग करना होगा।
एंबेडेड VM नियंत्रण दस्तावेज़ देखें ( स्रोत ट्री से कच्चा HTML , या एक अच्छी तरह से स्वरूपित प्रतिलिपि)।
मूल रूप से, Dalvik VM डिफ़ॉल्ट रूप से दावे की जाँच को अनदेखा करने के लिए सेट किया गया है, भले ही .dex बाइट कोड में चेक को करने के लिए कोड शामिल हो। दो तरीकों में से एक में जाँच की जाती है:
(1) सिस्टम प्रॉपर्टी को "debug.assert" द्वारा सेट करके:
adb shell setprop debug.assert 1
जो मैंने सत्यापित किया है कि जब तक आप यह करने के बाद अपने ऐप को पुन: स्थापित करते हैं, या तब तक काम करता है
(2) dalvik VM को कमांड लाइन तर्क "--enable-assert" भेजकर जो कि कुछ ऐप डेवलपर्स नहीं हो सकता है, ऐसा करने में सक्षम होने की संभावना है (कोई मुझे सही कर रहा है अगर मैं यहां गलत हूं)।
मूल रूप से, एक झंडा होता है जिसे या तो वैश्विक स्तर पर, एक पैकेज स्तर पर या एक वर्ग स्तर पर सेट किया जा सकता है जो उस संबंधित स्तर पर जोर देता है। ध्वज डिफ़ॉल्ट रूप से बंद है, जिसके परिणामस्वरूप अभिकथन चेक छोड़ दिया जाता है।
मैंने अपनी नमूना गतिविधि में निम्नलिखित कोड लिखा है:
public class AssertActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
int x = 2 + 3;
assert x == 4;
}
}
इस कोड के लिए, उत्पन्न होने वाली dalvik बाइट कोड (Android 2.3.3 के लिए) है:
// Static constructor for the class
000318: |[000318] com.example.asserttest.AssertActivity.:()V
000328: 1c00 0300 |0000: const-class v0, Lcom/example/asserttest/AssertActivity; // class@0003
00032c: 6e10 0c00 0000 |0002: invoke-virtual {v0}, Ljava/lang/Class;.desiredAssertionStatus:()Z // method@000c
000332: 0a00 |0005: move-result v0
000334: 3900 0600 |0006: if-nez v0, 000c // +0006
000338: 1210 |0008: const/4 v0, #int 1 // #1
00033a: 6a00 0000 |0009: sput-boolean v0, Lcom/example/asserttest/AssertActivity;.$assertionsDisabled:Z // field@0000
00033e: 0e00 |000b: return-void
000340: 1200 |000c: const/4 v0, #int 0 // #0
000342: 28fc |000d: goto 0009 // -0004
:
:
// onCreate()
00035c: |[00035c] com.example.asserttest.AssertActivity.onCreate:(Landroid/os/Bundle;)V
00036c: 6f20 0100 3200 |0000: invoke-super {v2, v3}, Landroid/app/Activity;.onCreate:(Landroid/os/Bundle;)V // method@0001
000372: 1501 037f |0003: const/high16 v1, #int 2130903040 // #7f03
000376: 6e20 0500 1200 |0005: invoke-virtual {v2, v1}, Lcom/example/asserttest/AssertActivity;.setContentView:(I)V // method@0005
00037c: 1250 |0008: const/4 v0, #int 5 // #5
00037e: 6301 0000 |0009: sget-boolean v1, Lcom/example/asserttest/AssertActivity;.$assertionsDisabled:Z // field@0000
000382: 3901 0b00 |000b: if-nez v1, 0016 // +000b
000386: 1251 |000d: const/4 v1, #int 5 // #5
000388: 3210 0800 |000e: if-eq v0, v1, 0016 // +0008
00038c: 2201 0c00 |0010: new-instance v1, Ljava/lang/AssertionError; // class@000c
000390: 7010 0b00 0100 |0012: invoke-direct {v1}, Ljava/lang/AssertionError;.:()V // method@000b
000396: 2701 |0015: throw v1
000398: 0e00 |0016: return-void
ध्यान दें कि स्टैटिक कंस्ट्रक्टर क्लास ऑब्जेक्ट पर वांछित वांछित डेटा को कैसे जमा करता है और क्लास-वाइड वैरिएबल $ assertionsDisabled सेट करता है; यह भी ध्यान दें कि onCreate () में, सभी कोड java.lang.AssertionError को फेंकने के लिए संकलित किया गया है, लेकिन इसका निष्पादन $ assertionsDisabled के मूल्य पर आकस्मिक है जो स्थिर निर्माण में क्लास ऑब्जेक्ट के लिए निर्धारित है।
ऐसा प्रतीत होता है कि JUnit का Assert वर्ग वह है जो मुख्य रूप से उपयोग किया जाता है, इसलिए इसका उपयोग करने के लिए एक सुरक्षित शर्त होने की संभावना है। मुखर खोजशब्द का लचीलापन विकास के समय में अभिकर्मकों को चालू करने और उन्हें शिपिंग बिट्स के लिए बंद करने की क्षमता है और इसके बजाय शालीनता से विफल हो जाते हैं।
उम्मीद है की यह मदद करेगा।
import static junit.framework.Assert.*
और फिर मैं इसके किसी एक तरीके का उपयोग करता हूं, जैसे assertNotNull("It's null!", someObject);
, क्या यह दावा शिपिंग बिट्स में बंद हो गया है?
adb shell setprop debug.assert 1
ग्रहण करने का कोई तरीका है ?
su
, फिर setprop debug.assert 1
। ध्यान दें कि जो कोड आपको असंतुष्ट दिखाते हैं, वह रिलीज़ बिल्ड ( stackoverflow.com/a/5590378/50907373 ) पर रहेगा । मुझे विश्वास नहीं है कि जेवैक कंपाइलर को कथनों का उत्सर्जन नहीं करने के लिए कहा जा सकता है, इसलिए उन्हें किसी तरह छीनने की जरूरत है। इसका एक सरल उपाय यह है कि आप अपने स्वयं के फंक्शन में कीवर्ड अस्सेर को लपेटें जो कि आपके लिए प्रागार्ड स्ट्रिप कर सकता है।
जब दावे सक्षम होते हैं, तो बूलियन अभिव्यक्ति होने पर assert
कीवर्ड बस फेंकता AssertionError
है false
।
तो IMO, सबसे अच्छा विकल्प, esp। यदि आप कनिष्ठ पर निर्भर होना चाहते हैं, तो AssertionError
नीचे दिखाए अनुसार स्पष्ट रूप से फेंकना है :
assert x == 0 : "x = " + x;
उपरोक्त कथन का एक विकल्प है:
Utils._assert(x == 0, "x = " + x);
जहां विधि को इस प्रकार परिभाषित किया गया है:
public static void _assert(boolean condition, String message) {
if (!condition) {
throw new AssertionError(message);
}
}
Oracle जावा डॉक्स स्वीकार्य विकल्प के रूप में फेंकने की सलाह देते हैंAssertionError
।
मुझे लगता है कि आप प्रोडक्शन कोड के लिए इन कॉल्स को हटाने के लिए Proguard को कॉन्फ़िगर कर सकते हैं।
"एंड्रॉइड इन प्रैक्टिस" में इसका उपयोग करने का सुझाव दिया गया है:
$adb shell setprop dalvik.vm.enableassertions all
यदि यह सेटिंग आपके फ़ोन पर बनी नहीं है, तो आप /data/local.prop फ़ाइल को गुणों के साथ बना सकते हैं:
dalvik.vm.enableassertions=all
chmod 644
)।
यह मेरे लिए नरक को कम कर रहा था, कि मेरे दावे ने काम नहीं किया, जब तक कि मैंने Google पर इस मुद्दे की जांच नहीं की ... मैंने सरल अभिकथन पर ध्यान दिया और जूनियर तरीकों के साथ जाना होगा।
सुविधा प्रयोजनों के लिए मैं उपयोग कर रहा हूँ:
स्थैतिक junit.framework.Assert। * आयात करें;
स्थिर आयात के कारण मैं बाद में लिख सकता हूं:
assertTrue (...); इसके बजाय Assert.assertTrue (...);
यदि आप (या किसी अन्य वर्ग पथ) में JUnit के साथ शिपिंग कोड के बारे में चिंतित हैं, तो आप ProGuard कॉन्फिगर विकल्प 'ग्रहण' का उपयोग कर सकते हैं, जो इस धारणा पर एक क्लास का रास्ता निकाल देगा कि यह कोड को कुछ भी नहीं करता है। ।
उदाहरण के लिए।
-assumenosideeffects junit.framework.Assert {
*;
}
मेरे पास एक सामान्य डीबग लाइब्रेरी है मैंने अपने सभी परीक्षण तरीकों को रखा, और फिर अपने जारी किए गए एप्लिकेशन से इसे हटाने के लिए इस विकल्प का उपयोग करें।
यह स्ट्रिंग्स के हेरफेर की समस्या को भी दूर करता है, जिसे रिलीज कोड में कभी इस्तेमाल नहीं किया जाता है। उदाहरण के लिए यदि आप एक डीबग लॉग विधि लिखते हैं, और उस विधि में आप स्ट्रिंग लॉग करने से पहले डीबग मोड की जाँच करते हैं, तो आप अभी भी स्ट्रिंग का निर्माण कर रहे हैं, मेमोरी आवंटित कर रहे हैं, विधि को कॉल कर रहे हैं, लेकिन फिर कुछ भी नहीं करने का विरोध कर रहे हैं। क्लास को स्ट्रिप करना फिर कॉल को पूरी तरह से हटा देता है, मतलब जब तक आपका स्ट्रिंग मेथड कॉल के अंदर निर्मित नहीं हो जाता है, तब तक यह चला जाता है।
सुनिश्चित करें कि यह वास्तव में सिर्फ लाइनों को बाहर निकालने के लिए सुरक्षित है, क्योंकि यह प्रोगार्ड के हिस्से पर कोई जाँच नहीं है। किसी भी शून्य वापसी विधि को हटाना ठीक होगा, हालाँकि यदि आप जो भी हटा रहे हैं, उससे कोई वापसी मान ले रहे हैं, तो सुनिश्चित करें कि आप वास्तविक परिचालन तर्क के लिए उनका उपयोग नहीं कर रहे हैं।
-assumenosideeffects class junit.framework.Assert { *; }
आप अभिकथन का उपयोग कर सकते हैं, लेकिन उन्हें मज़बूती से उपयोग करने के लिए कुछ काम लगते हैं। सिस्टम की संपत्ति debug.assert
अविश्वसनीय है; 175697 , 65183 , 36786 और 17324 मुद्दे देखें ।
एक विधि यह है assert
कि किसी भी क्रम से निपटने के लिए प्रत्येक कथन का अनुवाद किया जाए। जावा कंपाइलर के सामने एक स्रोत प्रीप्रोसेसर के साथ ऐसा करें। उदाहरण के लिए, इस कथन को लें:
assert x == 0: "Failure message";
डीबग बिल्ड के लिए, आपका प्रीप्रोसेसर किसी if
कथन के लिए उपरोक्त का अनुवाद करेगा :
{ if( !(x == 0) ) throw new AssertionError( "Failure message" ); }
एक निर्माण के लिए, एक खाली बयान के लिए:
;
ध्यान दें कि यह निर्माण समय पर जोर को नियंत्रित करेगा, जैसा कि समय चलाने (सामान्य अभ्यास) के विपरीत है।
मुझे कोई रेडीमेड प्रीप्रोसेसर नहीं मिला, इसलिए मैंने एक स्क्रिप्ट की । दावे के साथ काम करने वाले भाग को देखें। कॉपी करने का लाइसेंस यहाँ है ।
जुगिटिया को जुनीत को बाहर करने के जवाब में जोड़ने के लिए - प्रोगार्ड पहले से ही एंड्रॉइड एसडीके / एक्लिप्स का हिस्सा है और निम्न पृष्ठ आपको बताता है कि इसे कैसे सक्षम किया जाए।
http://developer.android.com/guide/developing/tools/proguard.html
इसके अलावा उपरोक्त अभ्यस्त नवीनतम डिफ़ॉल्ट गार्ड विन्यास के साथ काम करता है क्योंकि यह -dontoptimize ध्वज का उपयोग करता है जिसे बाहर ले जाना चाहिए और कुछ अनुकूलन चालू हो गए।
उदाहरण के लिए, मानक जावा मुखर खोजशब्द का प्रयोग करें :
assert a==b;
इस काम के लिए, आपको /system/build.prop, और रिबूट फोन में एक पंक्ति जोड़ना होगा:
debug.assert=1
यह रूट किए गए फोन पर काम करेगा। Build.prop (जैसे X-plore) को संपादित करने में सक्षम कुछ फ़ाइल प्रबंधक का उपयोग करें।
प्लसस: अधिकांश (सभी?) एंड्रॉइड फोन जहाज के साथ अक्षम हैं। यहां तक कि अगर आपका कोड गलती से झूठे का दावा करता है, तो ऐप बाधित या दुर्घटना नहीं करेगा। हालाँकि, आपके विकास उपकरण पर आपको अभिकथन अपवाद मिलेगा।