Back to Repositories

Testing Drawable CrossFade Transitions in Glide Library

This test suite validates the DrawableCrossFadeTransition functionality in Glide’s image loading library, focusing on transition animations between drawables. It ensures proper handling of cross-fade effects, null views, and drawable state management.

Test Coverage Overview

The test suite provides comprehensive coverage of the DrawableCrossFadeTransition implementation.

Key areas tested include:
  • Null view handling in transitions
  • Transition behavior with and without previous drawables
  • Proper TransitionDrawable setup
  • State management during drawable transitions

Implementation Analysis

The testing approach utilizes JUnit and Robolectric for Android drawable testing. It employs a harness pattern for test setup and implements mock objects for ViewAdapter interactions.

Notable patterns include:
  • Use of @RunWith(RobolectricTestRunner.class) for Android environment simulation
  • Mockito verification for drawable state changes
  • Consistent test fixture setup via @Before methods

Technical Details

Testing infrastructure includes:
  • Robolectric SDK configuration for Android environment
  • Mockito for mocking ViewAdapter behaviors
  • JUnit 4 test framework
  • Custom CrossFadeHarness class for test setup
  • ColorDrawable implementations for transition testing

Best Practices Demonstrated

The test suite exemplifies several testing best practices:

  • Isolated test cases with clear, single-responsibility assertions
  • Proper test setup separation using @Before annotations
  • Consistent naming convention for test methods
  • Effective use of mock objects to isolate system under test
  • Clear separation of concerns in test organization

bumptech/glide

library/test/src/test/java/com/bumptech/glide/request/transition/DrawableCrossFadeViewAnimationTest.java

            
package com.bumptech.glide.request.transition;

import static com.bumptech.glide.RobolectricConstants.ROBOLECTRIC_SDK;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import com.bumptech.glide.request.transition.Transition.ViewAdapter;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

@RunWith(RobolectricTestRunner.class)
@Config(sdk = ROBOLECTRIC_SDK)
public class DrawableCrossFadeViewAnimationTest {
  private CrossFadeHarness harness;

  @Before
  public void setup() {
    harness = new CrossFadeHarness();
  }

  @Test
  public void testIgnoresNullViews() {
    when(harness.adapter.getView()).thenReturn(null);
    harness.animation.transition(harness.current, harness.adapter);
  }

  @Test
  public void transition_withNonNullPreviousDrawable_setsTransitionDrawable() {
    Drawable previous = new ColorDrawable(Color.WHITE);
    when(harness.adapter.getCurrentDrawable()).thenReturn(previous);
    harness.animation.transition(harness.current, harness.adapter);

    verify(harness.adapter).setDrawable(any(TransitionDrawable.class));
  }

  @Test
  public void transition_withNullPreviousDrawable_setsTransitionDrawable() {
    harness.animation.transition(harness.current, harness.adapter);

    verify(harness.adapter).setDrawable(any(TransitionDrawable.class));
  }

  @Test
  public void transition_withNoCurrentDrawable_returnsTrue() {
    assertTrue(harness.animation.transition(harness.current, harness.adapter));
  }

  @Test
  public void transition_withCurrentDrawable_returnsTrue() {
    Drawable previous = new ColorDrawable(Color.RED);
    when(harness.adapter.getCurrentDrawable()).thenReturn(previous);
    assertTrue(harness.animation.transition(harness.current, harness.adapter));
  }

  @SuppressWarnings("unchecked")
  private static class CrossFadeHarness {
    final Drawable current = new ColorDrawable(Color.GRAY);
    final ViewAdapter adapter = mock(ViewAdapter.class);
    final int duration = 200;
    final DrawableCrossFadeTransition animation =
        new DrawableCrossFadeTransition(duration, true /*isCrossFadeEnabled*/);
  }
}