Back to Repositories

Testing Android Resource Signature Generation in Glide

This test suite evaluates the AndroidResourceSignature class in Glide, focusing on resource signature generation and validation. It verifies signature consistency, night mode handling, and package information management using Robolectric for Android environment simulation.

Test Coverage Overview

The test suite provides comprehensive coverage of AndroidResourceSignature functionality.

Key areas tested include:
  • Signature generation and validation
  • Signature consistency across multiple calls
  • Night mode differentiation in signatures
  • Error handling for missing package information

Implementation Analysis

The testing approach utilizes JUnit with Robolectric for Android environment simulation. The implementation employs the KeyTester utility for signature comparison and regression testing, with specific focus on equivalence grouping and hash verification.

Notable patterns include:
  • Setup isolation using @Before annotations
  • Runtime environment manipulation for night mode testing
  • Shadow package manager usage for error condition simulation

Technical Details

Testing infrastructure includes:
  • JUnit 4 test framework
  • Robolectric TestRunner with SDK 28 configuration
  • KeyTester utility for signature validation
  • ApplicationProvider for context management
  • Shadow classes for Android component simulation

Best Practices Demonstrated

The test suite exemplifies several testing best practices in Android development.

Notable practices include:
  • Proper test isolation and setup
  • Comprehensive edge case coverage
  • Effective use of test utilities and helpers
  • Clear test method naming and organization
  • Robust regression testing implementation

bumptech/glide

library/test/src/test/java/com/bumptech/glide/signature/AndroidResourceSignatureTest.java

            
package com.bumptech.glide.signature;

import static org.junit.Assert.assertNotNull;

import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import androidx.test.core.app.ApplicationProvider;
import com.bumptech.glide.load.Key;
import com.bumptech.glide.tests.KeyTester;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;

@RunWith(RobolectricTestRunner.class)
@Config(sdk = 28)
public class AndroidResourceSignatureTest {
  @Rule public final KeyTester keyTester = new KeyTester();
  private Context context;

  @Before
  public void setUp() {
    context = ApplicationProvider.getApplicationContext();
  }

  @Test
  public void testCanGetKeyForSignature() {
    Key key = AndroidResourceSignature.obtain(context);
    assertNotNull(key);
  }

  @Test
  public void testKeyForSignatureIsTheSameAcrossCallsInTheSamePackage() {
    keyTester
        .addEquivalenceGroup(
            AndroidResourceSignature.obtain(context), AndroidResourceSignature.obtain(context))
        .addEquivalenceGroup(new ObjectKey("test"))
        .addRegressionTest(
            ApplicationVersionSignature.obtain(context),
            "5feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9")
        .test();
  }

  @Test
  public void testKeyForSignatureDiffersByNightMode() {
    RuntimeEnvironment.setQualifiers("notnight");
    keyTester
        .addEquivalenceGroup(
            AndroidResourceSignature.obtain(context), AndroidResourceSignature.obtain(context))
        .addRegressionTest(
            AndroidResourceSignature.obtain(context),
            "265d958bdae1bea56e45cc31f4db672c22893b66fef85617bbc78742bd912207");
    RuntimeEnvironment.setQualifiers("night");
    keyTester
        .addEquivalenceGroup(
            AndroidResourceSignature.obtain(context), AndroidResourceSignature.obtain(context))
        .addRegressionTest(
            AndroidResourceSignature.obtain(context),
            "96c9b8d5bb071ccd67df50cd9a0059640ebd02db78d08f07611ec145ce44a638");

    keyTester.test();
  }

  @Test
  public void testMissingPackageInfo() throws NameNotFoundException {
    // Make getPackageInfo throw NameNotFoundException.
    Shadows.shadowOf(context.getPackageManager()).removePackage(context.getPackageName());
    Key key = AndroidResourceSignature.obtain(context);

    assertNotNull(key);
  }
}