Commit 629200a5 authored by Bernhard Bauer's avatar Bernhard Bauer Committed by Commit Bot

Add @UseMethodParamBefore and @UseMethodParamAfter annotations

The annotations can be used in conjunction with a newly added test rule
to do setup and teardown for tests that use method parameters. The
methods will be called iff a test method with the given parameter is
executed, with the corresponding parameters.

As an example, use @UseMethodParamBefore in HomeSheetUiCaptureTest to
set the state of the SigninPromo feature before the activity is started.

Also, for moar reusability, extract a MethodParamRule that can be used
to build arbitrary rules that are applied to test statements that use
method parameters and that have access to the parameter value.

Bug: 783820
Cq-Include-Trybots: master.tryserver.chromium.android:android_cronet_tester;master.tryserver.chromium.mac:ios-simulator-cronet
Change-Id: If422eef9009c1e8721039d52f4979e5efda98089
Reviewed-on: https://chromium-review.googlesource.com/757356
Commit-Queue: Bernhard Bauer <bauerb@chromium.org>
Reviewed-by: 's avataragrieve <agrieve@chromium.org>
Reviewed-by: 's avatarNicolas Dossou-Gbété <dgn@chromium.org>
Cr-Commit-Position: refs/heads/master@{#515849}
parent b5107cb6
......@@ -2743,6 +2743,8 @@ if (is_android) {
"test/android/javatests/src/org/chromium/base/test/params/ParameterizedRunner.java",
"test/android/javatests/src/org/chromium/base/test/params/BlockJUnit4RunnerDelegate.java",
"test/android/javatests/src/org/chromium/base/test/params/BaseJUnit4RunnerDelegate.java",
"test/android/javatests/src/org/chromium/base/test/params/MethodParamAnnotationRule.java",
"test/android/javatests/src/org/chromium/base/test/params/MethodParamRule.java",
"test/android/javatests/src/org/chromium/base/test/params/ParameterizedRunnerDelegateFactory.java",
"test/android/javatests/src/org/chromium/base/test/params/ParameterizedFrameworkMethod.java",
"test/android/javatests/src/org/chromium/base/test/params/ParameterSet.java",
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.base.test.params;
import org.junit.runners.model.Statement;
import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameterAfter;
import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameterBefore;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
/**
* Processes {@link UseMethodParameterBefore} and {@link UseMethodParameterAfter} annotations to run
* the corresponding methods. To use, add an instance to the test class and annotate it with
* {@code @}{@link org.junit.Rule Rule}.
*/
public class MethodParamAnnotationRule extends MethodParamRule {
@Override
protected Statement applyParameterAndValues(
final Statement base, Object target, String parameterName, List<Object> values) {
final List<Method> beforeMethods = new ArrayList<>();
final List<Method> afterMethods = new ArrayList<>();
for (Method m : target.getClass().getDeclaredMethods()) {
if (!m.getReturnType().equals(Void.TYPE)) continue;
if (!Modifier.isPublic(m.getModifiers())) continue;
UseMethodParameterBefore beforeAnnotation =
m.getAnnotation(UseMethodParameterBefore.class);
if (beforeAnnotation != null && beforeAnnotation.value().equals(parameterName)) {
beforeMethods.add(m);
}
UseMethodParameterAfter afterAnnotation =
m.getAnnotation(UseMethodParameterAfter.class);
if (afterAnnotation != null && afterAnnotation.value().equals(parameterName)) {
afterMethods.add(m);
}
}
if (beforeMethods.isEmpty() && afterMethods.isEmpty()) return base;
return new Statement() {
@Override
public void evaluate() throws Throwable {
for (Method m : beforeMethods) {
m.invoke(target, values.toArray());
}
base.evaluate();
for (Method m : afterMethods) {
m.invoke(target, values.toArray());
}
}
};
}
}
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.base.test.params;
import org.junit.rules.MethodRule;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.Statement;
import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameter;
import java.util.List;
/**
* Abstract base class for rules that are applied to test methods using
* {@link org.chromium.base.test.params.ParameterAnnotations.MethodParameter method parameters}.
*/
public abstract class MethodParamRule implements MethodRule {
@Override
public Statement apply(final Statement base, FrameworkMethod method, Object target) {
UseMethodParameter useMethodParameter = method.getAnnotation(UseMethodParameter.class);
if (useMethodParameter == null) return base;
String parameterName = useMethodParameter.value();
if (!(method instanceof ParameterizedFrameworkMethod)) return base;
ParameterSet parameters = ((ParameterizedFrameworkMethod) method).getParameterSet();
List<Object> values = parameters.getValues();
return applyParameterAndValues(base, target, parameterName, values);
}
protected abstract Statement applyParameterAndValues(
final Statement base, Object target, String parameterName, List<Object> values);
}
......@@ -22,6 +22,28 @@ public class ParameterAnnotations {
String value();
}
/**
* Annotation for methods that should be called before running a test with method parameters.
* @see MethodParameter
* @see UseMethodParameterAfter
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface UseMethodParameterBefore {
String value();
}
/**
* Annotation for methods that should be called after running a test with method parameters.
* @see MethodParameter
* @see UseMethodParameterBefore
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface UseMethodParameterAfter {
String value();
}
/**
* Annotation for static field of a `List<ParameterSet>` for entire test class
*/
......
......@@ -5,12 +5,16 @@
package org.chromium.base.test.params;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.MethodRule;
import org.junit.runner.RunWith;
import org.chromium.base.test.params.ParameterAnnotations.ClassParameter;
import org.chromium.base.test.params.ParameterAnnotations.MethodParameter;
import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameter;
import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameterAfter;
import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameterBefore;
import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate;
import java.util.ArrayList;
......@@ -64,15 +68,36 @@ public class ExampleParameterizedTest {
"A and B string length aren't equal", mStringA.length(), mStringB.length());
}
@Rule
public MethodRule mMethodParamAnnotationProcessor = new MethodParamAnnotationRule();
private Integer mSum;
@UseMethodParameterBefore("A")
public void setupWithOnlyA(int intA, int intB) {
mSum = intA + intB;
}
@Test
@UseMethodParameter("A")
public void testWithOnlyA(int intA, int intB) {
Assert.assertTrue(intA + 1 == intB);
Assert.assertEquals(intA + 1, intB);
Assert.assertEquals(mSum, Integer.valueOf(intA + intB));
mSum = null;
}
private String mConcatenation;
@Test
@UseMethodParameter("B")
public void testWithOnlyB(String a, String b) {
Assert.assertTrue(a != b);
mConcatenation = a + b;
}
@UseMethodParameterAfter("B")
public void teardownWithOnlyB(String a, String b) {
Assert.assertEquals(mConcatenation, a + b);
mConcatenation = null;
}
}
......@@ -4,7 +4,9 @@
package org.chromium.chrome.browser.suggestions;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThat;
import static org.chromium.chrome.test.BottomSheetTestRule.waitForWindowUpdates;
......@@ -15,33 +17,40 @@ import android.support.v7.widget.RecyclerView;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.MethodRule;
import org.junit.runner.RunWith;
import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.params.MethodParamAnnotationRule;
import org.chromium.base.test.params.ParameterAnnotations.MethodParameter;
import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameter;
import org.chromium.base.test.params.ParameterAnnotations.UseMethodParameterBefore;
import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate;
import org.chromium.base.test.params.ParameterSet;
import org.chromium.base.test.params.ParameterizedRunner;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.Restriction;
import org.chromium.base.test.util.parameter.CommandLineParameter;
import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.ntp.NtpUiCaptureTestData;
import org.chromium.chrome.browser.ntp.cards.ItemViewType;
import org.chromium.chrome.browser.ntp.cards.NewTabPageAdapter;
import org.chromium.chrome.browser.test.ScreenShooter;
import org.chromium.chrome.browser.widget.bottomsheet.BottomSheet;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate;
import org.chromium.chrome.test.util.MenuUtils;
import org.chromium.chrome.test.util.browser.ChromeHome;
import org.chromium.chrome.test.util.browser.Features;
import org.chromium.chrome.test.util.browser.suggestions.SuggestionsDependenciesRule;
import org.chromium.ui.test.util.UiRestriction;
import java.util.Arrays;
import java.util.List;
/**
* Tests for the appearance of the special states of the home sheet.
*/
@RunWith(ChromeJUnit4ClassRunner.class)
@RunWith(ParameterizedRunner.class)
@UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class)
@Restriction(UiRestriction.RESTRICTION_TYPE_PHONE) // ChromeHome is only enabled on phones
// TODO(https://crbug.com/754778) improve annotation processor. We need to remove the currently
// registered Feature flags to be able to change them later.
@CommandLineFlags.Remove(ChromeHome.ENABLE_FLAGS)
@ScreenShooter.Directory("HomeSheetStates")
public class HomeSheetUiCaptureTest {
@Rule
......@@ -55,6 +64,25 @@ public class HomeSheetUiCaptureTest {
@Rule
public ScreenShooter mScreenShooter = new ScreenShooter();
@Rule
public MethodRule mMethodParamAnnotationProcessor = new MethodParamAnnotationRule();
private static final String SIGNIN_PROMO = "SigninPromo";
@MethodParameter(SIGNIN_PROMO)
private static List<ParameterSet> sSigninPromoParams = Arrays.asList(
new ParameterSet().name("SigninPromoDisabled").value(false),
new ParameterSet().name("SigninPromoEnabled").value(true)
);
@UseMethodParameterBefore(SIGNIN_PROMO)
public void applyEnableSigninPromoParam(boolean enableSigninPromo) {
if (enableSigninPromo) {
Features.getInstance().enable(ChromeFeatureList.ANDROID_SIGNIN_PROMOS);
} else {
Features.getInstance().disable(ChromeFeatureList.ANDROID_SIGNIN_PROMOS);
}
}
@Before
public void setup() throws InterruptedException {
mActivityRule.startMainActivityOnBlankPage();
......@@ -63,12 +91,12 @@ public class HomeSheetUiCaptureTest {
@Test
@MediumTest
@Feature({"UiCatalogue"})
@CommandLineParameter({
ChromeHome.ENABLE_FLAGS,
"enable-features=" + ChromeHome.FEATURES + "," + ChromeFeatureList.ANDROID_SIGNIN_PROMOS
})
@ScreenShooter.Directory("SignInPromo")
public void testSignInPromo() {
@UseMethodParameter(SIGNIN_PROMO)
public void testSignInPromo(boolean signinPromoEnabled) {
assertThat(ChromeFeatureList.isEnabled(ChromeFeatureList.ANDROID_SIGNIN_PROMOS),
is(signinPromoEnabled));
// Needs to be "Full" to for this to work on small screens in landscape.
mActivityRule.setSheetState(BottomSheet.SHEET_STATE_FULL, false);
waitForWindowUpdates();
......@@ -83,7 +111,6 @@ public class HomeSheetUiCaptureTest {
@Test
@MediumTest
@Feature({"UiCatalogue"})
@CommandLineFlags.Add(ChromeHome.ENABLE_FLAGS)
@ScreenShooter.Directory("AllDismissed")
public void testAllDismissed() {
NewTabPageAdapter adapter = mActivityRule.getAdapter();
......@@ -108,7 +135,6 @@ public class HomeSheetUiCaptureTest {
@Test
@MediumTest
@Feature({"UiCatalogue"})
@CommandLineFlags.Add(ChromeHome.ENABLE_FLAGS)
@ScreenShooter.Directory("NewTab")
public void testNewTab() {
// Select "New tab" from the menu.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment