You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ParameterizedTB3Runner.java 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. package com.vaadin.tests.tb3;
  2. import java.lang.reflect.Method;
  3. import java.lang.reflect.Modifier;
  4. import java.util.ArrayList;
  5. import java.util.Collection;
  6. import java.util.LinkedHashMap;
  7. import java.util.List;
  8. import java.util.Map;
  9. import java.util.Objects;
  10. import org.junit.runners.Parameterized.Parameters;
  11. import org.junit.runners.model.FrameworkMethod;
  12. import org.junit.runners.model.InitializationError;
  13. /**
  14. * TestBench test runner which supports static @Parameters annotated methods
  15. * providing parameters for the corresponding setter.
  16. * <p>
  17. * {@code @Parameters public static Collection<String> getThemes() } creates one
  18. * permutation for each value returned by {@code getThemes()}. The value is
  19. * automatically assigned to the test instance using {@code setTheme(String)}
  20. * before invoking the test method
  21. *
  22. * @author Vaadin Ltd
  23. */
  24. public class ParameterizedTB3Runner extends TB3Runner {
  25. public ParameterizedTB3Runner(Class<?> klass) throws InitializationError {
  26. super(klass);
  27. }
  28. @Override
  29. protected List<FrameworkMethod> computeTestMethods() {
  30. List<FrameworkMethod> methods = super.computeTestMethods();
  31. Map<Method, Collection<String>> parameters = new LinkedHashMap<>();
  32. // Find all @Parameters methods and invoke them to find out permutations
  33. for (Method m : getTestClass().getJavaClass().getMethods()) {
  34. Parameters p = m.getAnnotation(Parameters.class);
  35. if (p == null) {
  36. continue;
  37. }
  38. if (!m.getName().startsWith("get") || !m.getName().endsWith("s")) {
  39. throw new IllegalStateException("Method " + m.getName()
  40. + " is annotated with @Parameter but is not named getSomeThings() as it should");
  41. }
  42. if (m.getParameterTypes().length != 0) {
  43. throw new IllegalStateException("Method " + m.getName()
  44. + " annotated with @Parameter should not have any arguments");
  45. }
  46. if (!Modifier.isStatic(m.getModifiers())) {
  47. throw new IllegalStateException("Method " + m.getName()
  48. + " annotated with @Parameter must be static");
  49. }
  50. // getThemes -> setTheme
  51. String setter = "set" + m.getName().substring("get".length());
  52. setter = setter.substring(0, setter.length() - 1);
  53. // property = property.substring(0, 1).toLowerCase(Locale.ROOT)
  54. // + property.substring(1);
  55. Method setterMethod;
  56. try {
  57. setterMethod = getTestClass().getJavaClass().getMethod(setter,
  58. String.class);
  59. } catch (Exception e) {
  60. throw new IllegalStateException(
  61. "No setter " + setter + " found in "
  62. + getTestClass().getJavaClass().getName(),
  63. e);
  64. }
  65. Collection<String> values;
  66. try {
  67. values = (Collection<String>) m.invoke(null);
  68. if (!values.isEmpty()) {
  69. // Ignore any empty collections to allow e.g. integration
  70. // tests to use "/demo" path by default without adding that
  71. // to the screenshot name
  72. parameters.put(setterMethod, values);
  73. }
  74. } catch (Exception e) {
  75. throw new IllegalStateException(
  76. "The setter " + m.getName() + " could not be invoked",
  77. e);
  78. }
  79. }
  80. // Add method permutations for all @Parameters
  81. for (Method setter : parameters.keySet()) {
  82. List<FrameworkMethod> newMethods = new ArrayList<>();
  83. for (FrameworkMethod m : methods) {
  84. if (!(m instanceof TBMethod)) {
  85. System.err.println(
  86. "Unknown method type: " + m.getClass().getName());
  87. newMethods.add(m);
  88. continue;
  89. }
  90. // testFoo
  91. // testBar
  92. // ->
  93. // testFoo[valo]
  94. // testFoo[runo]
  95. // testBar[valo]
  96. // testBar[runo]
  97. for (final String value : parameters.get(setter)) {
  98. newMethods.add(new TBMethodWithBefore((TBMethod) m, setter,
  99. value));
  100. }
  101. }
  102. // Update methods so next parameters will use all expanded methods
  103. methods = newMethods;
  104. }
  105. return methods;
  106. }
  107. public static class TBMethodWithBefore extends TBMethod {
  108. private Method setter;
  109. private String value;
  110. private TBMethod parent;
  111. public TBMethodWithBefore(TBMethod m, Method setter, String value) {
  112. super(m.getMethod(), m.getCapabilities());
  113. parent = m;
  114. this.setter = setter;
  115. this.value = value;
  116. }
  117. @Override
  118. public Object invokeExplosively(Object target, Object... params)
  119. throws Throwable {
  120. setter.invoke(target, value);
  121. return parent.invokeExplosively(target, params);
  122. }
  123. @Override
  124. public String getName() {
  125. return parent.getName() + "[" + value + "]";
  126. };
  127. @Override
  128. public boolean equals(Object obj) {
  129. if (!TBMethodWithBefore.class.isInstance(obj)) {
  130. return false;
  131. }
  132. TBMethodWithBefore otherTbMethod = (TBMethodWithBefore) obj;
  133. return super.equals(obj)
  134. && Objects.equals(otherTbMethod.parent, parent)
  135. && Objects.equals(otherTbMethod.setter, setter)
  136. && Objects.equals(otherTbMethod.value, value);
  137. }
  138. }
  139. }