【问题标题】:Why are my Cucumber definition steps undefined in Android Studio为什么我的 Cucumber 定义步骤在 Android Studio 中未定义
【发布时间】:2014-10-27 16:32:30
【问题描述】:

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

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

  • cucumber-android-1.1.8
  • cucumber-core-1.1.8
  • 黄瓜-html-0.2.3
  • 黄瓜-java-1.1.8
  • 黄瓜-junit-1.1.8
  • 黄瓜-jvm-deps-1.0.3
  • 小黄瓜2.12.2
  • robotium-solo-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 测试配置时,(截图如下) 找到了这些功能,但没有找到我的步骤定义。输出显示

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) 注释。

我做错了什么?

【问题讨论】:

  • 先看看,你的test app manifest中的目标包好像有错 - com.novomnetworks.formeval.truckcalibrator.test - remove .test
  • 我已经尝试过使用和不使用,我也尝试将我的 CucumberTest 类不在测试包中(所以它与我的 MainActivity 类是同一个包),但我得到了同样的错误

标签: android android-studio cucumber cucumber-jvm


【解决方案1】:

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

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

【讨论】:

  • 我不明白你想告诉我什么。 Cucumber 甚至找不到那个i_started_the_app 方法,那么它的内容是怎么处理的呢?另外,这正是错误消息告诉我放入我的方法的内容。
  • 你必须删除 throw new PendingException();从你的代码。该行准确地抛出了您在跟踪中看到的消息。 cucumber 告诉你的是你可以使用那个模板,但是你必须删除那一行。删除该行并使用 CucumberOptions 而不是 @RunWith
  • 我删除了throw new PendingException(); 行并将@RunWith 注释替换为@CucumberOptions 注释,但我得到了完全相同的错误。该错误没有提到要删除抛出异常的任何地方,它告诉使用抛出异常命令创建方法...
  • 另一个问题可能是构造函数。我有public CucumberTest (SomeDependency dependency) { super(MainActivity.class); }
  • 什么是SomeDependency?我的班级应该有什么样的依赖关系?
【解决方案2】:

我遇到了同样的问题,我想我解决了。首先,我们需要在所有黄瓜相关库上使用androidTestCompile 配置。请注意,我们需要对 cucumber-android 库使用 @jar 限定符,以避免 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,它就可以工作。

【讨论】:

    【解决方案3】:

    你的测试应该在文件夹src/androidTest而不是src/test

    此外,我会将 CucumberTest.java 分成一个带有配置注释的 Cucumber Runner 类和一个从 ActivityInstrumentationTestCase2 扩展的单独类,其中包含您的胶水代码。

    这里有一个使用 Cucumber 和 Espresso 代替 Robotium 的 Android Studio 运行示例:

    https://github.com/neoranga55/CleanGUITestArchitecture

    【讨论】:

    • 我可以确认您的测试是在 android studio 中运行的,如果我们使用 CucumberTestRunner.java 运行它,有没有什么方法可以一次运行一个场景以便于测试方法?
    • 我使用标签,然后在启动测试时按标签过滤以仅运行一个测试用例,例如:./gradlew connectedAndroidTest -Ptags="@test-scenario-whatever-id-001"
    猜你喜欢
    • 1970-01-01
    • 2016-10-15
    • 2022-08-19
    • 1970-01-01
    • 1970-01-01
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多