Android的单元测试多线程 [英] Android unit tests with multiple threads

查看:375
本文介绍了Android的单元测试多线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在Android的单元测试的一个问题。

I have a problem with unit tests in Android.

我的对象为MyObject有一个方法的start()是这样的:

My object MyObject has a method start() like this :

public void start() {
    final Handler onStartHandler = new Handler();
    new Thread() {
        @Override
        public void run() {
            super.run();

            onStartHandler.post(new Runnable() {
                @Override
                public void run() {
                    mIsRunning = true;
                    onStart();
                }
            });
        }
    }.start();
}

和我想测试ONSTART()被调用。 所以,我想是这样的:

And I want to test that onStart() is called. So I tried something like that :

public void testOnStartIsCalled() {
    assertFalse("onStart() should not be called", mMyObject.isRunning());
    mMyObject.start();
    assertTrue("onStart() should be called", mMyObject.isRunning());
    mMyObject.stop();
    assertFalse("onStop() should be called", mMyObject.isRunning());
}

但它不工作,我想这是因为它是在一个处理器和一个新的主题。

But it doesn't work, I guess it's because it's in a Handler and a new Thread.

我的测试类扩展AndroidTestCase。 我该怎么办 ?这究竟是什么情况下,最好的做法是什么?

My test class extends AndroidTestCase. What should I do ? What is the best practice for this case ?

问候。

推荐答案

当我处理测试一些多线程code我尝试让程序采取尽可能多的自然流动成为可能。此外,我避免使用睡眠语句,因为你没有得到任何保证,您所选择的睡眠时间间隔足以让你测试的主题来完成它在做什么;你经常最终不得不选择睡眠间隔太大的这迫使慢得多的执行你的测试用例。

When I deal with testing some multi-threaded code I try to let the program take as much of its natural flow as possible. Additionally, I avoid the use of sleep statements since you don't get any guarantees that the sleep interval you've chosen is enough to allow the subject of your test to finish what it's doing; you often end up having to choose sleep intervals that are too large and it forces a much slower execution of your test cases.

我会建议您尝试添加一些code到正在测试的类,在这种情况下为MyObject ,其中所说的监听器,每当有事情发生。看来你已经有所回调方法 ONSTART()的onStop()(如果这些事件/回调) ,所以这些应该得到调用,您可以用它来控制你的测试流程。当你得到一个 ONSTART()事件,那么你就应该叫停止()和等待的onStop()事件。

I would recommend that you try to add some code into the class you're testing, in this case MyObject, which call a listener whenever something happens. It seems that you already have callback methods for onStart() and onStop()(if those are events/callbacks), so those should be getting invoked and you should use them to control the flow of your test. When you get an onStart() event, you should then call stop() and wait for an onStop() event.

首先,你有多余的code:

First and foremost, you have redundant code:

public void start() {
    final Handler onStartHandler = new Handler();
    new Thread() {
        @Override
        public void run() {
            super.run();

            onStartHandler.post(new Runnable() {
                @Override
                public void run() {
                    mIsRunning = true;
                    onStart();
                }
            });
        }
    }.start();
}

无论是开始一个新的线程调用 ONSTART()或计划可运行在处理器的线程队列中。

Either start a new thread to call onStart() or schedule the runnable on the Handler's thread queue.

1版删除的处理程序,只是让code在一个新的线程来执行:

Version 1- remove the handler and just let the code be executed in a new thread:

public void start() {
    new Thread() {
        @Override
        public void run() {
            super.run();
            mIsRunning = true;
            onStart();
        }
    }.start();
}

版2 - 仅使用handler异步执行回调:

Version 2- only use the handler to asynchronously execute the callback:

public void start() {
    final Handler onStartHandler = new Handler();

    onStartHandler.post(new Runnable() {
        @Override
        public void run() {
            mIsRunning = true;
            onStart();
        }
    });
}

和第二:我注意到的是,如果你没有一个活套,然后不管您发布的处理程序将被忽略(因此它永远不会被调用)。有关乐句处理程序模式的更多信息,请参阅文章: Android的胆量:简介为活套和处理程序。该尺蠖处理程序都应该连接到同一个线程(通常是主线程)。此外,如果你在一个单独的线程作为你的尺蠖,那么你会碰到的创建处理程序同样的问题:任何你发布的处理程序将被忽略。

And second: I noticed is that if you don't have a Looper, then whatever you post with the Handler will be ignored (thus it will never be called). For more information on the Looper-Handler pattern see the article: Android Guts: Intro to Loopers and Handlers. The Looper and the Handler are supposed to be attached to the same thread (usually the main thread). Additionally, if you're creating the Handler on a separate thread as your Looper, then you'll run into the same problem: anything you post with the Handler will be ignored.

下面是一些比较详细的活套和处理好问题和文章:

Here are a few more good questions and articles on loopers and handlers:

  • Just do IT: looper and handler in android
  • Handler-Looper implementation in Android

尺蠖,处理程序和MessageQueue之间的关系如下图所示:

The relationships between Looper, Handler and MessageQueue is shown below:

这篇关于Android的单元测试多线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