Android
JUnit के साथ एंड्रॉइड में यूनिट परीक्षण
खोज…
टिप्पणियों
- वोगेला: जेयूनाइट के साथ यूनिट परीक्षण
- जूनोट एनोटेशन: java2novice.com
- Assert Class: junit.org
- JUnit Api: tutorialspoint.com
- मीडियम परीक्षण
स्थानीय इकाई परीक्षण बनाना
अपनी परीक्षा कक्षाएं यहाँ रखें: /src/test/<pkg_name>/
उदाहरण परीक्षण वर्ग
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
int a=4, b=5, c;
c = a + b;
assertEquals(9, c); // This test passes
assertEquals(10, c); //Test fails
}
}
टूट - फूट
public class ExampleUnitTest {
...
}
परीक्षण वर्ग, आप कई परीक्षण कक्षाएं बना सकते हैं और उन्हें परीक्षण पैकेज के अंदर रख सकते हैं।
@Test
public void addition_isCorrect() {
...
}
परीक्षण विधि, एक परीक्षण वर्ग के अंदर कई परीक्षण विधियां बनाई जा सकती हैं।
एनोटेशन @Test
ध्यान @Test
।
टेस्ट एनोटेशन JUnit को बताता है कि सार्वजनिक शून्य विधि जिससे इसे संलग्न किया जाता है, परीक्षण केस के रूप में चलाया जा सकता है।
@Before
, @After
आदि जैसे कई अन्य उपयोगी एनोटेशन हैं। यह पेज शुरू करने के लिए एक अच्छी जगह होगी।
assertEquals(9, c); // This test passes
assertEquals(10, c); //Test fails
ये विधियाँ Assert
वर्ग की सदस्य हैं। कुछ अन्य उपयोगी विधियाँ assertFalse()
, assertNotNull()
, assertTrue
आदि यहाँ एक विस्तृत व्याख्या है ।
JUnit टेस्ट के लिए सूचना नोट:
@ टेस्ट : टेस्ट एनोटेशन जेयूनिट को बताता है कि सार्वजनिक शून्य विधि जिससे इसे संलग्न किया जाता है, परीक्षण के मामले के रूप में चलाया जा सकता है। विधि को चलाने के लिए, JUnit पहले वर्ग का एक ताजा उदाहरण बनाता है, फिर एनोटेट पद्धति का उपयोग करता है।
@Before: परीक्षण लिखते समय, यह पता लगाना आम है कि कई परीक्षणों को चलाने से पहले समान वस्तुओं की आवश्यकता होती है। @Before
विधि के साथ सार्वजनिक शून्य विधि की व्याख्या करने से परीक्षण विधि से पहले उस विधि को चलाया जाता है।
@ परिणाम: यदि आप पहले के तरीके में बाहरी संसाधनों को आवंटित करते हैं, तो आपको परीक्षण चलाने के बाद उन्हें जारी करना होगा। @After
विधि के साथ सार्वजनिक शून्य विधि की व्याख्या करने के बाद परीक्षण विधि के बाद उस विधि को चलाया जाता है। सभी @After
विधियों को चलाने की गारंटी दी जाती है, भले ही पहले या टेस्ट विधि अपवाद को फेंके
टिप एंड्रॉइड स्टूडियो में जल्दी से टेस्ट क्लास बनाएं
- कर्सर को उस वर्ग के नाम पर रखें जिसके लिए आप एक टेस्ट क्लास बनाना चाहते हैं।
- Alt + Enter (विंडोज) दबाएँ।
- क्रिएट टेस्ट चुनें, रिटर्न हिट करें।
- उन विधियों का चयन करें जिनके लिए आप परीक्षण विधियाँ बनाना चाहते हैं, ठीक पर क्लिक करें।
- वह निर्देशिका चुनें जहां आप परीक्षण वर्ग बनाना चाहते हैं।
- आप कर रहे हैं, यह आपको मिलता है आपका पहला परीक्षण है।
टिप आसानी से एंड्रॉइड स्टूडियो में परीक्षण निष्पादित करता है
- पैकेज पर राइट क्लिक करें।
- चयन रन 'टेस्ट इन ...
- पैकेज में सभी परीक्षणों को एक ही बार में निष्पादित किया जाएगा।
एंड्रॉइड कॉमननेट्स से बिजनेस लॉजिक आउट होना
स्थानीय JVM इकाई परीक्षणों से बहुत सारे मूल्य आपके आवेदन को डिजाइन करने के तरीके से आते हैं। आपको इसे इस तरह से डिजाइन करना होगा, जहां आप अपने एंड्रॉइड कंपोनेंट्स से अपने बिजनेस लॉजिक को कम कर सकें। मॉडल-दृश्य-प्रस्तुतकर्ता पैटर्न का उपयोग करके इस तरह का एक उदाहरण है। केवल एक उपयोगकर्ता नाम और पासवर्ड लेने वाली एक मूल साइन अप स्क्रीन को लागू करने से यह अभ्यास करता है। हमारा एंड्रॉइड ऐप यह पुष्टि करने के लिए ज़िम्मेदार है कि उपयोगकर्ता की आपूर्ति खाली नहीं है और यह पासवर्ड कम से कम आठ वर्ण लंबा है और इसमें कम से कम दो अंक हैं। यदि उपयोगकर्ता नाम / पासवर्ड मान्य है तो हम अपना साइन अप एप कॉल करते हैं, अन्यथा हम एक त्रुटि संदेश प्रदर्शित करते हैं।
उदाहरण जहां व्यावसायिक तर्क एंड्रॉइड घटक के साथ अत्यधिक जुड़ा हुआ है।
public class LoginActivity extends Activity{
...
private void onSubmitButtonClicked(){
String username = findViewById(R.id.username).getText().toString();
String password = findViewById(R.id.password).getText().toString();
boolean isUsernameValid = username != null && username.trim().length() != 0;
boolean isPasswordValid = password != null && password.trim().length() >= 8 && password.matches(".*\\d+.*");
if(isUsernameValid && isPasswordValid){
performSignUpApiCall(username, password);
} else {
displayInvalidCredentialsErrorMessage();
}
}
}
उदाहरण जहां व्यावसायिक तर्क एंड्रॉइड घटक से डिकॉय किया गया है।
यहाँ हम एक ही वर्ग में परिभाषित करते हैं, LoginContract, जो हमारी विभिन्न कक्षाओं के बीच विभिन्न अंतःक्रियाओं को प्रदर्शित करेगा।
public interface LoginContract {
public interface View {
performSignUpApiCall(String username, String password);
displayInvalidCredentialsErrorMessage();
}
public interface Presenter {
void validateUserCredentials(String username, String password);
}
}
हमारी LoginActivity अधिकांश भाग के लिए समान है सिवाय इसके कि हमने यह जानने की ज़िम्मेदारी को हटा दिया है कि उपयोगकर्ता के साइन अप फॉर्म (हमारे व्यावसायिक तर्क) को कैसे मान्य किया जाए। LoginActivity अब सत्यापन करने के लिए हमारे नए LoginPresenter पर निर्भर करेगी।
public class LoginActivity extends Activity implements LoginContract.View{
private LoginContract.Presenter presenter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
presenter = new LoginPresenter(this);
....
}
...
private void onSubmitButtonClicked(){
String username = findViewById(R.id.username).getText().toString();
String password = findViewById(R.id.password).getText().toString();
presenter.validateUserCredentials(username, password);
}
...
}
अब आपका व्यवसाय तर्क आपके नए लॉगिनपार्टनर वर्ग में रहेगा।
public class LoginPresenter implements LoginContract.Presenter{
private LoginContract.View view;
public LoginPresenter(LoginContract.View view){
this.view = view;
}
public void validateUserCredentials(String username, String password){
boolean isUsernameValid = username != null && username.trim().length() != 0;
boolean isPasswordValid = password != null && password.trim().length() >= 8 && password.matches(".*\\d+.*");
if(isUsernameValid && isPasswordValid){
view.performSignUpApiCall(username, password);
} else {
view.displayInvalidCredentialsErrorMessage();
}
}
}
और अब हम आपके नए LoginPresenter वर्ग के विरुद्ध स्थानीय JVM इकाई परीक्षण बना सकते हैं।
public class LoginPresenterTest {
@Mock
LoginContract.View view;
private LoginPresenter presenter;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
presenter = new LoginPresenter(view);
}
@Test
public void test_validateUserCredentials_userDidNotEnterUsername_displayErrorMessage() throws Exception {
String username = "";
String password = "kingslayer1";
presenter.validateUserCredentials(username, password);
Mockito.verify(view). displayInvalidCredentialsErrorMessage();
}
@Test
public void test_validateUserCredentials_userEnteredFourLettersAndOneDigitPassword_displayErrorMessage() throws Exception {
String username = "Jaime Lanninster";
String password = "king1";
presenter.validateUserCredentials(username, password);
Mockito.verify(view). displayInvalidCredentialsErrorMessage();
}
@Test
public void test_validateUserCredentials_userEnteredNineLettersButNoDigitsPassword_displayErrorMessage() throws Exception {
String username = "Jaime Lanninster";
String password = "kingslayer";
presenter.validateUserCredentials(username, password);
Mockito.verify(view). displayInvalidCredentialsErrorMessage();
}
@Test
public void test_validateUserCredentials_userEnteredNineLettersButOneDigitPassword_performApiCallToSignUpUser() throws Exception {
String username = "Jaime Lanninster";
String password = "kingslayer1";
presenter.validateUserCredentials(username, password);
Mockito.verify(view).performSignUpApiCall(username, password);
}
}
जैसा कि आप देख सकते हैं, जब हमने अपने व्यापार तर्क को LoginActivity से बाहर निकाला और उसे LoginPresenter POJO में रखा। अब हम अपने व्यापार तर्क के खिलाफ स्थानीय जेवीएम इकाई परीक्षण बना सकते हैं।
यह ध्यान दिया जाना चाहिए कि वास्तुकला में हमारे परिवर्तन से कई अन्य निहितार्थ हैं जैसे कि हम प्रत्येक वर्ग को एक ही जिम्मेदारी, अतिरिक्त कक्षाएं, आदि का पालन करने के करीब हैं। ये मेरे द्वारा प्रदर्शन के बारे में जाने के तरीके के साइड इफेक्ट्स हैं। एमवीपी शैली के माध्यम से decoupling। एमवीपी इस बारे में जाने का सिर्फ एक तरीका है लेकिन ऐसे अन्य विकल्प भी हैं जिन्हें आप एमवीवीएम जैसे देखना चाहते हैं। आपको बस सबसे अच्छा सिस्टम चुनना है जो आपके लिए काम करता है।
JUnit से शुरुआत करना
सेट अप
JUnit का उपयोग करके अपने एंड्रॉइड प्रोजेक्ट का यूनिट परीक्षण शुरू करने के लिए आपको अपने प्रोजेक्ट में JUnit निर्भरता जोड़ने की आवश्यकता है और आपको एक परीक्षण स्रोत-सेट बनाने की आवश्यकता है जिसमें यूनिट परीक्षणों के लिए स्रोत कोड शामिल होने वाला है। एंड्रॉइड स्टूडियो के साथ बनाई गई परियोजनाओं में अक्सर पहले से ही JUnit निर्भरता और परीक्षण स्रोत-सेट शामिल होते हैं
निर्भरता Closure
भीतर अपने मॉड्यूल build.gradle
फ़ाइल के लिए निम्न पंक्ति जोड़ें:
testCompile 'junit:junit:4.12'
JUnit परीक्षण कक्षाएं एक विशेष स्रोत-सेट नाम test
। यदि यह स्रोत-सेट मौजूद नहीं है, तो आपको स्वयं एक नया फ़ोल्डर बनाने की आवश्यकता है। एक डिफ़ॉल्ट एंड्रॉइड स्टूडियो (ग्रैडल आधारित) प्रोजेक्ट की फ़ोल्डर संरचना इस तरह दिखती है:
<project-root-folder>
/app (module root folder)
/build
/libs
/src
/main (source code)
/test (unit test source code)
/androidTest (instrumentation test source code)
build.gradle (module gradle file)
/build
/gradle
build.gradle (project gradle file)
gradle.properties
gradlew
gradlew.bat
local.properties
settings.gradle (gradle settings)
यदि आपके प्रोजेक्ट में /app/src/test
फ़ोल्डर नहीं है, तो आपको इसे स्वयं बनाने की आवश्यकता है। test
फ़ोल्डर के भीतर आपको एक java
फ़ोल्डर की आवश्यकता है (इसे बनाएं यदि यह मौजूद नहीं है)। test
स्रोत सेट में जावा फ़ोल्डर में आपके main
स्रोत-सेट के समान पैकेज संरचना होनी चाहिए।
यदि सेटअप सही ढंग से आपकी परियोजना संरचना (एंड्रॉइड स्टूडियो में एंड्रॉइड दृश्य में) इस तरह दिखना चाहिए:
नोट: आपको androidTest
स्रोत-सेट की आवश्यकता नहीं है, यह स्रोत-सेट अक्सर एंड्रॉइड स्टूडियो द्वारा बनाई गई परियोजनाओं में पाया जाता है और संदर्भ के लिए यहां शामिल है।
टेस्ट लिखना
test
स्रोत-सेट के भीतर एक नया वर्ग बनाएँ।
प्रोजेक्ट दृश्य में परीक्षण स्रोत-सेट पर राइट क्लिक करेंNew
>Java class
।
सबसे ज्यादा इस्तेमाल किया जाने वाला नामकरण पैटर्न उस वर्ग के नाम का उपयोग करना है जिसे आपTest
शामिल करने जा रहे हैं। तोStringUtilities
हो जाता हैStringUtilitiesTest
।@RunWith
एनोटेशन जोड़ें
JUnit को उन परीक्षणों को चलाने के लिए@RunWith
एनोटेशन की आवश्यकता है, जिन्हें हम अपने परीक्षण वर्ग में परिभाषित करने जा रहे हैं। डिफ़ॉल्ट JUnit धावक (JUnit 4 के लिए)BlockJUnit4ClassRunner
लेकिन इसके बजाय सीधे अपने अधिक सुविधाजनक उपयोग करने के लिए उपनामJUnit4
का उपयोग करें जो डिफ़ॉल्ट JUnit धावक के लिए एक शॉर्टहैंड है।@RunWith(JUnit4.class) public class StringUtilitiesTest { }
एक परीक्षण बनाएँ
एक यूनिट टेस्ट अनिवार्य रूप से सिर्फ एक विधि है, जो ज्यादातर मामलों में, रन होने पर विफल नहीं होनी चाहिए। दूसरे शब्दों में इसे अपवाद नहीं कहना चाहिए। एक परीक्षण विधि के अंदर आप लगभग हमेशा ऐसे दावे पाएंगे जो यह जाँचते हैं कि क्या विशिष्ट स्थितियाँ पूरी हुई हैं। यदि कोई दावा विफल हो जाता है, तो यह एक अपवाद को फेंक देता है जो विधि / परीक्षण को विफल करने का कारण बनता है। एक परीक्षण विधि को हमेशा@Test
टिप्पणी एनोटेशन के साथ एनोटेट किया जाता है। इस एनोटेशन के बिना JUnit स्वचालित रूप से परीक्षण नहीं चलाएगा।@RunWith(JUnit4.class) public class StringUtilitiesTest { @Test public void addition_isCorrect() throws Exception { assertEquals("Hello JUnit", "Hello" + " " + "JUnit"); } }
नोट: मानक जावा विधि का नामकरण कन्वेंशन यूनिट टेस्ट विधि के विपरीत नाम अक्सर अंडरस्कोर होते हैं।
एक परीक्षण चल रहा है
तरीका
किसी एकल परीक्षण विधि को चलाने के लिए, आप विधि पर राइट क्लिक कर सकते हैं औरRun 'addition_isCorrect()'
ctrl+shift+f10
Run 'addition_isCorrect()'
क्लिक कर सकते हैं या कीबोर्ड शॉर्टकटctrl+shift+f10
।यदि सब कुछ सही ढंग से सेटअप है, तो JUnit विधि को चलाना शुरू कर देता है और आपको Android स्टूडियो में निम्नलिखित इंटरफ़ेस देखना चाहिए:
कक्षा
आप प्रोजेक्ट दृश्य में कक्षा को राइट क्लिक करके औरRun 'StringUtilitiesTest '
पर क्लिक करके या कीबोर्ड शॉर्टकटctrl+shift+f10
उपयोग करके, यदि आपने प्रोजेक्ट दृश्य में कक्षा का चयन किया है, तो आप एकल श्रेणी में परिभाषित सभी परीक्षण चला सकते हैं।पैकेज (सब कुछ)
यदि आप परियोजना में या पैकेज में परिभाषित सभी परीक्षणों को नहीं चलाना चाहते हैं, तो आप केवल पैकेज पर राइट क्लिक करकेRun ...
क्लिक कर सकते हैंRun ...
जैसे आप एक ही क्लास में परिभाषित सभी परीक्षण चलाएंगे।
अपवाद
JUnit का उपयोग परीक्षण करने के लिए भी किया जा सकता है यदि कोई विधि किसी दिए गए इनपुट के लिए एक विशिष्ट अपवाद को फेंकता है।
इस उदाहरण में हम परीक्षण करेंगे कि यदि निम्न विधि वास्तव में एक अपवाद को फेंक देती है यदि बूलियन प्रारूप (इनपुट) मान्यता प्राप्त / अज्ञात नहीं है:
public static boolean parseBoolean(@NonNull String raw) throws IllegalArgumentException{
raw = raw.toLowerCase().trim();
switch (raw) {
case "t": case "yes": case "1": case "true":
return true;
case "f": case "no": case "0": case "false":
return false;
default:
throw new IllegalArgumentException("Unknown boolean format: " + raw);
}
}
@Test
एनोटेशन में expected
पैरामीटर जोड़कर, कोई भी परिभाषित कर सकता है कि कौन सा अपवाद फेंकने की उम्मीद है। यदि यह अपवाद नहीं होता है, तो इकाई परीक्षण विफल हो जाएगा, और यदि अपवाद वास्तव में फेंक दिया गया है तो सफल होगा:
@Test(expected = IllegalArgumentException.class)
public void parseBoolean_parsesInvalidFormat_throwsException(){
StringUtilities.parseBoolean("Hello JUnit");
}
यह अच्छी तरह से काम करता है, हालांकि, यह आपको विधि के भीतर केवल एक परीक्षण मामले तक सीमित करता है। कभी-कभी आप एक ही तरीके के भीतर कई मामलों का परीक्षण करना चाह सकते हैं। इस सीमा को पार करने के लिए अक्सर इस्तेमाल की जाने वाली तकनीक Assert.fail()
try-catch
ब्लॉक और Assert.fail()
विधि का उपयोग कर रही है:
@Test
public void parseBoolean_parsesInvalidFormats_throwsException(){
try {
StringUtilities.parseBoolean("Hello!");
fail("Expected IllegalArgumentException");
} catch(IllegalArgumentException e){
}
try {
StringUtilities.parseBoolean("JUnit!");
fail("Expected IllegalArgumentException");
} catch(IllegalArgumentException e){
}
}
नोट: कुछ लोग इसे इकाई परीक्षण के अंदर एक से अधिक मामलों का परीक्षण करने के लिए बुरा व्यवहार मानते हैं।
स्थैतिक आयात
JUnit कम से कम एक आदिम प्रकार के लिए एक और वस्तुओं के लिए एक उपलब्ध है कुछ काफी assertEquals
तरीकों को परिभाषित करता है। ये विधियां डिफ़ॉल्ट रूप से सीधे कॉल करने के लिए उपलब्ध नहीं हैं और इसे इस तरह कहा जाना चाहिए: Assert.assertEquals
। लेकिन क्योंकि इन विधियों का उपयोग किया जाता है इसलिए अक्सर लोग लगभग हमेशा एक स्थिर आयात का उपयोग करते हैं ताकि विधि का उपयोग सीधे रूप से किया जा सके जैसे कि यह कक्षा का ही हिस्सा है।
assertEquals
विधि के लिए स्थैतिक आयात जोड़ने के लिए निम्नलिखित आयात कथन का उपयोग करें:
import static org.junit.Assert.assertEquals;
आप निम्न स्थिर आयात का उपयोग करके सभी assertArrayEquals
जैसे कि assertArrayEquals
, assertNotNull
और assertFalse
आदि सहित स्थैतिक आयात कर सकते हैं:
import static org.junit.Assert.*;
स्थिर आयात के बिना:
@Test
public void addition_isCorrect(){
Assert.assertEquals(4 , 2 + 2);
}
स्थैतिक आयात के साथ:
@Test
public void addition_isCorrect(){
assertEquals(4 , 2 + 2);
}