Skip to content

Instantly share code, notes, and snippets.

@BrantApps
Last active July 18, 2017 16:51
Show Gist options
  • Save BrantApps/0c56697ff4e7de96cefd329b99bd3fed to your computer and use it in GitHub Desktop.
Save BrantApps/0c56697ff4e7de96cefd329b99bd3fed to your computer and use it in GitHub Desktop.
A test that finds all of my app's Activitys and then ensures the tracking annotation @ScreenView exists. Friendly error message when you miss one.
package com.brantapps.oceanlife.activity;
import android.app.Activity;
import com.brantapps.oceanlife.analytics.aop.ScreenView;
import com.brantapps.oceanlife.analytics.event.Tags;
import com.brantapps.oceanlife.domain.activity.SplashActivity;
import com.brantapps.oceanlife.preference.activity.AboutActivity;
import com.brantapps.oceanlife.preference.activity.ApplicationPreferencesActivity;
import com.brantapps.oceanlife.preference.activity.DisclaimerActivity;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Sets;
import com.google.common.reflect.ClassPath;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.Set;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
/**
* Test to ensure that subclasses of {@link android.app.Activity}
* are annotated with the correct analytics tracking events & properties.
*
* Created by david.branton on 18/07/2017.
*/
public class TestActivityAnalytics {
/**
* Check that each of the sub-classes of activity override the
* {@linkplain Activity#onResume()} method and have annotated it
* with the {@link com.brantapps.oceanlife.analytics.aop.ScreenView}
* tag.
*/
@Test
public void haveScreenViewAnnotationOnResume() throws IOException {
// Given - load the classes on the classpath.
final ClassPath classPath = ClassPath.from(ClassLoader.getSystemClassLoader());
// When - a class that subclasses Activity (that isn't abstract) is found...
final Set<Class<?>> concreteActivities = Sets.newHashSet();
for (ClassPath.ClassInfo classInfo : classPath.getTopLevelClassesRecursive("com.brantapps.oceanlife")) {
final Class clazz = classInfo.load();
if (Activity.class.isAssignableFrom(clazz) && !Modifier.isAbstract(clazz.getModifiers())) {
concreteActivities.add(clazz);
}
}
// Then - find the onResume() method and check the method is annotated.
concreteActivities.stream().allMatch(input -> {
try {
final ScreenView[] screenViewAnnotations = input.getDeclaredMethod("onResume").getAnnotationsByType(ScreenView.class);
assertThat(screenViewAnnotations.length, is(equalTo(1)));
assertThat(screenViewAnnotations[0].screenName(), is(equalTo(activityToCurrentScreenParameter.get(input.getName()))));
assertThat(screenViewAnnotations[0].screenClassOverride(), is(equalTo(StringUtils.EMPTY)));
return true;
} catch (NoSuchMethodException e) {
fail(String.format("Missing onResume screen view tracking for activity [%s]", input.getSimpleName()));
return false;
}
});
}
private ImmutableMap<String, String> activityToCurrentScreenParameter = ImmutableMap.<String, String>builder()
.put(AboutActivity.class.getName(), Tags.ScreenView.ABOUT)
.put(AddSpotActivity.class.getName(), Tags.ScreenView.ADD_SPOT)
.put(DisclaimerActivity.class.getName(), Tags.ScreenView.DISCLAIMER)
.put(SplashActivity.class.getName(), Tags.ScreenView.SPLASH)
.put(SpotDetailActivity.class.getName(), Tags.ScreenView.SPOT_DETAIL)
.put(SpotListActivity.class.getName(), Tags.ScreenView.SPOT_LIST)
.put(ApplicationPreferencesActivity.class.getName(), Tags.ScreenView.PREFERENCES)
.build();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment