小编Chu*_*ger的帖子

如何为android单元测试提供数据文件

我正在开发使用Android的java.xml.parsers.DocumentBuilder和DocumentBuilderFactory实现从XML文件加载信息的软件.我正在编写我的对象的单元测试,我需要能够提供各种xml文件来运行测试中的代码.我正在使用Eclipse并拥有一个单独的Android测试项目.我找不到将测试xml放入测试项目的方法,以便测试中的代码可以打开文件.

  • 如果我将文件放在测试项目的/ assets中,则测试中的代码无法看到它.
  • 如果我把文件放在被测代码的/ assets中,它当然可以看到文件,但现在我把我的实际系统弄得乱七八糟的只有测试数据文件.
  • 如果我将文件复制到/ sdcard/data目录,我可以从被测试的代码中打开它们,但这会干扰我的测试自动化.

任何关于如何让不同的xml测试文件驻留在测试包中但对被测试代码可见的建议将不胜感激.

以下是我尝试构建单元测试的方法:

public class AppDescLoaderTest extends AndroidTestCase
{
  private static final String SAMPLE_XML = "sample.xml";

  private AppDescLoader       m_appDescLoader;
  private Application         m_app;

  protected void setUp() throws Exception
  {
    super.setUp();
    m_app = new Application();
    //call to system under test to load m_app using
    //a sample xml file
    m_appDescLoader = new AppDescLoader(m_app, SAMPLE_XML, getContext());
  }

  public void testLoad_ShouldPopulateDocument() throws Exception
  {
    m_appDescLoader.load();

  }    
}
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为SAMPLE_XML文件位于测试的上下文中,但AndroidTestCase正在为被测系统提供上下文,该系统无法从测试包中看到资产.

这是每个答案给出的修改后的代码:

public class AppDescLoaderTest extends InstrumentationTestCase
{
   ...
  protected void setUp() …
Run Code Online (Sandbox Code Playgroud)

xml android unit-testing junit3

48
推荐指数
2
解决办法
2万
查看次数

如何解决“scanLocation”在 iOS 13.0 中已被弃用

尝试使用扫描仪时,我收到警告:iOS 13.0 中不推荐使用“scanLocation”。由于能够从下一个位置进行扫描是扫描字符串的基础,因此想知道使用什么来代替 scanLocation。Apple 的Scanner文档甚至没有提到弃用,更不用说是什么取代了 scanLocation。

使用已弃用的 scanLocation 的示例:

while !scanner.isAtEnd {
    print(scanner.scanUpToCharacters(from: brackets))
    let block = scanner.string[scanner.currentIndex...]
    print(block)
    scanner.scanLocation = scanner.scanLocation + 1
}
Run Code Online (Sandbox Code Playgroud)

foundation swift

18
推荐指数
2
解决办法
5518
查看次数

即使不是nil,IBOutlet也会与EXC_BAD_ACCESS崩溃

在UIViewController(rolePageController)中,我配置另一个UIViewController(drawerController)并从角色页面传递2个UIViews,该页面将成为drawerController配置的一部分.一旦drawerController尝试从rolePageController访问IBOutlet视图,它就会崩溃EXC_BAD_ACCESS(代码= EXC_I386_GPFLT).

在第一个VC(rolePageController)中,这里是IBOutlets:

@IBOutlet var rolePageDrawerView: UIView!
@IBOutlet var rolePageContentView: UIView!
Run Code Online (Sandbox Code Playgroud)

在rolePageController.viewDidLoad()中,我调用了抽屉控件.configureDrawer(...):

override func viewDidLoad() {
    super.viewDidLoad()

    //other stuff happens here

    let drawerController = UIStoryboard(name: "StoryboardName", bundle: nil).instantiateViewController(withIdentifier: "drawerController") as! DrawerViewController
    drawerController.configureDrawer(drawerContainerView: self.rolePageDrawerView, overlaidView: self.rolePageContentView)

    //other stuff here
}
Run Code Online (Sandbox Code Playgroud)

DrawerViewController协议定义为:

protocol DrawerViewController where Self: UIViewController {
    func configureDrawer(drawerContainerView: UIView, overlaidView: UIView)
}
Run Code Online (Sandbox Code Playgroud)

这是configureDrawer(...)func的代码:

private var drawerParentView: UIView!
private var overlaidByDrawerView: UIView!


func configureDrawer(drawerContainerView: UIView, overlaidView: UIView) {
    self.drawerParentView = drawerContainerView
    self.overlaidByDrawerView = overlaidView
}
Run Code Online (Sandbox Code Playgroud)

在调试器中注意到,调用的drawerController实例与接收调用的self实例不匹配.这是将被调用的实例的地址:

在此输入图像描述

这是我进入呼叫时实例的地址:

在此输入图像描述

当我进入呼叫时,呼叫前抽屉控制器的地址不是自己的地址.这绝不应该发生.

我创建了一个简化的项目,通过https://github.com/ksoftllc/DynamicStackBufferOverflow重现崩溃. …

exc-bad-access uiviewcontroller ios swift swift-protocols

17
推荐指数
2
解决办法
656
查看次数

在完成AsyncTask后,如何处理解除DialogFragment(兼容性lib)的问题

关于如何在AsyncTask期间处理配置更改的帖子很多,但是当AsyncTask完成并尝试解除DialogFragment(兼容性库)时,我找不到任何关于后台应用程序(onPause())的明确解决方案.

这是问题,如果我有一个AsyncTask运行应该解雇onPostExecute()中的DialogFragment,如果应用程序在后台尝试关闭DialogFragment时,我会收到IllegalStateException.

private static class SomeTask extends AsyncTask<Void, Void, Boolean> {

