Back to Repositories

Testing RoundedCorners Bitmap Transformation in Glide

This test suite validates the RoundedCorners transformation functionality in Glide, an image loading library for Android. It performs regression testing across multiple SDK versions to ensure consistent bitmap corner rounding behavior and proper resource management.

Test Coverage Overview

The test suite comprehensively covers RoundedCorners transformation functionality:

  • Basic corner rounding with specific radius
  • Bitmap pool utilization and resource recycling
  • Over-rounded corner scenarios
  • Cross-SDK version compatibility testing
  • Regression testing against canonical bitmap outputs

Implementation Analysis

The testing approach utilizes JUnit4 with Android-specific test runners and custom annotations for SDK segmentation. The implementation leverages BitmapRegressionTester for comparing transformation outputs against canonical resources, ensuring consistent behavior across different Android versions.

Key patterns include bitmap pool management testing and parametrized SDK version testing using @SplitBySdk annotation.

Technical Details

Testing infrastructure includes:

  • AndroidJUnit4 test runner
  • Custom BitmapRegressionTester utility
  • CanonicalBitmap test resources
  • TearDownGlide rule for cleanup
  • ApplicationProvider for context management
  • Custom annotations for test segmentation (@SplitByCpu, @SplitBySdk)

Best Practices Demonstrated

The test suite exemplifies several testing best practices:

  • Proper test cleanup and resource management
  • Systematic regression testing approach
  • Cross-version compatibility validation
  • Isolated test cases with clear objectives
  • Effective use of test rules and setup methods

bumptech/glide

instrumentation/src/androidTest/java/com/bumptech/glide/RoundedCornersRegressionTest.java

            
package com.bumptech.glide;

import static com.google.common.truth.Truth.assertThat;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.test.BitmapRegressionTester;
import com.bumptech.glide.test.CanonicalBitmap;
import com.bumptech.glide.test.GlideApp;
import com.bumptech.glide.test.RegressionTest;
import com.bumptech.glide.test.SplitByCpu;
import com.bumptech.glide.test.SplitBySdk;
import com.bumptech.glide.testutil.TearDownGlide;
import java.util.concurrent.ExecutionException;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;
import org.junit.rules.TestRule;
import org.junit.runner.RunWith;

/**
 * Compares the output of RoundedCorners with canonical resource files for all SDKs Glide supports
 * and fails on deltas.
 */
@RunWith(AndroidJUnit4.class)
@SplitByCpu
@SplitBySdk({26, 24, 23, 21, 19, 18, 16})
@RegressionTest
public class RoundedCornersRegressionTest {
  @Rule public final TestRule tearDownGlide = new TearDownGlide();
  @Rule public final TestName testName = new TestName();

  private Context context;
  private BitmapRegressionTester bitmapRegressionTester;
  private CanonicalBitmap canonicalBitmap;

  @Before
  public void setUp() throws Exception {
    context = ApplicationProvider.getApplicationContext();
    bitmapRegressionTester =
        BitmapRegressionTester.newInstance(getClass(), testName).assumeShouldRun();
    canonicalBitmap = new CanonicalBitmap();
  }

  @Test
  public void testRoundedCorners() throws ExecutionException, InterruptedException {
    bitmapRegressionTester.test(
        GlideApp.with(context)
            .asBitmap()
            .load(canonicalBitmap.getBitmap())
            .transform(new RoundedCorners(5)));
  }

  @Test
  public void testRoundedCorners_usePool() throws ExecutionException, InterruptedException {
    canonicalBitmap = canonicalBitmap.scale(0.1f);

    Bitmap redRect =
        createRect(
            Color.RED,
            canonicalBitmap.getWidth(),
            canonicalBitmap.getHeight(),
            Bitmap.Config.ARGB_8888);

    Glide.get(context).getBitmapPool().put(redRect);

    Bitmap roundedRect =
        bitmapRegressionTester.test(
            GlideApp.with(context)
                .asBitmap()
                .load(canonicalBitmap.getBitmap())
                .override(canonicalBitmap.getWidth(), canonicalBitmap.getHeight())
                .transform(new RoundedCorners(5)));

    assertThat(roundedRect).isEqualTo(redRect);
  }

  @Test
  public void testRoundedCorners_overRounded() throws ExecutionException, InterruptedException {
    bitmapRegressionTester.test(
        GlideApp.with(context)
            .asBitmap()
            .load(canonicalBitmap.getBitmap())
            .transform(new RoundedCorners(20)));
  }

  private Bitmap createRect(int color, int width, int height, Bitmap.Config config) {
    final Bitmap result = Bitmap.createBitmap(width, height, config);
    Canvas canvas = new Canvas(result);
    canvas.drawColor(color);
    return result;
  }
}