2010-05-10 23 views
5

मैं इस ShakeActivity के आधार पर एक गतिविधि के साथ शुरू कर रहा हूं और मैं इसके लिए कुछ यूनिट परीक्षण लिखना चाहता हूं। मैंने पहले एंड्रॉइड गतिविधियों के लिए कुछ छोटे यूनिट परीक्षण लिखे हैं लेकिन मुझे यकीन नहीं है कि यहां कहां से शुरू करना है। मैं एक्सेलेरोमीटर को कुछ अलग मूल्यों को खिलाना चाहता हूं और परीक्षण करता हूं कि गतिविधि इसका जवाब कैसे देती है। अभी के लिए मैं इसे सरल रख रहा हूं और एक "शेक" घटना होने पर एक निजी int काउंटर वैरिएबल और टेक्स्ट व्यू को अपडेट कर रहा हूं।मैं एक एंड्रॉइड गतिविधि का परीक्षण कैसे कर सकता हूं जो एक्सेलेरोमीटर पर कार्य करता है?

तो मेरे सवाल का काफी हद तक इस करने पर निर्भर करता:

मैं कैसे एक इकाई परीक्षण से accelerometer करने के लिए नकली डेटा भेज सकते हैं?

उत्तर

5

मेरा समाधान इस तरह से आसान हो गया, तो मुझे उम्मीद थी। मैं वास्तव में इतना के रूप में मैं accelerometer द्वारा उठाए गए एक घटना के लिए आवेदन की प्रतिक्रिया का परीक्षण कर रहा हूँ accelerometer का परीक्षण कर रहा हूँ, और मैं सिर्फ उसके अनुसार परीक्षण करने के लिए की जरूरत है। मेरी कक्षा SensorListener लागू करती है और मैं जांच करना चाहता था कि सेंसर चेंज पर क्या होता है। तब कुंजी कुछ मूल्यों में फ़ीड करना था और मेरी गतिविधि की स्थिति की जांच करना था। उदाहरण:

public void testShake() throws InterruptedException { 
    mShaker.onSensorChanged(SensorManager.SENSOR_ACCELEROMETER, new float[] {0, 0, 0}); 
    //Required because method only allows one shake per 100ms 
    Thread.sleep(500); 
    mShaker.onSensorChanged(SensorManager.SENSOR_ACCELEROMETER, new float[] {300, 300, 300}); 
    Assert.assertTrue("Counter: " + mShaker.shakeCounter, mShaker.shakeCounter > 0); 
} 
4

मैं कैसे एक इकाई परीक्षण से accelerometer करने के लिए नकली डेटा भेज सकते हैं?

AFAIK, आप नहीं कर सकते।

क्या आपके शेकर तर्क एक प्लग करने योग्य डेटा स्रोत को स्वीकार करते हैं। यूनिट परीक्षण में, एक नकली आपूर्ति करें। उत्पादन में, एक्सेलेरोमीटर के चारों ओर एक रैपर की आपूर्ति करें।

या, इकाई शेकर ही परीक्षण के बारे में चिंता नहीं है, लेकिन बल्कि इकाई परीक्षण चीजें हैं जो शेकर का उपयोग के बारे में चिंता है, और एक नकली शेकर पैदा करते हैं।

+0

कि निश्चित रूप से समझ में आता है और एक बेहतर विचार की तरह ध्वनि करता है के द्वारा कोड का टुकड़ा ऊपर परीक्षण कर सकते हैं। क्या आपके पास इस तरह "प्लग करने योग्य डेटा स्रोत" का उपयोग करने के कोई उदाहरण हैं? –

+0

क्या यह उत्तर अभी तक अद्यतित है? या कुछ नया आ गया है? – TinyTimZamboni

+1

@TinyTimZamboni: मैं याद करने के लिए है कि Android उपकरण टीम एक तरह से एक एमुलेटर के लिए सेंसर इनपुट के रूप में एक Android डिवाइस का उपयोग करने पर काम कर रहा था लगते हैं, लेकिन मैं नहीं जानता कि जहां कि खड़ा है।अन्यथा, मुझे फर्जी सेंसर इनपुट प्रदान करने के किसी भी तरीके से अवगत नहीं है। – CommonsWare

1

ठीक है, आप एक इंटरफेस लिख सकते हैं।

