2014-10-27 35 views
5

Mam projekt aplikacji na Androida, do którego chcę dodać automatyczne testy. W tym celu chciałbym użyć Cucumber dla java w Android Studio i wykonać te testy bezpośrednio do mojego IDE (z konfiguracją Run/Debug).Dlaczego moje definicje definicji Cucumber są niezdefiniowane w Android Studio

Jestem na Windows 7 sp1 64 bitów przy użyciu Android Studio 0.8.9. Dodałem wtyczki Gherkin wersja 134.1007 i Cucumber for Java wersja 134.1007. Użyć następujące biblioteki dla Cucumber:

  • ogórek Android 1.1.8
  • ogórek rdzenia 1.1.8
  • ogórek HTML 0.2.3
  • ogórek Java-1.1. 8
  • ogórek JUnit-1.1.8
  • ogórek JVM-deps-1.0.3
  • ogórek-2.12.2
  • robotium-solo 5.2.1

To jest mój struktury projektu:

TruckCalibrator/ 
    .idea/ 
    app/ 
     build/ 
     libs/ 
      [libraries listed above in .jar format] 
     src/ 
      main/ 
       java/ 
        com/ 
         novomnetworks/ 
          formeval/ 
           truckcalibrator/ 
            MainActivity.java 
       res/ 
       AndroidManifest.xml 
      test/ 
       assets/ 
        features/ 
         app_start.feature 
       java/ 
        com/ 
         novomnetworks/ 
          formeval/ 
           truckcalibrator/ 
            test/ 
             CucumberTest.java 
      build.gradle 
    build/ 
    gradle/ 

To mój Gradle plik:

apply plugin: 'com.android.application' 

android { 
    compileSdkVersion 20 
    buildToolsVersion '20.0.0' 

    defaultConfig { 
     applicationId "com.novomnetworks.formeval.truckcalibrator" 
     minSdkVersion 16 
     targetSdkVersion 20 
     versionCode 1 
     versionName "1.0" 
     testInstrumentationRunner "cucumber.api.android.CucumberInstrumentation" 
    } 
    buildTypes { 
     release { 
      runProguard false 
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
     } 
    } 
    sourceSets { 
     instrumentTest { 
      java.srcDirs = ['src/test/java'] 
     } 
    } 
} 

dependencies { 
    compile fileTree(dir: 'libs', include: ['*.jar']) 
    compile 'com.github.satyan:sugar:1.3' 
} 

To jest mój manifest:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.novomnetworks.formeval.truckcalibrator" 
    xmlns:tools="http://schemas.android.com/tools"> 

    <uses-permission android:name="android.permission.CALL_PHONE" /> 
    <uses-permission android:name="android.permission.INTERNET" /> 

    <instrumentation 
     android:name="cucumber.api.android.CucumberInstrumentation" 
     android:targetPackage="com.novomnetworks.formeval.truckcalibrator.test" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/launcher_icon" 
     tools:replace="icon" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" 
     android:name="com.orm.SugarApp"> 
     <uses-library android:name="android.test.runner" /> 
     <meta-data android:name="DATABASE" android:value="form-eval.db" /> 
     <meta-data android:name="VERSION" android:value="1" /> 
     <meta-data android:name="QUERY_LOG" android:value="true" /> 
     <meta-data android:name="DOMAIN_PACKAGE_NAME" android:value="com.novomnetworks.formeval.truckcalibrator.database" /> 
     <activity 
      android:name=".MainActivity" 
      android:screenOrientation="portrait"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
    </application> 

</manifest> 

To definicje mój krok Ogórek plik (CucumberTest.java):

package com.novomnetworks.formeval.truckcalibrator.test; 

import android.test.ActivityInstrumentationTestCase2; 
import android.util.Log; 

import cucumber.api.CucumberOptions; 
import cucumber.api.PendingException; 
import cucumber.api.java.After; 
import cucumber.api.java.Before; 
import cucumber.api.java.en.Given; 
import cucumber.api.java.en.Then; 
import cucumber.api.java.en.When; 
import cucumber.api.junit.Cucumber; 

import com.novomnetworks.formeval.truckcalibrator.MainActivity; 
import com.novomnetworks.formeval.truckcalibrator.R; 
import com.robotium.solo.Solo; 

import org.junit.runner.RunWith; 

/** 
* Created by rroyer on 2014-10-24. 
*/ 
@RunWith(Cucumber.class) 
/*@CucumberOptions(monochrome = true, 
     tags = "@tags", 
     features = "src/test/assets/features/", 
     format = { "pretty","html: cucumber-html-reports", "json: cucumber-html-reports/cucumber.json" }, 
     dryRun = false, 
     glue = "com.novomnetworks.formeval.truckcalibrator.test")*/ 
public class CucumberTest extends ActivityInstrumentationTestCase2<MainActivity> { 
    private static final String TAG = "CucumberTest"; 

    Solo solo; 

    public CucumberTest() { 
     super(MainActivity.class); 
    } 

    @Before 
    protected void before() throws Exception { 
     Log.d(TAG, "setUp"); 
     super.setUp(); 
     solo = new Solo(getInstrumentation(), getActivity()); 
     getActivity().resetDB(); 
    } 

    @After 
    protected void after() throws Exception { 
     Log.d(TAG, "tearDown"); 
     solo.finishOpenedActivities(); 
     super.tearDown(); 
    } 

    @Given("^I started the app$") 
    public void i_started_the_app() throws Throwable { 
     solo.waitForActivity(MainActivity.class); 
     throw new PendingException(); 
    } 

    @Then("I should see the action bar") 
    public void I_should_see_the_action_bar() throws Exception { 
     assertNotNull(getActivity().getMenu()); 
    } 

    @Given("I am on the clients list") 
    public void I_am_on_the_clients_list() throws Exception { 
     solo.waitForFragmentById(R.layout.fragment_clients); 
    } 

    @Then("^I should see the clients list header$") 
    public void I_should_see_the_clients_list_header() throws Exception { 
     assertTrue(solo.searchText(solo.getString(R.string.clients))); 
     assertTrue(solo.searchText(solo.getString(R.string.sorted_by))); 
     assertNotNull(solo.getView(R.id.clients_spinner)); 
    } 

    @Then("I should see the new client button") 
    public void I_should_see_the_new_client_button() throws Exception { 
     assertNotNull(solo.getView(R.id.action_new_client).isShown()); 
    } 

    @Then("^I should see the clients list$") 
    public void I_should_see_the_clients_list() throws Exception { 
     assertNotNull(solo.getView(R.id.clients)); 
    } 
} 

I to jest mój plik cecha:

Feature: Démarrage de l'app 
    Scenario: La barre de menu devrait s'afficher 
    Given I started the app 
    Then I should see the action bar 
    Scenario: La liste des clients devrait s'afficher 
    Given I started the app 
    Then I should see the clients list header 
    And I should see the new client button 
    And I should see the clients list 

Kiedy uruchamiam moją konfigurację testową Ogórek (zrzut ekranu poniżej) Run/Debug configuration screenshot of my Cucumber test file Cechy znajdują definicje mój krok, ale nie są. Na wyjściu jest napisane:

Undefined step: Given I started the app 
Undefined step: Then I should see the action bar 
Undefined step: Given I started the app 
Undefined step: Then I should see the clients list header 
Undefined step: And I should see the new client button 
Undefined step: And I should see the clients list 

2 Scenarios (2 undefined) 
6 Steps (6 undefined) 
0m0,000s 

You can implement missing steps with the snippets below: 

@Given("^I started the app$") 
public void i_started_the_app() throws Throwable { 
    // Write code here that turns the phrase above into concrete actions 
    throw new PendingException(); 
} 

[other similar suggestions...] 

Przeszukałem internet przez cały dzień bez znajdowania poprawnego sposobu połączenia pliku definicji kroków. Każdy post wydaje mi się mówić ludziom, aby wspomnieli o pakiecie testowym w polu konfiguracji Glue i to jest to, co zrobiłem, ale to nie ma sensu. Jeśli przyjrzysz się uważnie plikowi CucumberTest.java, możesz zobaczyć, że próbowałem również z adnotacją @CucumberOptions, ale nie zmieniło to wyniku. Próbowałem również z i bez adnotacji @RunWith(Cucumber.class).

Co robię źle?

