EndlessShw 2021-08-15 15:40 采纳率: 100%
浏览 589
已结题

测试类报错:AndroidJUnit4ClassRunner for AndroidJUnit4 could not be found.

我在学习编写测试类来测试SQLite中的SQL语句,但是当我右键运行测试函数时,“run” 里面就会报错,Android Studio的版本为4.2.2,运行的安卓为Android11
报错内容如下:

java.lang.RuntimeException: Delegate runner androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner for AndroidJUnit4 could not be found.
    at androidx.test.ext.junit.runners.AndroidJUnit4.throwInitializationError(AndroidJUnit4.java:121)
    at androidx.test.ext.junit.runners.AndroidJUnit4.loadRunner(AndroidJUnit4.java:85)
    at androidx.test.ext.junit.runners.AndroidJUnit4.loadRunner(AndroidJUnit4.java:74)
    at androidx.test.ext.junit.runners.AndroidJUnit4.<init>(AndroidJUnit4.java:48)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
    at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
    at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:37)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:70)
    at org.junit.internal.requests.ClassRequest.createRunner(ClassRequest.java:28)
    at org.junit.internal.requests.MemoizingRequest.getRunner(MemoizingRequest.java:19)
    at org.junit.internal.requests.FilterRequest.getRunner(FilterRequest.java:36)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:50)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Caused by: java.lang.ClassNotFoundException: androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:315)
    at androidx.test.ext.junit.runners.AndroidJUnit4.loadRunner(AndroidJUnit4.java:83)
    ... 18 more

我去询问别人,他给出了办法,一是导入dependencies,二是将测试类放在test文件夹下。要导入的内容如下:

testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

这两个方法都试过后,依旧没有效果。
接着我去bing和谷歌查找,导入尽可能的包,依旧没有结果。
随后我在 【Android-SQLite】测试DAO类_小菜要发财的博客-CSDN博客 在写完DAO类进行增删改查操作后,可以对其进行测试 https://blog.csdn.net/qq_40716430/article/details/105452850 中尝试他的新建configuration方法,可是运行时出现Test framework quit unexpectedly。我尝试使用了在StackOverflow中别人给出的办法,可是依旧没有解决问题。

例如我想测试insert()
这是Dao类:

package com.example.databasedemo;
// 该类用于操作数据库的增删改查

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class Dao {
    private static final String TAG = "Dao";
    private final DatabaseHelper mHelper;

    public Dao(Context context){
        // 创建数据库
        // 步骤:
        // 1. 写一个类去继承SqliteOpenHelper
        // 2. 实现里面的方法
        // 实现的参数介绍
        /**
         *
         * @ context   上下文
         * @ name      数据库名称
         * @ factory   游标工厂
         * @ version   版本号
         */
        // 3. 创建子类对象,再调用getReadableDatabase()/getWriteableDatabase()方法,即可创建数据库

        mHelper = new DatabaseHelper(context);
        mHelper.getWritableDatabase();
    }

    public void insert(){
        // 获取到数据库连接(打开数据库
        SQLiteDatabase db = mHelper.getWritableDatabase();

        // ? 用来防止sql注入
        String sql_insert = "insert into " + Constants.TABLE_NAME + " (id, name, age, salary, phone_number, address) values(?, ?, ?, ?, ?, ?)";
        db.execSQL(sql_insert, new Object[]{1, "Tom", 25, 5000, 110110110, "USA"});
        db.close();
    }
}

这是测试类:

package com.example.databasedemo;
import android.content.Context;

import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;

import junit.framework.TestCase;

import org.junit.Test;
import org.junit.runner.RunWith;


@RunWith(AndroidJUnit4.class)
public class TestDatabase extends TestCase {

    Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();

    @Test
    public void testInsert(){
        // 测试插入数据
        Dao dao = new Dao(appContext);
        dao.insert();
    }
}


这是dependences:
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"

defaultConfig {
    applicationId "com.example.databasedemo"
    minSdkVersion 22
    targetSdkVersion 30
    versionCode 1
    versionName "1.0"
    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}

buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
    }
}
compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
    dependencies {
        implementation 'androidx.appcompat:appcompat:1.2.0'
        implementation 'androidx.core:core-ktx:1.3.2'
        implementation 'com.google.android.material:material:1.2.1'
        implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
        implementation 'androidx.test.ext:junit:1.1.2'
        testImplementation 'junit:junit:4.13.1'
        // Optional -- Robolectric environment
        testImplementation 'androidx.test:core:1.3.0'
        // Optional -- Mockito framework
        testImplementation 'org.mockito:mockito-core:2.18.0'
        testImplementation 'androidx.test.ext:junit:1.1.2'
        androidTestImplementation 'com.android.support:support-annotations:26.1.0'
        androidTestImplementation 'com.android.support.test:rules:1.0.2'
        androidTestImplementation 'com.android.support.test:runner:1.0.2'
        androidTestImplementation 'androidx.test.ext:junit:1.1.2'
        androidTestImplementation "androidx.test.espresso:espresso-core:3.3.0"
        debugImplementation ("androidx.fragment:fragment-testing:1.2.5", {
            exclude group: 'androidx.test', module: 'core'
        })
        }
    }
}

我不知道我是哪里做错了,还是某些方法看错了还是漏看了什么,希望能有人帮忙给个解决办法,或者指出我的错误,抑或是给一个参考学习的方向。非常感谢。

  • 写回答

1条回答 默认 最新

  • EndlessShw 2021-08-20 19:08
    关注

    最终我找到了解决方案。第一个问题在于我将导入包的代码放在的"android"中的dependencies,但是实际上在我重新回顾build.gradle的时候发现,有两个dependencies,所以我重新新建一个项目并且把代码完全复制进去,同时还将依赖库的代码放在的独立在外的dependencies(即不在"android"这个标签中),其次它又报了android Cannot resolve symbol 'AndroidJUnit4'的错误,后来我在 android - Cannot resolve symbol 'AndroidJUnit4' - Stack Overflow Obviously I need the correct import statment to solve this problem. According to the docs for AndroidJUnit4, this should be import android.support.test.runner.AndroidJUnit4; When I do that, Andr... https://stackoverflow.com/questions/30603487/cannot-resolve-symbol-androidjunit4 中找到了解决办法:就是将测试类放在AndroidTest文件夹下而不是Test文件夹下。

    总结一下,两个步骤:

    1. 将依赖库放在独立的dependencies,而不是"android"中的。
    2. 把测试类放在AndroidTest文件夹而不是Test文件夹。

    (我其实还是对这两个dependencies和两个文件夹的区别抱有疑问,接下来会去查询相关内容)

    这是我的build.gradle文件:

    android {
        compileSdkVersion 30
        buildToolsVersion "30.0.3"
    
        defaultConfig {
            applicationId "com.example.databasedemo"
            minSdkVersion 18
            targetSdkVersion 30
            versionCode 1
            versionName "1.0"
    
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_8
            targetCompatibility JavaVersion.VERSION_1_8
        }
    }
    
    dependencies {
    
        implementation 'androidx.appcompat:appcompat:1.2.0'
        implementation 'com.google.android.material:material:1.2.1'
        implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'androidx.test.ext:junit:1.1.2'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    }
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 8月29日
  • 已采纳回答 8月21日
  • 创建了问题 8月15日

悬赏问题

  • ¥15 利用决策森林为什么会出现这样·的问题(关键词-情感分析)
  • ¥15 DispatcherServlet.noHandlerFound No mapping found for HTTP request with URI[/untitled30_war_e
  • ¥15 使用deepspeed训练,发现想要训练的参数没有梯度
  • ¥15 寻找一块做为智能割草机的驱动板(标签-stm32|关键词-m3)
  • ¥15 信息管理系统的查找和排序
  • ¥15 基于STM32,电机驱动模块为L298N,四路运放电磁传感器,三轮智能小车电磁组电磁循迹(两个电机,一个万向轮),怎么用读取的电磁传感器信号表示小车所在的位置
  • ¥15 如何解决y_true和y_predict数据类型不匹配的问题(相关搜索:机器学习)
  • ¥15 PB中矩阵文本型数据的总计问题。
  • ¥15 MATLAB卫星二体模型仿真
  • ¥15 怎么让数码管亮的同时让led执行流水灯代码