Come posso testare un'attività Android che agisce sull'accelerometro?

Sto iniziando con un'attività basata su questa ShakeActivity e voglio scrivere alcuni test di unità per esso. Ho scritto alcune piccole unità di test per le attività Android prima ma non sono sicuro where cominciare qui. Voglio nutrire l'accelerometro di alcuni valori diversi e verificare come l'attività risponda. Per ora sto mantenendo semplice e aggiornando semplicemente una variabile di conteggi privata int e un TextView quando si verifica un evento "scuotimento".

Quindi la mia domanda in gran parte si riduce a questo:

  • pacchettabile incontrato ioexception scrivere object serializzabile ...?
  • Come aprire Google Maps utilizzando l'indirizzo?
  • Servizio di riconoscimento vocale di Android Continuous Service
  • Comunicazione di Android e PC tramite USB: che cos'è una directory sicura che posso utilizzare l'accesso / accesso ADB e l'accesso da un'applicazione Android?
  • Chiudere una window di dialogo personalizzato sul button di scatto
  • Android - Pulsante con l'image "caricamento" di rotazione / filatura quando viene premuto
  • Come posso submit dati falsi all'accelerometro da un test di unità?

  • Comportmento strano con sensore di orientamento android
  • Sensore orientamento Android per la rotazione del cubo 3D
  • Componenti di gravità dell'accelerometro
  • Utilizzando giroscopio Android anziché accelerometro. Trovo un sacco di pezzi, ma nessun codice completo
  • LocationRequest in Google Play Services non si aggiorna per intervalli impostati in less di 1 secondo.
  • Qual è la precisione del mondo reale degli accelerometri telefonici quando viene utilizzato per il posizionamento?
  • 5 Solutions collect form web for “Come posso testare un'attività Android che agisce sull'accelerometro?”

    La mia soluzione a questo è finita in modo più semplice che mi aspettavo. Non sto provando veramente l'accelerometro tanto che sto testando la risposta dell'applicazione ad un evento sollevato dall'accelerometro, e ho solo bisogno di provare di conseguenza. La mia class implementa SensorListener e volevo testare cosa succede su SensorChanged. La chiave allora è stata quella di alimentare alcuni valori e verificare lo stato della mia attività. Esempio:

    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); } 

    Come posso submit dati falsi all'accelerometro da un test di unità?

    AFAIK, non puoi.

    Accettare la logica degli shaker ad accettare una fonte di dati collegabile. Nel test dell'unità, fornire un mock. Nella produzione, fornire un involucro attorno all'accelerometro.

    Oppure, non preoccuparti di testare l'unità stessa, ma preoccuparti di testare le unità che utilizzano l'agitatore e creare un agitatore imbroglione.

    Beh, puoi scrivere un'interface.

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

    La scrittura di un AndroidAccelerometerReader e di FakeAccelerometerReader . Il tuo codice utilizzerebbe IAccelerometerReader ma puoi scambiare nei lettori Android o Fake.

    Non c'è bisogno di testare l'accelerometro del sistema operativo, prova solo la tua logica che risponde all'OS – in altre parole il tuo SensorListener . Sfortunatamente SensorEvent è privato e non ho potuto call direttamente SensorListener.onSensorChanged(SensorEvent event) , così SensorListener.onSensorChanged(SensorEvent event) prima classificare la class di SensorListener con la mia class personale e call direttamente il mio metodo dai test:

     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 } } 

    Quindi posso call onSensorUpdated direttamente dal mio codice di prova, che simula l'accelerometro.

     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); } 
      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]; } } } 

    è ansible verificare la parte superiore del codice seguendo il modo seguente

     @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}); } 
    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.