rahatarmanahmed/CircularProgressView

Causes robolectric unable to proceed

Closed this issue · 19 comments

Hi, I was using this library and robolectric (3.0-rc3) for unit test. I found that circularProgressView.startAnimation() will prevent Robolectric from proceeding.

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        CircularProgressView progressView = (CircularProgressView) findViewById(R.id.progress_view);
        progressView.startAnimation();
    }
}

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
public class MainActivityTest {
    @Test
    public void testMainActivity() {
        MainActivity mainActivity = Robolectric.setupActivity(MainActivity.class);
        Assert.assertNotNull(mainActivity);
    }
}

The program will stuck in setupActivity() and the assertion will never be reached. And if I comment out progressView.startAnimation();, then everything works fine. I don't know if its a problem of this library or of Robolectric, but would you take a look at this?

please try write while(1){
} code in oncreate function, and see whether the assertion will be reached or not;

------------------ 原始邮件 ------------------
发件人: "Chris";notifications@github.com;
发送时间: 2015年6月12日(星期五) 上午9:28
收件人: "rahatarmanahmed/CircularProgressView"CircularProgressView@noreply.github.com;

主题: [CircularProgressView] Causes robolectric unable to proceed (#21)

Hi, I was using this library and robolectric (3.0-rc3) for unit test. I found that circularProgressView.startAnimation() will prevent Robolectric from proceeding.
public class MainActivity extends AppCompatActivity { @OverRide protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); CircularProgressView progressView = (CircularProgressView) findViewById(R.id.progress_view); progressView.startAnimation(); } } @RunWith(RobolectricGradleTestRunner.class) @config(constants = BuildConfig.class, sdk = 21) public class MainActivityTest { @test public void testMainActivity() { MainActivity mainActivity = Robolectric.setupActivity(MainActivity.class); Assert.assertNotNull(mainActivity); } }

The program will stuck in setupActivity() and the assertion will never be reached. And if I comment out progressView.startAnimation();, then everything works fine.


Reply to this email directly or view it on GitHub.

@kaoree I don't understand. What is while(1){} code? I don't think java support using integer in while statement.

sorry , true,not 1

------------------ 原始邮件 ------------------
发件人: "Chris";notifications@github.com;
发送时间: 2015年6月12日(星期五) 上午9:42
收件人: "rahatarmanahmed/CircularProgressView"CircularProgressView@noreply.github.com;
抄送: "枫叶"1052942629@qq.com;
主题: Re: [CircularProgressView] Causes robolectric unable to proceed (#21)

@kaoree I don't understand. What is while(1){} code? I don't think java support using integer in while statement.


Reply to this email directly or view it on GitHub.

@kaoree Do you mean that CircularProgressView uses a while(true) loop and that's why the assertion will never be reached?

What happens if you use the cpv_animAutostart option in XML and remove progressViewstartAnimation()?

@rahatarmanahmed It does no difference, the test will still stuck.

Can you try logging before and after progressView.startAnimation() to see if it actually completes? Also maybe a try-catch, in case Robolectric is swallowing the exception.

@rahatarmanahmed I added some logs before and after startAnimation.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        CircularProgressView progressView = (CircularProgressView) findViewById(R.id.progress_view);
        System.out.println("oncreate");
        try {
            progressView.startAnimation();
        } catch (Exception e) {
            System.out.println("exception happened when start animation");
            e.printStackTrace();
        }
        System.out.println("oncreate end");
    }

The "oncreate" and "oncreate end" messages were successfully logged and no exception was thrown.

How about after startActivity()? How do you know the assert statement isn't reached? mainActivity shouldn't be null so it won't say anything.

I know because the test never stops, it just keeps running and running and nothing comes out. If it reaches then there would be a test result output and the running would end. But in this case, it doesn't.

Can you try debugging it and seeing what line it's hanging on? I think you should be able to pause it after it starts hanging.

Hey so I think I know the issue here. With Robolectrics latest release the Animation classes are not faked or shadowed. This means that the actual animations are running. So you must call ShadowLooper.pauseMainLooper() before any animation.

This solution does not work because it is actually running in a loop here:

https://github.com/rahatarmanahmed/CircularProgressView/blob/master/circularprogressview/src/main/java/com/github/rahatarmanahmed/cpv/CircularProgressView.java#L373-L380

I'm not at all familiar with Robolectric so what is the issue with this loop?

I was seeing an infinite loop, I will do some more investigation and post
my findings.

Trevor
On Aug 14, 2015 14:31, "Rahat Ahmed" notifications@github.com wrote:

I'm not at all familiar with Robolectric so what is the issue with this
loop?


Reply to this email directly or view it on GitHub
#21 (comment)
.

I've ran into this issue myself in the following scenario:

  • i had an overlay over my layout with the progress while data was loading
  • when the data loaded the visibility was set to GONE but the view kept animating. The solution to bypass the test was to add the view when showing the loading layout and remove it programatically when hiding the layout.
    My advice for your library is to have the current functionality in case someone else runs into this:
  • move the code from onDetachedFromWindow into a public cancel() method
  • override the setVisibility method in which you call resetAnimation for VISIBLE and cancel() for GONE or INVISIBLE

@alexandrudumbravan a pull request would be very welcome! I am no longer actively maintaining this library.

@alexandrudumbravan thank you for this suggestion. I had similar problems with Espresso tests and your fix seems to have improved the situation. Do you want to submit a pull request or should I?

@lukaszkalnik go ahead. I don't think I would have the time for this

Just released v2.5.0, give it a few hours to show up. This includes @lukaszkalnik's PR, which should hopefully fix this issue.