+0

pierwsze spojrzenie wydaje się pakiet cel w manifeście aplikacji testowej jest źle - com.novomnetworks.formeval .truckcalibrator.test - remove .test – maszter

+0

Próbowałem już z i bez, próbowałem również umieścić moją klasę CucumberTest nie w pakiecie testowym (więc jest to ten sam pakiet co moja klasa MainActivity), ale mam te same błędy –

Odpowiedz

0

Jesteś rzuca wyjątek: throw new PendingException();

w

@Given("^I started the app$") 
    public void i_started_the_app() throws Throwable { 
     solo.waitForActivity(MainActivity.class); 
     throw new PendingException(); 
    } 
+0

I nie rozumiem, co próbujesz mi powiedzieć. Ogórek nie jest nawet w stanie znaleźć metody "i_started_the_app", więc jaka jest umowa z jej zawartością? Plus to dokładnie to, co komunikat o błędzie informuje mnie, aby umieścić w mojej metodzie. –

+0

Musisz usunąć throw new PendingException(); ze swojego kodu. Ta linia rzuca dokładnie wiadomość, którą widzisz w swoich śladach. Jaki ogórek mówi, że możesz użyć tego szablonu, ale musisz usunąć tę linię. Usuń tę linię i użyj CucumberOptions zamiast @RunWith – mromer

+0

Usunąłem linię 'throw new PendingException();' i zastąpiłem adnotację '@ RunWith' adnotacją' @ CucumberOptions', ale dostaję dokładnie ten sam błąd. Błąd nie wspomina nigdzie, aby usunąć wyjątek throw, mówi, aby utworzyć metody z poleceniami throw throw ... –

0

natknąłem się na ten sam problem i myślę, rozwiązał go. Najpierw musimy użyć konfiguracji androidTestCompile we wszystkich bibliotekach związanych z ogórkiem. Zauważ, że musimy użyć kwalifikatora @jar do biblioteki androida ogórka, aby uniknąć gradle pobierania pliku apklib zamiast pliku jar.Na przykład:

dependencies { 
    compile fileTree(dir: 'libs', include: ['*.jar']) 
    ... 
    androidTestCompile 'info.cukes:cucumber-core:1.2.0' 
    androidTestCompile 'info.cukes:cucumber-java:1.2.0' 
    androidTestCompile 'info.cukes:gherkin:2.12.2' 
    androidTestCompile 'info.cukes:cucumber-html:0.2.3' 
    androidTestCompile 'info.cukes:cucumber-android:[email protected]' 
} 

Po drugie, nie musimy używać wtyczki cucumber-java dla Androida Studio. Musimy uruchomić test na emulatorze/urządzeniu i nie mogę znaleźć sposobu na ustawienie go za pomocą wtyczki cucumber-java. Zamiast tego po prostu skorzystaj z Testu Androida dla swoich konfiguracji biegowych i ustaw Specjalną Oprzyrządowanie Instrumentacji na cucumber.api.android.CucumberInstrumentation.

I ostatnią rzeczą, jaką zauważyłem, jest to, że nie trzeba używać adnotacji @RunWith. Po prostu użyj @CucumberOptions na jednej ze swoich klas i działa.

0

Twoje testy powinny być w folderze src/androidTest zamiast src/test

Również chciałbym rozdzielić CucumberTest.java do jednej klasy dla Ogórek Runner z adnotacjami konfiguracyjnych i osobnej klasy rozciągającej się od ActivityInstrumentationTestCase2 zawierającego kod kleju.

Tutaj masz uruchomioną przykład dla Androida Studio przy użyciu ogórek i Espresso zamiast Robotium:

https://github.com/neoranga55/CleanGUITestArchitecture

+0

Mogę potwierdzić, że Twój test działa w Androidzie, jeśli uruchomimy go za pomocą CucumberTestRunner.java, czy jest jakiś sposób, abyśmy mogli uruchomić go po jednym scenariuszu na raz w celu łatwiejszej metody testowania? –

+0

Używam tagów, a po uruchomieniu testu filtruję według tagów, aby uruchomić tylko jeden test, np .: ./gradlew connectedAndroidTest -Ptags = "@ test-scenario-whatever-id-001" –