为什么我的Cucumber定义步骤在Android Studio中未定义

时间:2014-10-27 16:32:30

标签: android android-studio cucumber cucumber-jvm

我有一个Android应用程序项目,我想在其中添加自动化测试。为此,我想在Android Studio中使用Cucumber for java,并将这些测试直接执行到我的IDE中(使用Run / Debug配置)。

我在使用Android Studio 0.8.9的Windows 7 sp1 64位上。我添加了插件Gherkin版本134.1007和Cucumber for Java版本134.1007。我为Cucumber使用以下库:

  • 黄瓜机器人-1.1.8
  • 黄瓜核-1.1.8
  • 黄瓜-HTML-0.2.3
  • 黄瓜-java的1.1.8
  • 黄瓜的junit-1.1.8
  • 黄瓜-JVM-DEPS-1.0.3
  • 小黄瓜-2.12.2
  • robotium-独奏5.2.1

这是我的项目结构:

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/

这是我的gradle文件:

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

这是我的清单:

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

这是我的Cucumber步骤定义文件(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));
    }
}

这是我的专题文件:

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

当我运行我的Cucumber测试配置时,(截图)Run/Debug configuration screenshot of my Cucumber test file找到了功能,但我的步骤定义不是。输出说

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...]

我在网上搜索了一整天而没有找到链接我的步骤定义文件的正确方法。我发现的每个帖子似乎都告诉人们在配置字段Glue中提到测试包,这就是我所做的,但它没用。如果仔细查看我的CucumberTest.java文件,您可以看到我尝试使用@CucumberOptions注释,但它没有更改结果。我也尝试过使用和不使用@RunWith(Cucumber.class)注释。

我做错了什么?

3 个答案:

答案 0 :(得分:0)

您正在抛出异常:throw new PendingException();

in

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

答案 1 :(得分:0)

我遇到了同样的问题,我想我已经解决了。首先,我们需要在所有黄瓜相关库上使用androidTestCompile配置。请注意,我们需要使用@jar限定符来执行cucumber-android库,以避免gradle获取apklib文件而不是jar文件。例如:

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:1.2.0@jar'
}

其次,我们不需要为Android Studio使用cucumber-java插件。我们需要在模拟器/设备上运行测试,而我无法找到使用cucumber-java插件设置的方法。相反,只需对运行配置使用Android Test,并将Specific Instrumentation Runner设置为cucumber.api.android.CucumberInstrumentation

我注意到的最后一件事是你不需要使用@RunWith注释。只需在其中一个课程上使用@CucumberOptions即可。

答案 2 :(得分:0)

您的测试应位于src/test文件夹中,而不是ActivityInstrumentationTestCase2

此外,我将CucumberTest.java分离为Cucumber Runner的一个类,其中包含配置注释和从string strCmdText = string.Format("advfirewall firewall add rule name=\"BlockU\" protocol=any dir=in action=block remoteip={0}", ip); ProcessStartInfo psi = new ProcessStartInfo("netsh.exe", strCmdText); psi.RedirectStandardOutput = true; psi.UseShellExecute = false; psi.CreateNoWindow = true; try { Process.Start(psi); } catch (Exception ex) { Debug.WriteLine(ex.Message); } 扩展的包含胶水代码的单独类。

这里有一个使用Cucumber和Espresso而不是Robotium的Android Studio的运行示例:

https://github.com/neoranga55/CleanGUITestArchitecture