单元测试无疑是个好东西,不然每次都要去编译整个项目然后安装到模拟器启动,按照指定的步骤去看是否有问题,这样非常浪费时间,之前公司的项目超过10万行,每次编译都在3.5分钟左右,遇到需要调试的地方更加花时间。所以决定花时间研究下单元测试。先从数据库开始吧。
1.项目中引入greendao 进行简单的配置
android {
compileSdkVersion rootProject.ext.android.compileSdkVersion
defaultConfig {
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode 1
versionName "1.0"
}
//greendao配置
greendao {
//版本号,升级时可配置
schemaVersion 1
//greendao 根目录
targetGenDir 'src/main/java/'
//单元测试的根目录
targetGenDirTests 'src/main/java/'
//生成的文件的包名
daoPackage 'greendao'
//自动生成单元测试
generateTests true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
testOptions {
unitTests.returnDefaultValues = true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
abortOnError false
}
publishNonDefault true
}
其他配置可以忽略。
然后写一个实体类
@Entity(nameInDb = "test")
public class TestDb {
@Id
@Property(nameInDb = "_id")
private Long id;
@Property(nameInDb = "name")
private String name;
@Generated(hash = )
public TestDb(Long id, String name) {
this.id = id;
this.name = name;
}
@Generated(hash = )
public TestDb() {
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "TestDb{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
build----》makeProject 完成之后就会自动生成
看看自动生成的
package greendao;
import org.greenrobot.greendao.test.AbstractDaoTestLongPk;
import greendao.TestDbDao;
public class TestDbTest extends AbstractDaoTestLongPk {
public TestDbTest() {
super(TestDbDao.class);
}
@Override
protected TestDb createEntity(Long key) {
TestDb entity = new TestDb();
entity.setId(key);
return entity;
}
}
右键运行报错:
java.lang.RuntimeException: Could not prepare DAO Test
at org.greenrobot.greendao.test.AbstractDaoTest.setUp(AbstractDaoTest.java:71)
at org.greenrobot.greendao.test.AbstractDaoTestSinglePk.setUp(AbstractDaoTestSinglePk.java:52)
at junit.framework.TestCase.runBare(TestCase.java:139)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:129)
at junit.framework.TestSuite.runTest(TestSuite.java:252)
at junit.framework.TestSuite.run(TestSuite.java:247)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:86)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMainV2.main(AppMainV2.java:131)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.greenrobot.greendao.test.AbstractDaoTest.setUpTableForDao(AbstractDaoTest.java:78)
at org.greenrobot.greendao.test.AbstractDaoTest.setUp(AbstractDaoTest.java:67)
... 19 more
Caused by: java.lang.NullPointerException
at org.greenrobot.greendao.database.StandardDatabase.execSQL(StandardDatabase.java:37)
at greendao.TestDbDao.createTable(TestDbDao.java:43)
... 24 more
找了很久网上基本上没给什么有用的信息:最后断点的时候发现getcontext 是空的,导致创建的数据库是空的。
这涉及到两点:androidTest 和test 的区别问题,如果是纯java 不需要android模拟器纯java环境的就放在test 目录下,如果需要模拟器提供android 环境相关功能就放在 androidtest 下面,暂时只看到这些。
回头看看我们的配置:
这个很明显不是androidTest目录,那么试着把它改成 androidTest 目录
这个时候生成的文件就在androidTest目录下面了
点进去之后发现报红
手动将包名改一下,之后运行就好了,但是难道每次都要去改包名吗?
网上查到的修改 test路径的方法
android {
sourceSets {
test.root 'src/tests/javaTest'
test.java.srcDirs 'src/tests/javaTest/java'
androidTest.root 'src/tests/androidTest'
androidTest.java.srcDirs 'src/tests/androidTest/java'
}
}
没试过应该是可以的。
或者试着在daopackage 设置成项目的路径
greendao {
//版本号,升级时可配置
schemaVersion 1
//greendao 根目录
targetGenDir 'src/main/java'
//单元测试的根目录
targetGenDirTests 'src/androidTest/java'
//生成的文件的包名
daoPackage '你的项目包名.greendao'注意这里打点不是"/"
//自动生成单元测试
generateTests true
}
右键运行正常
后续就可以在每个TestCase类里面写自己想要测试的逻辑了.
注意!!!
如果生成的test 不是在项目相同的目录下
就是这个自动生成的test 所在的文件夹里面 将不会成功,说会说class not found,
这个坑里面爬了大半天了!!!终于出来了!!!