Android单元测试环境配置指南
来源:互联网 发布:目前淘宝卖什么最火 编辑:程序博客网 时间:2024/06/05 06:30
由于客户要求手机端APP要有单元测试并达到一定的覆盖率,本人花了几天研究一下AndroidStudio下单元测试的环境配置,经历了大大小小不少坑,这里写出来给需要的小伙伴一个参考。
1.概念
安卓测试分为AndroidInstrumentTest和AndroidUnitTest。区别是前者需要安卓模拟器或实机测试,后者只需JVM环境。
使用AndroidStudio创建Android项目后可以看到src下有如下目录
其中androidTest存在AndroidInstrumentTest代码,test存在AndroidUnitTest代码。
相比较来说,使用AndroidUnitTest更舒服一些。AndroidInstrumentTest的话大家可以想象一下在模拟器或实机上调试Android工程,速度是比较慢的。
所以这里配置的是AndroidUnitTest的环境。
2.配置
AndroidStudio自带JUnit,但是这个尚不足够。Android程序是运行在DVM上的,想要他在JVM环境下直接运行,就需要一个模拟环境。这就需要第三方测试框架Robolectric。具体就不介绍了,大家可以上官方网站自己看,配置方法也很简单:
修改build.gradle里的dependencies
dependencies { ... testCompile ('junit:junit:4.12') testCompile ('org.robolectric:robolectric:3.2.2') testCompile ("org.robolectric:shadows-support-v4:3.2") ...}
其中shadows-support-v4提供了对应support-v4包的测试类,如果不需要删除。
测试类配置如下
@RunWith(RobolectricTestRunner.class)@Config(constants = BuildConfig.class, sdk = 22)public class ExampleUnitTest { @Before public void setup() { ... } @Test public void addition_isCorrect() throws Exception { assertEquals(4, 2 + 2); }}
是不是很简单?然而如果仅仅是这样就没必要写这篇文章了,请大家往下看
3.遇到的坑
如果你在国内且没有VPN,在配置dependencies后,你就会发现gradle在自动build下载时很慢。就算你耐心等待它完成后,在运行时你会发现Robolectric会需要根据你的配置进一步下载一些包,包很大,下载速度却慢的令人发指。
这里推荐使用aliyun的国内maven镜像库。
修改工程目录下的build.gradle
buildscript { repositories { jcenter(){ url 'http://maven.aliyun.com/nexus/content/groups/public/'} } dependencies { classpath 'com.android.tools.build:gradle:2.2.3' }}allprojects { repositories { jcenter(){ url 'http://maven.aliyun.com/nexus/content/groups/public/'} }}task clean(type: Delete) { delete rootProject.buildDir}
Gradle的build问题就解决了。但是Robolectric呢?
官方网站上推荐设置systemProperty来手动修改库的url,修改方法如下
android { testOptions { unitTests.all { systemProperty 'robolectric.dependency.repo.url', 'https://local-mirror/repo' systemProperty 'robolectric.dependency.repo.id', 'local' } }}
然而这不起作用,所以这里需要修改RobolectricTestRunner.class。
本人这里就直接在网上找个代码。当然到GitHub上找到Robolectric原代码自己重写也是可以的
public class CustomRepoRobolectricTestRunner extends RobolectricTestRunner { public static final String REP_URL = "http://maven.aliyun.com/nexus/content/groups/public/"; public static final String REP_ID = "aliyun_mirror"; public CustomRepoRobolectricTestRunner(Class<?> klass) throws InitializationError { super(klass); } //覆盖该方法 可以定制DependencyResolver @Override protected DependencyResolver getJarResolver() {// String repoUrl = System.getProperty("robolectric.dependency.repo.url", ".");// String repoId = System.getProperty("robolectric.dependency.repo.id", "."); String repoUrl = REP_URL; String repoId = REP_ID; if (StringUtils.isNotEmpty(repoUrl) && StringUtils.isNotEmpty(repoId)) { File cacheDir = new File(new File(System.getProperty("java.io.tmpdir")), "robolectric"); cacheDir.mkdir(); DependencyResolver dependencyResolver; //如果设置了robolectric.dependency.repo.url属性,则利用LocalNetDependencyResolver来解决依赖 //这样便可以调整仓库地址 if (cacheDir.exists()) { Logger.info("Dependency cache location: %s", cacheDir.getAbsolutePath()); dependencyResolver = new CachedDependencyResolver( new LocalNetDependencyResolver(repoUrl, repoId), cacheDir, 60 * 60 * 24 * 1000 ); } else { dependencyResolver = new LocalNetDependencyResolver(repoUrl, repoId); } return dependencyResolver; } else { return super.getJarResolver(); } } private static class LocalNetDependencyResolver implements DependencyResolver { private String mRepoUrl; private String mRepoId; private final Project project = new Project(); public LocalNetDependencyResolver(String repoUrl, String repoId) { mRepoId = repoId; mRepoUrl = repoUrl; } @Override public URL[] getLocalArtifactUrls(DependencyJar... dependencies) { DependenciesTask dependenciesTask = new DependenciesTask(); configureMaven(dependenciesTask); RemoteRepository sonatypeRepository = new RemoteRepository(); sonatypeRepository.setUrl(mRepoUrl); sonatypeRepository.setId(mRepoId); dependenciesTask.addConfiguredRemoteRepository(sonatypeRepository); dependenciesTask.setProject(project); for (DependencyJar dependencyJar : dependencies) { Dependency dependency = new Dependency(); dependency.setArtifactId(dependencyJar.getArtifactId()); dependency.setGroupId(dependencyJar.getGroupId()); dependency.setType(dependencyJar.getType()); dependency.setVersion(dependencyJar.getVersion()); if (dependencyJar.getClassifier() != null) { dependency.setClassifier(dependencyJar.getClassifier()); } dependenciesTask.addDependency(dependency); } dependenciesTask.execute(); @SuppressWarnings("unchecked") Hashtable<String, String> artifacts = project.getProperties(); URL[] urls = new URL[dependencies.length]; for (int i = 0; i < urls.length; i++) { try { urls[i] = Util.url(artifacts.get(key(dependencies[i]))); } catch (MalformedURLException e) { throw new RuntimeException(e); } } return urls; } @Override public URL getLocalArtifactUrl(DependencyJar dependency) { URL[] urls = getLocalArtifactUrls(dependency); if (urls.length > 0) { return urls[0]; } return null; } private String key(DependencyJar dependency) { String key = dependency.getGroupId() + ":" + dependency.getArtifactId() + ":" + dependency.getType(); if (dependency.getClassifier() != null) { key += ":" + dependency.getClassifier(); } return key; } protected void configureMaven(DependenciesTask dependenciesTask) { // maybe you want to override this method and some settings? } }}
这里我直接在代码中写了URL,其实通过Gradle配置SystemProperty更为合理。
修改测试代码
@RunWith(CustomRepoRobolectricTestRunner.class)@Config(constants = BuildConfig.class, sdk = 22)public class ExampleUnitTest { @Before public void setup() { } @Test public void addition_isCorrect() throws Exception { assertEquals(4, 2 + 2); }}
这样就配置后可以看到能跑起来了。
还有个注意点Robolectric的sdk版本推荐配置为22,不要试图在更高版本上运行。
参考:
1.http://blog.csdn.net/x356982611/article/details/21983267
2.http://robolectric.org/
3.https://github.com/robolectric/robolectric
- Android单元测试环境配置指南
- Android 单元测试之Roboletric 环境配置
- Xcode单元测试环境配置
- iOS_Xcode单元测试环境配置
- junit单元测试环境配置
- 搭建android单元测试环境
- Android----搭建单元测试环境
- 实体环境中配置Android项目Ubuntu开发环境指南
- Yii单元测试环境配置总结
- Android配置 常规单元测试
- Android配置 常规单元测试
- android单元测试 配置注意
- Android:单元测试Junit配置
- Android单元测试的配置
- android 添加单元测试配置
- Android配置单元测试
- android 单元测试配置
- Android单元测试的配置
- linux下如何卸载opencv
- 再论数据科学竞赛中的Data Leakage
- LeetCode之路——Palindrome Number
- ViewPager异常总结
- LeetCode-190. Reverse Bits
- Android单元测试环境配置指南
- RHCE 6.7虚拟机克隆后网卡无法启动
- hdu 1907 John(组合游戏 NIM变形)@
- 堆栈简介
- Activity的四种启动模式
- Linux远程传输scp命令
- 【Get深一度】卷积
- LeetCode 4. Median of Two Sorted Arrays
- 环境变量设置中的疑问