我想知道如何在JUnit中将我的测试标记为@Test,因为到目前为止我必须使用'测试...'名称。这意味着:
@Test
private void creatingAcc(){
而不是
private void testCreatingAcc(){
提前致谢
答案 0 :(得分:0)
是的,你可以做到。请按照以下步骤实现:
转到您的应用build.gradle
文件并添加如下所示的测试依赖关系:
androidTestCompile 'com.android.support.test:runner:0.4.1'
androidTestCompile 'com.android.support.test:rules:0.4.1'
androidTestCompile 'com.android.support:support-annotations:24.1.1'
compile 'com.jayway.android.robotium:robotium-solo:5.6.1'
现在你的build.gradle
应该是这样的:
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "24.0.1"
defaultConfig {
applicationId "com.example.piotr.myapplication"
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:24.1.1'
compile 'com.android.support:design:24.1.1'
androidTestCompile 'com.android.support.test:runner:0.4.1'
androidTestCompile 'com.android.support.test:rules:0.4.1'
androidTestCompile 'com.android.support:support-annotations:24.1.1'
compile 'com.jayway.android.robotium:robotium-solo:5.6.1'
}
然后你需要转到你的androidTest
目录并创建Java类并命名为例如MyActivityTestRule
在此文件中输入以下代码:
@Beta
public class MyActivityTestRule<T extends Activity> extends UiThreadTestRule {
private static final String TAG = "ActivityInstrumentationRule";
private final Class<T> mActivityClass;
public Instrumentation getInstrumentation() {
return mInstrumentation;
}
private Instrumentation mInstrumentation;
private boolean mInitialTouchMode = false;
private boolean mLaunchActivity = false;
private T mActivity;
/**
* Similar to {@link #MyActivityTestRule(Class, boolean, boolean)} but with "touch mode" disabled.
*
* @param activityClass The activity under test. This must be a class in the instrumentation
* targetPackage specified in the AndroidManifest.xml
* @see MyActivityTestRule#MyActivityTestRule(Class, boolean, boolean)
*/
public MyActivityTestRule(Class<T> activityClass) {
this(activityClass, false);
}
/**
* Similar to {@link #MyActivityTestRule(Class, boolean, boolean)} but defaults to launch the
* activity under test once per
* <a href="http://junit.org/javadoc/latest/org/junit/Test.html"><code>Test</code></a> method.
* It is launched before the first
* <a href="http://junit.sourceforge.net/javadoc/org/junit/Before.html"><code>Before</code></a>
* method, and terminated after the last
* <a href="http://junit.sourceforge.net/javadoc/org/junit/After.html"><code>After</code></a>
* method.
*
* @param activityClass The activity under test. This must be a class in the instrumentation
* targetPackage specified in the AndroidManifest.xml
* @param initialTouchMode true if the Activity should be placed into "touch mode" when started
* @see MyActivityTestRule#MyActivityTestRule(Class, boolean, boolean)
*/
public MyActivityTestRule(Class<T> activityClass, boolean initialTouchMode) {
this(activityClass, initialTouchMode, true);
}
/**
* Creates an {@link MyActivityTestRule} for the Activity under test.
*
* @param activityClass The activity under test. This must be a class in the instrumentation
* targetPackage specified in the AndroidManifest.xml
* @param initialTouchMode true if the Activity should be placed into "touch mode" when started
* @param launchActivity true if the Activity should be launched once per
* <a href="http://junit.org/javadoc/latest/org/junit/Test.html">
* <code>Test</code></a> method. It will be launched before the first
* <a href="http://junit.sourceforge.net/javadoc/org/junit/Before.html">
* <code>Before</code></a> method, and terminated after the last
* <a href="http://junit.sourceforge.net/javadoc/org/junit/After.html">
* <code>After</code></a> method.
*/
public MyActivityTestRule(Class<T> activityClass, boolean initialTouchMode,
boolean launchActivity) {
mActivityClass = activityClass;
mInitialTouchMode = initialTouchMode;
mLaunchActivity = launchActivity;
mInstrumentation = InstrumentationRegistry.getInstrumentation();
}
/**
* Override this method to set up Intent as if supplied to
* {@link android.content.Context#startActivity}.
* <p>
* The default Intent (if this method returns null or is not overwritten) is:
* action = {@link Intent#ACTION_MAIN}
* flags = {@link Intent#FLAG_ACTIVITY_NEW_TASK}
* All other intent fields are null or empty.
*
* @return The Intent as if supplied to {@link android.content.Context#startActivity}.
*/
protected Intent getActivityIntent() {
return new Intent(Intent.ACTION_MAIN);
}
/**
* Override this method to execute any code that should run before your {@link Activity} is
* created and launched.
* This method is called before each test method, including any method annotated with
* <a href="http://junit.sourceforge.net/javadoc/org/junit/Before.html"><code>Before</code></a>.
*/
protected void beforeActivityLaunched() {
// empty by default
}
/**
* Override this method to execute any code that should run after your {@link Activity} is
* launched, but before any test code is run including any method annotated with
* <a href="http://junit.sourceforge.net/javadoc/org/junit/Before.html"><code>Before</code></a>.
* <p>
* Prefer
* <a href="http://junit.sourceforge.net/javadoc/org/junit/Before.html"><code>Before</code></a>
* over this method. This method should usually not be overwritten directly in tests and only be
* used by subclasses of MyActivityTestRule to get notified when the activity is created and
* visible but test runs.
*/
protected void afterActivityLaunched() {
// empty by default
}
/**
* Override this method to execute any code that should run after your {@link Activity} is
* finished.
* This method is called after each test method, including any method annotated with
* <a href="http://junit.sourceforge.net/javadoc/org/junit/After.html"><code>After</code></a>.
*/
protected void afterActivityFinished() {
// empty by default
}
/**
* @return The activity under test.
*/
public T getActivity() {
if (mActivity == null) {
Log.w(TAG, "Activity wasn't created yet");
}
return mActivity;
}
@Override
public Statement apply(final Statement base, Description description) {
return new ActivityStatement(super.apply(base, description));
}
/**
* Launches the Activity under test.
* <p>
* Don't call this method directly, unless you explicitly requested not to launch the Activity
* manually using the launchActivity flag in
* {@link MyActivityTestRule#MyActivityTestRule(Class, boolean, boolean)}.
* <p>
* Usage:
* <pre>
* @Test
* public void customIntentToStartActivity() {
* Intent intent = new Intent(Intent.ACTION_PICK);
* mActivity = mActivityRule.launchActivity(intent);
* }
* </pre>
* @param startIntent The Intent that will be used to start the Activity under test. If
* {@code startIntent} is null, the Intent returned by
* {@link MyActivityTestRule#getActivityIntent()} is used.
* @return the Activity launched by this rule.
* @see MyActivityTestRule#getActivityIntent()
*/
public T launchActivity(@Nullable Intent startIntent) {
// set initial touch mode
mInstrumentation.setInTouchMode(mInitialTouchMode);
final String targetPackage = mInstrumentation.getTargetContext().getPackageName();
// inject custom intent, if provided
if (null == startIntent) {
startIntent = getActivityIntent();
if (null == startIntent) {
Log.w(TAG, "getActivityIntent() returned null using default: " +
"Intent(Intent.ACTION_MAIN)");
startIntent = new Intent(Intent.ACTION_MAIN);
}
}
startIntent.setClassName(targetPackage, mActivityClass.getName());
startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Log.d(TAG, String.format("Launching activity %s",
mActivityClass.getName()));
beforeActivityLaunched();
// The following cast is correct because the activity we're creating is of the same type as
// the one passed in
mActivity = mActivityClass.cast(mInstrumentation.startActivitySync(startIntent));
mInstrumentation.waitForIdleSync();
afterActivityLaunched();
return mActivity;
}
// Visible for testing
void setInstrumentation(Instrumentation instrumentation) {
mInstrumentation = checkNotNull(instrumentation, "instrumentation cannot be null!");
}
void finishActivity() {
if (mActivity != null) {
mActivity.finish();
mActivity = null;
}
}
/**
* <a href="http://junit.org/apidocs/org/junit/runners/model/Statement.html">
* <code>Statement</code></a> that finishes the activity after the test was executed
*/
private class ActivityStatement extends Statement {
private final Statement mBase;
public ActivityStatement(Statement base) {
mBase = base;
}
@Override
public void evaluate() throws Throwable {
try {
if (mLaunchActivity) {
mActivity = launchActivity(getActivityIntent());
}
mBase.evaluate();
} finally {
finishActivity();
afterActivityFinished();
}
}
}
}
嗯,说实话,这是标准ActivityTestRule
带有额外的getter getInstrumentation()
,我将在我的测试类中使用。
创建一个新的Java类 - 它将是您的测试类并将代码放在下面:
@RunWith(AndroidJUnit4.class)
public class MainActivityTest {
private Solo solo;
private static final String MAIN_ACTIVITY = MainActivity.class.getSimpleName();
@Rule
public MyActivityTestRule<MainActivity> mActivityRule = new MyActivityTestRule<>(MainActivity.class);
@Before
public void setUp() throws Exception {
solo = new Solo(mActivityRule.getInstrumentation(), mActivityRule.getActivity());
}
@Test
public void checkIfMainActivityIsProperlyDisplayed() throws InterruptedException {
solo.waitForActivity("MainActivity", 2000);
solo.assertCurrentActivity(mActivityRule.getActivity().getString(
R.string.error_no_class_def_found, MAIN_ACTIVITY), MAIN_ACTIVITY);
solo.getText("Hello World").isShown();
}
}
正如你所看到的那样并不困难。
希望它会有所帮助