1336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustpackage org.testng.junit;
2336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
3ed0917f31f0b66158bc786cd018fd95175f76f29Cédric Beustimport org.testng.ITestMethodFinder;
4ed0917f31f0b66158bc786cd018fd95175f76f29Cédric Beustimport org.testng.ITestNGMethod;
5ed0917f31f0b66158bc786cd018fd95175f76f29Cédric Beustimport org.testng.collections.Lists;
6ed0917f31f0b66158bc786cd018fd95175f76f29Cédric Beustimport org.testng.internal.TestNGMethod;
7ed0917f31f0b66158bc786cd018fd95175f76f29Cédric Beustimport org.testng.internal.annotations.IAnnotationFinder;
8ed0917f31f0b66158bc786cd018fd95175f76f29Cédric Beustimport org.testng.xml.XmlTest;
9ed0917f31f0b66158bc786cd018fd95175f76f29Cédric Beust
10336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.lang.reflect.Constructor;
11336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.lang.reflect.InvocationTargetException;
12336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.lang.reflect.Method;
13336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.util.HashSet;
14336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.util.List;
15336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustimport java.util.Set;
16336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
17336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
18336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust/**
190f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin * This class locates all test and configuration methods according to JUnit.
20336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust * It is used to change the strategy used by TestRunner to locate its test
21336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust * methods.
22336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust *
23336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust * @author Cedric Beust, May 3, 2004
240f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin *
25336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust */
26336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustpublic class JUnitMethodFinder implements ITestMethodFinder {
27336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  private String m_testName = null;
28336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  private IAnnotationFinder m_annotationFinder = null;
290f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
30336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public JUnitMethodFinder(String testName, IAnnotationFinder finder) {
31336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    m_testName = testName;
32336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    m_annotationFinder = finder;
33336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
340f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
35336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  private Constructor findConstructor(Class cls, Class[] parameters) {
36336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    Constructor result = null;
370f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
38336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    try {
39336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      result = cls.getConstructor(parameters);
400f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin    }
41a3f78c5debcd03e7755f5ff2956a6f325e41d0b7Ryan Schmitt    catch (SecurityException | NoSuchMethodException ex) {
42336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      // ignore
43336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
440f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
45336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return result;
46336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
47336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
480f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin  @Override
496bf0a7dfff25a8fecd8b57577d5f244ae5eb8003Cédric Beust  public ITestNGMethod[] getTestMethods(Class cls, XmlTest xmlTest) {
500f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin    ITestNGMethod[] result =
51336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      privateFindTestMethods(new INameFilter() {
520f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin        @Override
53336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        public boolean accept(Method method) {
54336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust          return method.getName().startsWith("test") &&
55336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust            method.getParameterTypes().length == 0;
56336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        }
57336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }, cls);
580f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
59336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust//    ppp("=====");
60336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust//    ppp("FIND TEST METHOD RETURNING ");
61336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust//    for (ITestMethod m : result) {
62336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust//      ppp("  " + m);
63336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust//    }
64336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust//    ppp("=====");
65336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return result;
660f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin  }
670f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
68336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  private ITestNGMethod[] privateFindTestMethods(INameFilter filter, Class cls) {
69ed0917f31f0b66158bc786cd018fd95175f76f29Cédric Beust    List<ITestNGMethod> vResult = Lists.newArrayList();
700f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
71336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    // We do not want to walk up the class hierarchy and accept the
72336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    // same method twice (e.g. setUp) which would lead to double-invocation.
73336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    // All relevant JUnit methods are parameter-less so we store accepted
74336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    // method names in a Set to filter out duplicates.
7510c223b7aa6bf34778079bb5ee1a494c83cd1239Ryan Schmitt    Set<String> acceptedMethodNames = new HashSet<>();
760f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
77336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    //
78336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    // Collect all methods that start with test
79336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    //
80336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    Class current = cls;
81336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    while(!(current == Object.class)) {
82336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      Method[] allMethods = current.getDeclaredMethods();
83336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      for(Method allMethod : allMethods) {
840f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin        ITestNGMethod m = new TestNGMethod(/* allMethods[i].getDeclaringClass(), */ allMethod,
85d2cb0ebdfecac643c380d1e84f273f5ba92374a4Cédric Beust            m_annotationFinder, null,
86d2cb0ebdfecac643c380d1e84f273f5ba92374a4Cédric Beust            null); /* @@@ */
87336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        Method method = m.getMethod();
88336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        String methodName = method.getName();
89336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        if(filter.accept(method) && !acceptedMethodNames.contains(methodName)) {
90336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust          //          if (m.getName().startsWith("test")) {
91336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust          //            ppp("Found JUnit test method: " + tm);
92336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust          vResult.add(m);
93336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust          acceptedMethodNames.add(methodName);
94336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        }
95336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
96336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      current = current.getSuperclass();
97336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    }
98336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
99336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return vResult.toArray(new ITestNGMethod[vResult.size()]);
100336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
1010f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
102336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  private static void ppp(String s) {
103336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    System.out.println("[JUnitMethodFinder] " + s);
104336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
1050f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
106336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  private Object instantiate(Class cls) {
107336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    Object result = null;
1080f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
109336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    Constructor ctor = findConstructor(cls, new Class[] { String.class });
110336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    try {
111336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      if (null != ctor) {
112336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        result = ctor.newInstance(new Object[] { m_testName });
113336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
114336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      else {
115336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        ctor = cls.getConstructor(new Class[0]);
116336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        result = ctor.newInstance(new Object[0]);
117336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }
1180f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin    }
119a3f78c5debcd03e7755f5ff2956a6f325e41d0b7Ryan Schmitt    catch (IllegalArgumentException | NoSuchMethodException | InvocationTargetException | IllegalAccessException | SecurityException ex) {
120336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      ex.printStackTrace();
121a3f78c5debcd03e7755f5ff2956a6f325e41d0b7Ryan Schmitt    } catch (InstantiationException ex) {
122336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      System.err.println("Couldn't find a constructor with a String parameter on your JUnit test class.");
123336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      ex.printStackTrace();
1240f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin    }
1250f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
126336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return result;
127336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
128336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
129336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
1300f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin  @Override
131336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public ITestNGMethod[] getBeforeTestMethods(Class cls) {
132336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    ITestNGMethod[] result = privateFindTestMethods(new INameFilter() {
1330f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin        @Override
134336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        public boolean accept(Method method) {
135336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust          return "setUp".equals(method.getName());
136336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        }
137336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }, cls);
1380f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
139336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return result;
140336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
141336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
1420f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin  @Override
143336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public ITestNGMethod[] getAfterTestMethods(Class cls) {
144336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    ITestNGMethod[] result =  privateFindTestMethods(new INameFilter() {
1450f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin        @Override
146336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        public boolean accept(Method method) {
147336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust          return "tearDown".equals(method.getName());
148336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust        }
149336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust      }, cls);
1500f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
151336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return result;
152336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
1530f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
1540f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin  @Override
155336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public ITestNGMethod[] getAfterClassMethods(Class cls) {
156336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return new ITestNGMethod[0];
157336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
1580f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
1590f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin  @Override
160336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public ITestNGMethod[] getBeforeClassMethods(Class cls) {
161336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return new ITestNGMethod[0];
162336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
1630f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
1640f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin  @Override
165336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public ITestNGMethod[] getBeforeSuiteMethods(Class cls) {
166336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return new ITestNGMethod[0];
167336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
1680f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
1690f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin  @Override
170336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public ITestNGMethod[] getAfterSuiteMethods(Class cls) {
171336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return new ITestNGMethod[0];
172336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
1730f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin
1740f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin  @Override
175336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public ITestNGMethod[] getBeforeTestConfigurationMethods(Class testClass) {
176336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return new ITestNGMethod[0];
177336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
178336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
1790f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin  @Override
180336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public ITestNGMethod[] getAfterTestConfigurationMethods(Class testClass) {
181336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return new ITestNGMethod[0];
182336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
183336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
1840f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin  @Override
185336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public ITestNGMethod[] getBeforeGroupsConfigurationMethods(Class testClass) {
186336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return new ITestNGMethod[0];
187336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
188336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
1890f7e671c94aeedee2fbc796b3318d44b0297b6cdnullin  @Override
190336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public ITestNGMethod[] getAfterGroupsConfigurationMethods(Class testClass) {
191336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust    return new ITestNGMethod[0];
192336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  }
193336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust}
194336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
195336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust/////////////
196336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust
197336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beustinterface INameFilter {
198336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust  public boolean accept(Method method);
199336f0ef401e9f564b8dc99d601ac80e8891ac2c1Cédric Beust}
200