草庐IT

android - 在 Android Studio 的 Android 项目中运行快速 JUnit 测试的最佳方式

coder 2023-12-01 原文

我的 Android Studio 项目中有一些普通的旧 Java 类和简单的 JUnit 测试。它们目前位于我的 Android 模块中。如果我将它们作为 Android 测试运行,它们会顺利通过,但它们真的很慢,因为它需要启动或连接到模拟器。

如果我尝试运行一个作为 JUnit 测试,我会点击 !!! JUnit version 3.8 or later expected JUnit 版本问题。这answer解释了如何解决该问题。不幸的是,我随后遇到了 java.lang.NoClassDefFoundError: junit/textui/ResultPrinter,我不知道如何修复。

然后我尝试将我的 JUnit 测试移动到一个独立的 Java 模块中,该模块依赖于 Android 模块。一切都很好。我添加了一个新配置来启动 JUnit 测试 (:MyJUnitTests:test),但测试失败并显示 package com.myproject.util does not exist。看起来类路径可能不包括依赖 Android 模块的类。

有人知道如何解决这个类路径问题吗?我看过很多相关的答案,但似乎没有一个对我有用。或者尝试将我的 JUnit 测试保留在它们自己的模块中只是一个坏主意?

如果我将纯 Java 类及其 JUnit 测试移动到一个完全独立的模块(例如 here ),并反转依赖关系,那么 Android 模块将依赖于 Java 模块,我可以让 JUnit 测试快速运行并通过.这是首选解决方案吗?

最佳答案

基本问题是 Android Framework 类在 Android 操作系统上下文之外不能正常工作,因此任何依赖于 Framework 类的代码都不能在常规 JUnit 环境中运行,正如您所发现的那样。

您尝试将 JUnit 测试移动到单独模块中的解决方案将行不通,因为您不能让纯 Java 模块依赖于 Android 模块。 Android Gradle 模块的行为不像 Java 模块,因为 Android 构建要复杂得多,而且 Android 模块构建的最终结果将是 APK 或 AAR,其他模块类型无法理解。

如果您可以将纯 Java 类和单元测试移动到一个纯 Java 模块中,并让 Android 模块依赖于它,这将是获得 IDE 官方功能最多支持的最佳方法。它还将具有架构优势,因为它将使这些类不受 Android 抽象的影响,使其更具可移植性,并强制将业务逻辑与 UI 或存储或其他更特定于设备的事物分离。

如果这对您来说很难做到,那么很多开发人员都会选择 Robolectric ,这是一个测试工具,允许依赖于 Android Framework 的许多部分的代码在没有模拟器或设备的 JUnit 环境中运行。它没有得到 Google 的官方支持,但 Google 知道它被广泛使用,并努力不去肆意破坏它。

关于android - 在 Android Studio 的 Android 项目中运行快速 JUnit 测试的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24662138/

有关android - 在 Android Studio 的 Android 项目中运行快速 JUnit 测试的最佳方式的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  5. ruby - Ruby 的 Hash 在比较键时使用哪种相等性测试? - 2

    我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。

  6. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  7. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

  8. ruby-on-rails - 迷你测试错误 : "NameError: uninitialized constant" - 2

    我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test

  9. ruby - 即使失败也继续进行多主机测试 - 2

    我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r

  10. ruby-on-rails - 如何使辅助方法在 Rails 集成测试中可用? - 2

    我在app/helpers/sessions_helper.rb中有一个帮助程序文件,其中包含一个方法my_preference,它返回当前登录用户的首选项。我想在集成测试中访问该方法。例如,这样我就可以在测试中使用getuser_path(my_preference)。在其他帖子中,我读到这可以通过在测试文件中包含requiresessions_helper来实现,但我仍然收到错误NameError:undefinedlocalvariableormethod'my_preference'.我做错了什么?require'test_helper'require'sessions_hel

随机推荐