interface IAccelerometerReader { 
    public float[] readAccelerometer(); 
} 

लिखने एक AndroidAccelerometerReader और FakeAccelerometerReader। आपका कोड IAccelerometerReader का उपयोग करेगा लेकिन आप एंड्रॉइड या नकली पाठकों में स्वैप कर सकते हैं।

0

बस अपनी स्वयं तर्क है कि ओएस का जवाब का परीक्षण, ओएस के एक्सीलरोमीटर परीक्षण करने के लिए कोई ज़रूरत नहीं है - दूसरे शब्दों अपने SensorListener में। दुर्भाग्य से SensorEvent निजी है और मैं SensorListener.onSensorChanged(SensorEvent event) सीधे कह सकते हैं नहीं है, तो अपने ही वर्ग के साथ पहले उपवर्ग SensorListener किया था, और परीक्षण से सीधे अपने ही विधि कॉल:

public class ShakeDetector implements SensorEventListener { 

    @Override 
    public void onSensorChanged(SensorEvent event) { 

     float x = event.values[0]; 
     float y = event.values[1]; 
     float z = event.values[2]; 

     onSensorUpdate(x, y, z); 
    } 

    public void onSensorUpdate(float x, float y, float z) { 
     // do my (testable) logic here 
    } 
} 

तब मैं अपने परीक्षण कोड से सीधे onSensorUpdated कॉल कर सकते हैं , जो एक्सेलेरोमीटर फायरिंग को अनुकरण करता है।

private void simulateShake(final float amplitude, int interval, int duration) throws InterruptedException { 
    final SignInFragment.ShakeDetector shaker = getFragment().getShakeSensorForTesting(); 
    long start = System.currentTimeMillis(); 

    do { 
     getInstrumentation().runOnMainSync(new Runnable() { 
      @Override 
      public void run() { 
       shaker.onSensorUpdate(amplitude, amplitude, amplitude); 
      } 
     }); 
     Thread.sleep(interval); 
    } while (System.currentTimeMillis() - start < duration); 
} 
0
public class SensorService implements SensorEventListener { 
/** 
    * Accelerometer values 
    */ 
    private float accValues[] = new float[3]; 
    @Override 
    public void onSensorChanged(SensorEvent event) { 

      if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { 
      accValues[0] = sensorEvent.values[0]; 
      accValues[1] = sensorEvent.values[1]; 
      accValues[2] = sensorEvent.values[2]; 
     } 

    } 
} 

आप निम्नलिखित तरीके

@Test 
    public void testOnSensorChangedForAcceleratorMeter() throws Exception { 
     Intent intent=new Intent(); 
     sensorService.onStartCommand(intent,-1,-1); 

     SensorEvent sensorEvent=getEvent(); 
     Sensor sensor=getSensor(Sensor.TYPE_ACCELEROMETER); 
     sensorEvent.sensor=sensor; 
     sensorEvent.values[0]=1.2345f; 
     sensorEvent.values[1]=2.45f; 
     sensorEvent.values[2]=1.6998f; 
     sensorService.onSensorChanged(sensorEvent); 

     Field field=sensorService.getClass().getDeclaredField("accValues"); 
     field.setAccessible(true); 
     float[] result= (float[]) field.get(sensorService); 
     Assert.assertEquals(sensorEvent.values.length,result.length); 
     Assert.assertEquals(sensorEvent.values[0],result[0],0.0f); 
     Assert.assertEquals(sensorEvent.values[1],result[1],0.0f); 
     Assert.assertEquals(sensorEvent.values[2],result[2],0.0f); 
    } 




private Sensor getSensor(int type) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException { 
      Constructor<Sensor> constructor = Sensor.class.getDeclaredConstructor(new Class[0]); 
      constructor.setAccessible(true); 
      Sensor sensor= constructor.newInstance(new Object[0]); 

      Field field=sensor.getClass().getDeclaredField("mType"); 
      field.setAccessible(true); 
      field.set(sensor,type); 
      return sensor; 
     } 



private SensorEvent getEvent() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { 
     Constructor<SensorEvent> constructor = SensorEvent.class.getDeclaredConstructor(int.class); 
     constructor.setAccessible(true); 
     return constructor.newInstance(new Object[]{3}); 
    } 
संबंधित मुद्दे

 संबंधित मुद्दे