    public SomeTask(SomeActivity tActivity)
    {
        mActivity = tActivity;
    }

    private SomeActivity mActivity;

    /** Set the view during/after config change */
    public void setView(Activity tActivity) {
        mActivity tActivity;
    }

    @Override
    protected Boolean doInBackground(Void... tParams) {
        try {
          //simulate some time consuming process
          TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException ignore) {}
        return true;
    }

    @Override
    protected void onPostExecute(Boolean tRouteFound) {
        mActivity.dismissSomeDialog();  
    }

}
Run Code Online (Sandbox Code Playgroud)

活动看起来像这样:

import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;

public class SomeActivity extends FragmentActivity { …
Run Code Online (Sandbox Code Playgroud)

java android android-fragments

13
推荐指数
2
解决办法
2万
查看次数

如何从我的.apk文件中打包的jar文件中加载一个类?

我正在尝试从jar文件加载一个接口的插件实现,该文件位于我的.apk文件的/ assets目录中.我能够让它工作的唯一方法是将jar文件解压缩到私有外部存储器,然后将该文件传递给DexClassLoader.

这有效,但为什么jar必须存在于两个地方(.apk和私人外部存储)?DexClassLoader必须以文件路径作为参数.

有没有办法给它一个直接路径到/ assets文件夹中的文件,这样我就不必使用外部存储来获取已存在的文件的额外副本?

以下是相关的代码段:

// somewhere in my main Activity ...
  final File aExtractedDexFile = new File(getDir("dex", Context.MODE_PRIVATE),
                                  LIBRARY_DEX_JAR);
  extractDexTo(aExtractedDexFile);
  loadLibraryProvider(aExtractedDexFile);
Run Code Online (Sandbox Code Playgroud)

/** Extract the jar file that contains the implementation class.dex and place in private storage */
private void extractDexTo(File tJarInternalStoragePath) {
  BufferedInputStream aJarInputStream = null;
  OutputStream aDexOutputStream = null;

  try {
    aJarInputStream = new BufferedInputStream(getAssets().open(LIBRARY_DEX_JAR));
    aJarOutputStream = new BufferedOutputStream(new FileOutputStream(tJarInternalStoragePath));
    byte[] buf = new byte[BUF_SIZE];
    int len;
    while ((len = aJarInputStream.read(buf, 0, BUF_SIZE)) > 0)
    { …
Run Code Online (Sandbox Code Playgroud)

android assets classloader

7
推荐指数
1
解决办法
3351
查看次数

UITextView仅在iPad上无法正确调整大小

我有一个静态UITableView,在1节中有3行.每行包含一个UITextView,它应根据内容调整大小.每个UITextView对象都禁用了滚动以强制它增长.每个都固定在单元格的contentView的所有4个边上,没有其他约束.

当我在iPad(真实或SIM卡)上运行时,无论UITextView的内容如何,​​单元格都会调整为单行文本.当我在调试器中检查视图层次结构时,我看到即使内容视图高度为183.5,UITextView高度也被设置为27.5.这似乎是UITableViewCellContentView上的高度约束的结果,它限制了单元格高度.这不是我设置的约束.我的表视图控制器没有heightForRow或cellForRow方法,因为它是一个静态表视图,并为所有内容使用自动布局.我不知道如何添加这个约束.

在此输入图像描述

这是完全相同的层次结构,在iPod touch上运行的完全相同的点上具有完全相同的内容.请注意,这次UITextView高度和内容高度相同.在这种情况下,UITableViewCellContentView对高度的约束足够大以容纳UITextView高度.

在此输入图像描述

在这两种情况下,这是执行和显示相同内容的相同源.该内容包含带有回车符的短文本行,这就是为什么它应在两种屏幕尺寸中调整到相同内容大小的原因.UITextView希望将其高度调整为183.5,但在iPad上,单元格高度受到iOS生成的约束的不必要限制.

这是viewDidLoad的代码:

- (void)viewDidLoad {
    [super viewDidLoad];

    //shrink the uiswitch a little bit
    self.displayRegexCharsSwitch.transform  = CGAffineTransformMakeScale(0.70, 0.70);

    //these next 2 lines set up the table to automatically resize based on content
    self.tableView.estimatedRowHeight = 100.0f;
    self.tableView.rowHeight = UITableViewAutomaticDimension;

    //next line hides the blank cells
    self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];

    //these are needed on iPad or rows with accessory view don't resize
    [self.tableView beginUpdates];
    [self.tableView endUpdates];
}
Run Code Online (Sandbox Code Playgroud)

同样,由于使用静态表视图,表视图控制器中没有heightForRow或cellForRow.

我很困惑.如果内容相同且代码相同,为什么UITextField在iPad上报告的内容大小与iPod上的内容大小不同?从层次结构视图可以清楚地看出,UITextField内部知道它的高度为200,但contentSize返回27.5.这是一个静态表视图,因此没有heightForRow方法,也没有cellForRow方法.我依靠自动布局来管理所有布局 - 它在iPad上正确运行.

编辑

仅供参考 - 该设计完全基于Any/Any尺寸等级.

在此输入图像描述

objective-c uitextview ipad ios autolayout

7
推荐指数
1
解决办法
431
查看次数

有没有办法在Android上使用junit.extensions.TestSetup进行测试?

android sdk源包含junit.extensions的源代码,但是这些类不在android.jar中,即使junit.framework和junit.runner在那里.我尝试创建自己的junit.extensions包并使用android sdk源中包含的源代码,但是我得到了一个ClassCastException(见下文).android.test.suitebuilder中的东西试图将套接字()方法的返回值强制转换为TestCase,即使套件返回Test接口.

我想使用junit.extensions中的TestSetup类,如下例所示(参见http://etutorials.org/Programming/Java+extreme+programming/Chapter+4.+JUnit/4.7+One-Time+Set+Up +和+撕裂+向下/):

public SomeTestCase extends TestCase {

  public static Test suite() {
    TestSetup setup = new TestSetup(new TestSuite(SomeTestCase.class)) {
      @Override
      protected void setUp(  ) throws Exception {
          // do your one-time setup here!
      }

      @Override
      protected void tearDown(  ) throws Exception {
          // do your one-time tear down here!
      }
    };
    return setup;
  }

  public void someTestMethod() { }

}
Run Code Online (Sandbox Code Playgroud)

但是,我收到以下错误:

05-21 08:10:14.152: I/TestRunner(1316): java.lang.RuntimeException: Exception during suite construction
05-21 08:10:14.152: I/TestRunner(1316):     at android.test.suitebuilder.TestSuiteBuilder$FailedToCreateTests.testSuiteConstructionFailed(TestSuiteBuilder.java:238)
05-21 …
Run Code Online (Sandbox Code Playgroud)

junit android

6
推荐指数
0
解决办法
1229
查看次数

XCode 5.1预处理器宏无法正常工作

我无法得到这个宏来编译正确的代码.

这是代码: 在此输入图像描述

以下是构建设置(我正在进行发布构建): 在此输入图像描述 请注意,GCC文档说-Dname将定义为1,因此我省略了Release的"= 1": 在此输入图像描述

这是编译日志,显示定义(黄色)在命令行上传递: 在此输入图像描述

这是我的输出日志,显示代码被编译为好像没有定义ADD_CAMERA_FEATURE: 在此输入图像描述

如果我在源中放入#define ADD_CAMERA_FEATURE 1,#ifdef会按预期工作,但我也会收到警告,我正在重新定义现有的宏.因此,XCode知道宏应该从构建方案设置中存在,但仍然不包括#ifdef代码分支.

其他详情:

  1. XCode 5.1
  2. OS X 10.9.2
  3. iOS 7.1

我的目标是建立一个目标,用于构建iOS 7版本的应用程序,以及构建应用程序的iOS 7之前版本的目标,两者都来自同一个来源.我必须支持那些无法再升级到iOS 7的旧设备.也许有更好的方法可以解决这个问题.任何关于如何实现这一点的建议将不胜感激.

macros xcode objective-c ios

6
推荐指数
1
解决办法
5524
查看次数

如何在Android上使用带有jUnit的Hamcrest匹配器

我对Android有些陌生,并且在如何将Hamcrest匹配器包含在我的测试项目中已经花了好几个小时.代码看起来应该在Eclipse中运行,没有指示错误.但是当我运行测试时,Hamcrest类没有加载.我得到"NoClassDefFoundError:org.hamcrest.Matchers".

我花了最后3个小时来查看论坛,发现有人之前遇到过这个,但没有运气.我必须做一些愚蠢的事情,因为IDE可以看到类,但运行时没有.

这是测试来源:

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import org.hamcrest.Matcher;
import android.test.InstrumentationTestCase;

public class AppDescLoaderTest extends InstrumentationTestCase {

  public void testHamcrest() {
    assertThat(3, equalTo(3));
  }
}
Run Code Online (Sandbox Code Playgroud)

我尝试将hamcrest-all-1.2.jar添加为库和外部jar.两种方式都有相同的结果,代码在IDE中看起来很好,但无法在运行时加载类.

我的理论是hamcrest.jar不会使用.apk文件,这就是为什么它的类没有被加载.如果这是真的,我如何将它与.apk文件一起推送到android?

junit android unit-testing hamcrest

2
推荐指数
1
解决办法
2296
查看次数

无法销毁使用 Core Data 和 SQLite 创建的持久存储

我有一个 iOS 应用程序,我想在每次启动时从一个新的 Core Data 数据库开始。存储类型是 SQLite。

但是,当我调用 persistentStoreCoordinator.destroyPersistentStore() 时,我 100% 都会收到错误消息。

这是代码:

func destroyPersistentStore() {
    guard let modelURL = Bundle.main.url(forResource: self.modelName, withExtension: "momd") else {
        print("Missing data model - could not destroy")
        return
    }

    do {
        try persistentStoreCoordinator.destroyPersistentStore(at: modelURL, ofType: storeType, options: nil)
    } catch  {
        print("Unable to destroy persistent store: \(error) - \(error.localizedDescription)")
   }
}
Run Code Online (Sandbox Code Playgroud)

错误是:

无法销毁持久存储:Error Domain=NSSQLiteErrorDomain Code=14 "(null)" UserInfo={NSFilePath=.../AppName.app/ModelName.momd, reason=Failed to truncate database} - 操作无法完成. (NSSQLiteErrorDomain 错误 14。)

即使发生此错误,该应用程序仍可以保存和访问商店中的数据。问题在于每次启动时都会加载初始数据,从而产生重复数据。

下面是调用 destroyPersistentStore 时的情况:

  1. SQLite 数据文件肯定存在并且包含数据
  2. 发生在模拟器或真机上
  3. modelUrl …

core-data ios swift

0
推荐指数
1
解决办法
1597
查看次数