Best Testng code snippet using org.testng.DataProviderHolder.addListener
Source:TestNG.java  
...554   *     IReporter555   */556  public void setListenerClasses(List<Class<? extends ITestNGListener>> classes) {557    for (Class<? extends ITestNGListener> cls : classes) {558      addListener(InstanceCreator.newInstance(cls));559    }560  }561  /**562   * @param listener The listener to add563   * @deprecated Use addListener(ITestNGListener) instead564   */565  // TODO remove later /!\ Caution: IntelliJ is using it. Check with @akozlova before removing it566  @Deprecated567  public void addListener(Object listener) {568    if (!(listener instanceof ITestNGListener)) {569      exitWithError(570          "Listener "571              + listener572              + " must be one of ITestListener, ISuiteListener, IReporter, "573              + " IAnnotationTransformer, IMethodInterceptor or IInvokedMethodListener");574    }575    addListener((ITestNGListener) listener);576  }577  private static <E> void maybeAddListener(Map<Class<? extends E>, E> map, E value) {578    maybeAddListener(map, (Class<? extends E>) value.getClass(), value, false);579  }580  private static <E> void maybeAddListener(581      Map<Class<? extends E>, E> map, Class<? extends E> type, E value, boolean quiet) {582    if (map.putIfAbsent(type, value) != null && !quiet) {583      LOGGER.warn("Ignoring duplicate listener : " + type.getName());584    }585  }586  public void addListener(ITestNGListener listener) {587    if (listener == null) {588      return;589    }590    if (listener instanceof IExecutionVisualiser) {591      IExecutionVisualiser visualiser = (IExecutionVisualiser) listener;592      maybeAddListener(m_executionVisualisers, visualiser);593    }594    if (listener instanceof ISuiteListener) {595      ISuiteListener suite = (ISuiteListener) listener;596      maybeAddListener(m_suiteListeners, suite);597    }598    if (listener instanceof ITestListener) {599      ITestListener test = (ITestListener) listener;600      maybeAddListener(m_testListeners, test);601    }602    if (listener instanceof IClassListener) {603      IClassListener clazz = (IClassListener) listener;604      maybeAddListener(m_classListeners, clazz);605    }606    if (listener instanceof IReporter) {607      IReporter reporter = (IReporter) listener;608      maybeAddListener(m_reporters, reporter);609    }610    if (listener instanceof IAnnotationTransformer) {611      setAnnotationTransformer((IAnnotationTransformer) listener);612    }613    if (listener instanceof IMethodInterceptor) {614      m_methodInterceptors.add((IMethodInterceptor) listener);615    }616    if (listener instanceof IInvokedMethodListener) {617      IInvokedMethodListener method = (IInvokedMethodListener) listener;618      maybeAddListener(m_invokedMethodListeners, method);619    }620    if (listener instanceof IHookable) {621      setHookable((IHookable) listener);622    }623    if (listener instanceof IConfigurable) {624      setConfigurable((IConfigurable) listener);625    }626    if (listener instanceof IExecutionListener) {627      m_configuration.addExecutionListenerIfAbsent((IExecutionListener) listener);628    }629    if (listener instanceof IConfigurationListener) {630      m_configuration.addConfigurationListener((IConfigurationListener) listener);631    }632    if (listener instanceof IAlterSuiteListener) {633      IAlterSuiteListener alter = (IAlterSuiteListener) listener;634      maybeAddListener(m_alterSuiteListeners, alter);635    }636    if (listener instanceof IDataProviderListener) {637      IDataProviderListener dataProvider = (IDataProviderListener) listener;638      maybeAddListener(m_dataProviderListeners, dataProvider);639    }640    if (listener instanceof IDataProviderInterceptor) {641      IDataProviderInterceptor interceptor = (IDataProviderInterceptor) listener;642      maybeAddListener(m_dataProviderInterceptors, interceptor);643    }644  }645  public Set<IReporter> getReporters() {646    // This will now cause a different behavior for consumers of this method because unlike before647    // they are no longer648    // going to be getting the original set but only a copy of it (since we internally moved from649    // Sets to Maps)650    return Sets.newHashSet(m_reporters.values());651  }652  public List<ITestListener> getTestListeners() {653    return Lists.newArrayList(m_testListeners.values());654  }655  public List<ISuiteListener> getSuiteListeners() {656    return Lists.newArrayList(m_suiteListeners.values());657  }658  /** If m_verbose gets set, it will override the verbose setting in testng.xml */659  private Integer m_verbose = null;660  private final IAnnotationTransformer m_defaultAnnoProcessor = new DefaultAnnotationTransformer();661  private IAnnotationTransformer m_annotationTransformer = m_defaultAnnoProcessor;662  private Boolean m_skipFailedInvocationCounts = false;663  private final List<IMethodInterceptor> m_methodInterceptors = Lists.newArrayList();664  /** The list of test names to run from the given suite */665  private List<String> m_testNames;666  private Integer m_suiteThreadPoolSize = CommandLineArgs.SUITE_THREAD_POOL_SIZE_DEFAULT;667  private boolean m_randomizeSuites = Boolean.FALSE;668  private boolean m_alwaysRun = Boolean.TRUE;669  private Boolean m_preserveOrder = XmlSuite.DEFAULT_PRESERVE_ORDER;670  private Boolean m_groupByInstances;671  private IConfiguration m_configuration;672  /**673   * Sets the level of verbosity. This value will override the value specified in the test suites.674   *675   * @param verbose the verbosity level (0 to 10 where 10 is most detailed) Actually, this is a lie:676   *     you can specify -1 and this will put TestNG in debug mode (no longer slicing off stack677   *     traces and all).678   */679  public void setVerbose(int verbose) {680    m_verbose = verbose;681  }682  public void setExecutorFactoryClass(String clazzName) {683    this.m_executorFactory = createExecutorFactoryInstanceUsing(clazzName);684  }685  private IExecutorFactory createExecutorFactoryInstanceUsing(String clazzName) {686    Class<?> cls = ClassHelper.forName(clazzName);687    Object instance = InstanceCreator.newInstance(cls);688    if (instance instanceof IExecutorFactory) {689      return (IExecutorFactory) instance;690    }691    throw new IllegalArgumentException(692        clazzName + " does not implement " + IExecutorFactory.class.getName());693  }694  public void setExecutorFactory(IExecutorFactory factory) {695    this.m_executorFactory = factory;696  }697  public IExecutorFactory getExecutorFactory() {698    if (this.m_executorFactory == null) {699      this.m_executorFactory = createExecutorFactoryInstanceUsing(DEFAULT_THREADPOOL_FACTORY);700    }701    return this.m_executorFactory;702  }703  private void initializeCommandLineSuites() {704    if (m_commandLineTestClasses != null || m_commandLineMethods != null) {705      if (null != m_commandLineMethods) {706        m_cmdlineSuites = createCommandLineSuitesForMethods(m_commandLineMethods);707      } else {708        m_cmdlineSuites = createCommandLineSuitesForClasses(m_commandLineTestClasses);709      }710      for (XmlSuite s : m_cmdlineSuites) {711        for (XmlTest t : s.getTests()) {712          t.setPreserveOrder(m_preserveOrder);713        }714        m_suites.add(s);715        if (m_groupByInstances != null) {716          s.setGroupByInstances(m_groupByInstances);717        }718      }719    }720  }721  private void initializeCommandLineSuitesParams() {722    if (null == m_cmdlineSuites) {723      return;724    }725    for (XmlSuite s : m_cmdlineSuites) {726      if (m_threadCount != -1) {727        s.setThreadCount(m_threadCount);728      }729      if (m_parallelMode != null) {730        s.setParallel(m_parallelMode);731      }732      if (m_configFailurePolicy != null) {733        s.setConfigFailurePolicy(m_configFailurePolicy);734      }735    }736  }737  private void initializeCommandLineSuitesGroups() {738    // If groups were specified on the command line, they should override groups739    // specified in the XML file740    boolean hasIncludedGroups = null != m_includedGroups && m_includedGroups.length > 0;741    boolean hasExcludedGroups = null != m_excludedGroups && m_excludedGroups.length > 0;742    List<XmlSuite> suites = m_cmdlineSuites != null ? m_cmdlineSuites : m_suites;743    if (hasIncludedGroups || hasExcludedGroups) {744      for (XmlSuite s : suites) {745        initializeCommandLineSuitesGroups(746            s, hasIncludedGroups, m_includedGroups, hasExcludedGroups, m_excludedGroups);747      }748    }749  }750  private static void initializeCommandLineSuitesGroups(751      XmlSuite s,752      boolean hasIncludedGroups,753      String[] m_includedGroups,754      boolean hasExcludedGroups,755      String[] m_excludedGroups) {756    if (hasIncludedGroups) {757      s.setIncludedGroups(Arrays.asList(m_includedGroups));758    }759    if (hasExcludedGroups) {760      s.setExcludedGroups(Arrays.asList(m_excludedGroups));761    }762    for (XmlSuite child : s.getChildSuites()) {763      initializeCommandLineSuitesGroups(764          child, hasIncludedGroups, m_includedGroups, hasExcludedGroups, m_excludedGroups);765    }766  }767  private void addReporter(Class<? extends IReporter> r) {768    if (!m_reporters.containsKey(r)) {769      m_reporters.put(r, InstanceCreator.newInstance(r));770    }771  }772  private void initializeDefaultListeners() {773    if (m_failIfAllTestsSkipped) {774      this.exitCodeListener.failIfAllTestsSkipped();775    }776    addListener(this.exitCodeListener);777    if (m_useDefaultListeners) {778      addReporter(SuiteHTMLReporter.class);779      addReporter(Main.class);780      addReporter(FailedReporter.class);781      addReporter(XMLReporter.class);782      if (RuntimeBehavior.useOldTestNGEmailableReporter()) {783        addReporter(EmailableReporter.class);784      } else if (RuntimeBehavior.useEmailableReporter()) {785        addReporter(EmailableReporter2.class);786      }787      addReporter(JUnitReportReporter.class);788      if (m_verbose != null && m_verbose > 4) {789        addListener(new VerboseReporter("[TestNG] "));790      }791    }792  }793  private void initializeConfiguration() {794    ITestObjectFactory factory = m_objectFactory;795    //796    // Install the listeners found in ServiceLoader (or use the class797    // loader for tests, if specified).798    //799    addServiceLoaderListeners();800    //801    // Install the listeners found in the suites802    //803    for (XmlSuite s : m_suites) {804      addListeners(s);805      //806      // Install the method selectors807      //808      for (XmlMethodSelector methodSelector : s.getMethodSelectors()) {809        addMethodSelector(methodSelector.getClassName(), methodSelector.getPriority());810        addMethodSelector(methodSelector);811      }812      //813      // Find if we have an object factory814      //815      if (s.getObjectFactory() != null) {816        if (factory == null) {817          factory = s.getObjectFactory();818        } else {819          throw new TestNGException("Found more than one object-factory tag in your suites");820        }821      }822    }823    m_configuration.setAnnotationFinder(new JDK15AnnotationFinder(getAnnotationTransformer()));824    m_configuration.setHookable(m_hookable);825    m_configuration.setConfigurable(m_configurable);826    m_configuration.setObjectFactory(factory);827    m_configuration.setAlwaysRunListeners(this.m_alwaysRun);828    m_configuration.setExecutorFactory(getExecutorFactory());829  }830  private void addListeners(XmlSuite s) {831    for (String listenerName : s.getListeners()) {832      Class<?> listenerClass = ClassHelper.forName(listenerName);833      // If specified listener does not exist, a TestNGException will be thrown834      if (listenerClass == null) {835        throw new TestNGException(836            "Listener " + listenerName + " was not found in project's classpath");837      }838      ITestNGListener listener = (ITestNGListener) InstanceCreator.newInstance(listenerClass);839      addListener(listener);840    }841    // Add the child suite listeners842    List<XmlSuite> childSuites = s.getChildSuites();843    for (XmlSuite c : childSuites) {844      addListeners(c);845    }846  }847  /** Using reflection to remain Java 5 compliant. */848  private void addServiceLoaderListeners() {849    Iterable<ITestNGListener> loader =850        m_serviceLoaderClassLoader != null851            ? ServiceLoader.load(ITestNGListener.class, m_serviceLoaderClassLoader)852            : ServiceLoader.load(ITestNGListener.class);853    for (ITestNGListener l : loader) {854      Utils.log("[TestNG]", 2, "Adding ServiceLoader listener:" + l);855      if (m_listenersToSkipFromBeingWiredIn.contains(l.getClass().getName())) {856        Utils.log("[TestNG]", 2, "Skipping adding the listener :" + l);857        continue;858      }859      addListener(l);860      addServiceLoaderListener(l);861    }862  }863  /**864   * Before suites are executed, do a sanity check to ensure all required conditions are met. If865   * not, throw an exception to stop test execution866   *867   * @throws TestNGException if the sanity check fails868   */869  private void sanityCheck() {870    XmlSuiteUtils.validateIfSuitesContainDuplicateTests(m_suites);871    XmlSuiteUtils.adjustSuiteNamesToEnsureUniqueness(m_suites);872  }873  /** Invoked by the remote runner. */874  public void initializeEverything() {875    // The Eclipse plug-in (RemoteTestNG) might have invoked this method already876    // so don't initialize suites twice.877    if (m_isInitialized) {878      return;879    }880    initializeSuitesAndJarFile();881    initializeConfiguration();882    initializeDefaultListeners();883    initializeCommandLineSuites();884    initializeCommandLineSuitesParams();885    initializeCommandLineSuitesGroups();886    m_isInitialized = true;887  }888  /** Run TestNG. */889  public void run() {890    initializeEverything();891    sanityCheck();892    runExecutionListeners(true /* start */);893    runSuiteAlterationListeners();894    m_start = System.currentTimeMillis();895    List<ISuite> suiteRunners = runSuites();896    m_end = System.currentTimeMillis();897    if (null != suiteRunners) {898      generateReports(suiteRunners);899    }900    runExecutionListeners(false /* finish */);901    exitCode = this.exitCodeListener.getStatus();902    if (exitCodeListener.noTestsFound()) {903      if (TestRunner.getVerbose() > 1) {904        System.err.println("[TestNG] No tests found. Nothing was run");905        usage();906      }907    }908    m_instance = null;909    m_jCommander = null;910  }911  /**912   * Run the test suites.913   *914   * <p>This method can be overridden by subclass. <br>915   * For example, DistributedTestNG to run in master/slave mode according to commandline args.916   *917   * @return - List of suites that were run as {@link ISuite} objects.918   * @since 6.9.11 when moving distributed/remote classes out into separate project919   */920  protected List<ISuite> runSuites() {921    return runSuitesLocally();922  }923  private void runSuiteAlterationListeners() {924    for (IAlterSuiteListener l : m_alterSuiteListeners.values()) {925      l.alter(m_suites);926    }927  }928  private void runExecutionListeners(boolean start) {929    for (IExecutionListener l : m_configuration.getExecutionListeners()) {930      if (start) {931        l.onExecutionStart();932      } else {933        l.onExecutionFinish();934      }935    }936  }937  private static void usage() {938    if (m_jCommander == null) {939      m_jCommander = new JCommander(new CommandLineArgs());940    }941    m_jCommander.usage();942  }943  private void generateReports(List<ISuite> suiteRunners) {944    for (IReporter reporter : m_reporters.values()) {945      try {946        long start = System.currentTimeMillis();947        reporter.generateReport(m_suites, suiteRunners, m_outputDir);948        Utils.log(949            "TestNG",950            2,951            "Time taken by " + reporter + ": " + (System.currentTimeMillis() - start) + " ms");952      } catch (Exception ex) {953        System.err.println("[TestNG] Reporter " + reporter + " failed");954        ex.printStackTrace(System.err);955      }956    }957  }958  /**959   * This needs to be public for maven2, for now..At least until an alternative mechanism is found.960   * @return The locally run suites961   */962  public List<ISuite> runSuitesLocally() {963    if (m_suites.isEmpty()) {964      error("No test suite found. Nothing to run");965      usage();966      return Collections.emptyList();967    }968    SuiteRunnerMap suiteRunnerMap = new SuiteRunnerMap();969    // First initialize the suite runners to ensure there are no configuration issues.970    // Create a map with XmlSuite as key and corresponding SuiteRunner as value971    for (XmlSuite xmlSuite : m_suites) {972      createSuiteRunners(suiteRunnerMap, xmlSuite);973    }974    //975    // Run suites976    //977    if (m_suiteThreadPoolSize == 1 && !m_randomizeSuites) {978      // Single threaded and not randomized: run the suites in order979      for (XmlSuite xmlSuite : m_suites) {980        runSuitesSequentially(981            xmlSuite, suiteRunnerMap, getVerbose(xmlSuite), getDefaultSuiteName());982      }983      //984      // Generate the suites report985      //986      return Lists.newArrayList(suiteRunnerMap.values());987    }988    // Multithreaded: generate a dynamic graph that stores the suite hierarchy. This is then989    // used to run related suites in specific order. Parent suites are run only990    // once all the child suites have completed execution991    IDynamicGraph<ISuite> suiteGraph = new DynamicGraph<>();992    for (XmlSuite xmlSuite : m_suites) {993      populateSuiteGraph(suiteGraph, suiteRunnerMap, xmlSuite);994    }995    IThreadWorkerFactory<ISuite> factory =996        new SuiteWorkerFactory(997            suiteRunnerMap, 0 /* verbose hasn't been set yet */, getDefaultSuiteName());998    ITestNGThreadPoolExecutor pooledExecutor = this.getExecutorFactory().newSuiteExecutor(999            "suites",1000            suiteGraph,1001            factory,1002            m_suiteThreadPoolSize,1003            m_suiteThreadPoolSize,1004            Integer.MAX_VALUE,1005            TimeUnit.MILLISECONDS,1006            new LinkedBlockingQueue<>(),1007            null);1008    Utils.log("TestNG", 2, "Starting executor for all suites");1009    // Run all suites in parallel1010    pooledExecutor.run();1011    try {1012      pooledExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);1013      pooledExecutor.shutdownNow();1014    } catch (InterruptedException handled) {1015      Thread.currentThread().interrupt();1016      error("Error waiting for concurrent executors to finish " + handled.getMessage());1017    }1018    //1019    // Generate the suites report1020    //1021    return Lists.newArrayList(suiteRunnerMap.values());1022  }1023  private static void error(String s) {1024    LOGGER.error(s);1025  }1026  /**1027   * @return the verbose level, checking in order: the verbose level on the suite, the verbose level1028   *     on the TestNG object, or 1.1029   */1030  private int getVerbose(XmlSuite xmlSuite) {1031    return xmlSuite.getVerbose() != null1032        ? xmlSuite.getVerbose()1033        : (m_verbose != null ? m_verbose : DEFAULT_VERBOSE);1034  }1035  /**1036   * Recursively runs suites. Runs the children suites before running the parent suite. This is done1037   * so that the results for parent suite can reflect the combined results of the children suites.1038   *1039   * @param xmlSuite XML Suite to be executed1040   * @param suiteRunnerMap Maps {@code XmlSuite}s to respective {@code ISuite}1041   * @param verbose verbose level1042   * @param defaultSuiteName default suite name1043   */1044  private void runSuitesSequentially(1045      XmlSuite xmlSuite, SuiteRunnerMap suiteRunnerMap, int verbose, String defaultSuiteName) {1046    for (XmlSuite childSuite : xmlSuite.getChildSuites()) {1047      runSuitesSequentially(childSuite, suiteRunnerMap, verbose, defaultSuiteName);1048    }1049    SuiteRunnerWorker srw =1050        new SuiteRunnerWorker(1051            suiteRunnerMap.get(xmlSuite), suiteRunnerMap, verbose, defaultSuiteName);1052    srw.run();1053  }1054  /**1055   * Populates the dynamic graph with the reverse hierarchy of suites. Edges are added pointing from1056   * child suite runners to parent suite runners, hence making parent suite runners dependent on all1057   * the child suite runners1058   *1059   * @param suiteGraph dynamic graph representing the reverse hierarchy of SuiteRunners1060   * @param suiteRunnerMap Map with XMLSuite as key and its respective SuiteRunner as value1061   * @param xmlSuite XML Suite1062   */1063  private void populateSuiteGraph(1064      IDynamicGraph<ISuite> suiteGraph /* OUT */, SuiteRunnerMap suiteRunnerMap, XmlSuite xmlSuite) {1065    ISuite parentSuiteRunner = suiteRunnerMap.get(xmlSuite);1066    if (xmlSuite.getChildSuites().isEmpty()) {1067      suiteGraph.addNode(parentSuiteRunner);1068    } else {1069      for (XmlSuite childSuite : xmlSuite.getChildSuites()) {1070        suiteGraph.addEdge(0, parentSuiteRunner, suiteRunnerMap.get(childSuite));1071        populateSuiteGraph(suiteGraph, suiteRunnerMap, childSuite);1072      }1073    }1074  }1075  /**1076   * Creates the {@code SuiteRunner}s and populates the suite runner map with this information1077   *1078   * @param suiteRunnerMap Map with XMLSuite as key and it's respective SuiteRunner as value. This1079   *     is updated as part of this method call1080   * @param xmlSuite Xml Suite (and its children) for which {@code SuiteRunner}s are created1081   */1082  private void createSuiteRunners(SuiteRunnerMap suiteRunnerMap /* OUT */, XmlSuite xmlSuite) {1083    if (null != m_isJUnit && !m_isJUnit.equals(XmlSuite.DEFAULT_JUNIT)) {1084      xmlSuite.setJUnit(m_isJUnit);1085    }1086    // If the skip flag was invoked on the command line, it1087    // takes precedence1088    if (null != m_skipFailedInvocationCounts) {1089      xmlSuite.setSkipFailedInvocationCounts(m_skipFailedInvocationCounts);1090    }1091    // Override the XmlSuite verbose value with the one from TestNG1092    if (m_verbose != null) {1093      xmlSuite.setVerbose(m_verbose);1094    }1095    if (null != m_configFailurePolicy) {1096      xmlSuite.setConfigFailurePolicy(m_configFailurePolicy);1097    }1098    Set<XmlMethodSelector> selectors = Sets.newHashSet();1099    for (XmlTest t : xmlSuite.getTests()) {1100      for (Map.Entry<String, Integer> ms : m_methodDescriptors.entrySet()) {1101        XmlMethodSelector xms = new XmlMethodSelector();1102        xms.setName(ms.getKey());1103        xms.setPriority(ms.getValue());1104        selectors.add(xms);1105      }1106      selectors.addAll(m_selectors);1107      t.getMethodSelectors().addAll(Lists.newArrayList(selectors));1108    }1109    suiteRunnerMap.put(xmlSuite, createSuiteRunner(xmlSuite));1110    for (XmlSuite childSuite : xmlSuite.getChildSuites()) {1111      createSuiteRunners(suiteRunnerMap, childSuite);1112    }1113  }1114  /** Creates a suite runner and configures its initial state */1115  private SuiteRunner createSuiteRunner(XmlSuite xmlSuite) {1116    DataProviderHolder holder = new DataProviderHolder();1117    holder.addListeners(m_dataProviderListeners.values());1118    holder.addInterceptors(m_dataProviderInterceptors.values());1119    SuiteRunner result =1120        new SuiteRunner(1121            getConfiguration(),1122            xmlSuite,1123            m_outputDir,1124            m_testRunnerFactory,1125            m_useDefaultListeners,1126            m_methodInterceptors,1127            m_invokedMethodListeners.values(),1128            m_testListeners.values(),1129            m_classListeners.values(),1130            holder,1131            Systematiser.getComparator());1132    for (ISuiteListener isl : m_suiteListeners.values()) {1133      result.addListener(isl);1134    }1135    for (IReporter r : result.getReporters()) {1136      maybeAddListener(m_reporters, r.getClass(), r, true);1137    }1138    for (IConfigurationListener cl : m_configuration.getConfigurationListeners()) {1139      result.addConfigurationListener(cl);1140    }1141    m_executionVisualisers.values().forEach(result::addListener);1142    return result;1143  }1144  protected IConfiguration getConfiguration() {1145    return m_configuration;1146  }1147  /**1148   * The TestNG entry point for command line execution.1149   *1150   * @param argv the TestNG command line parameters.1151   */1152  public static void main(String[] argv) {1153    TestNG testng = privateMain(argv, null);1154    System.exit(testng.getStatus());1155  }1156  /**1157   * <B>Note</B>: this method is not part of the public API and is meant for internal usage only.1158   *1159   * @param argv The param arguments1160   * @param listener The listener1161   * @return The TestNG instance1162   */1163  public static TestNG privateMain(String[] argv, ITestListener listener) {1164    TestNG result = new TestNG();1165    if (null != listener) {1166      result.addListener(listener);1167    }1168    //1169    // Parse the arguments1170    //1171    try {1172      CommandLineArgs cla = new CommandLineArgs();1173      m_jCommander = new JCommander(cla);1174      m_jCommander.parse(argv);1175      validateCommandLineParameters(cla);1176      result.configure(cla);1177    } catch (ParameterException ex) {1178      exitWithError(ex.getMessage());1179    }1180    //1181    // Run1182    //1183    try {1184      result.run();1185    } catch (TestNGException ex) {1186      if (TestRunner.getVerbose() > 1) {1187        ex.printStackTrace(System.out);1188      } else {1189        error(ex.getMessage());1190      }1191      result.exitCode = ExitCode.newExitCodeRepresentingFailure();1192    }1193    return result;1194  }1195  /**1196   * Configure the TestNG instance based on the command line parameters.1197   *1198   * @param cla The command line parameters1199   */1200  protected void configure(CommandLineArgs cla) {1201    if (cla.verbose != null) {1202      setVerbose(cla.verbose);1203    }1204    if (cla.dependencyInjectorFactoryClass != null) {1205      Class<?> clazz = ClassHelper.forName(cla.dependencyInjectorFactoryClass);1206      if (clazz != null && IInjectorFactory.class.isAssignableFrom(clazz)) {1207        m_configuration.setInjectorFactory(InstanceCreator.newInstance((Class<IInjectorFactory>) clazz));1208      }1209    }1210    if (cla.threadPoolFactoryClass != null) {1211      setExecutorFactoryClass(cla.threadPoolFactoryClass);1212    }1213    setOutputDirectory(cla.outputDirectory);1214    String testClasses = cla.testClass;1215    if (null != testClasses) {1216      String[] strClasses = testClasses.split(",");1217      List<Class<?>> classes = Lists.newArrayList();1218      for (String c : strClasses) {1219        classes.add(ClassHelper.fileToClass(c));1220      }1221      setTestClasses(classes.toArray(new Class[0]));1222    }1223    setOutputDirectory(cla.outputDirectory);1224    if (cla.testNames != null) {1225      setTestNames(Arrays.asList(cla.testNames.split(",")));1226    }1227    // Note: can't use a Boolean field here because we are allowing a boolean1228    // parameter with an arity of 1 ("-usedefaultlisteners false")1229    if (cla.useDefaultListeners != null) {1230      setUseDefaultListeners("true".equalsIgnoreCase(cla.useDefaultListeners));1231    }1232    setGroups(cla.groups);1233    setExcludedGroups(cla.excludedGroups);1234    setTestJar(cla.testJar);1235    setXmlPathInJar(cla.xmlPathInJar);1236    setJUnit(cla.junit);1237    setMixed(cla.mixed);1238    setSkipFailedInvocationCounts(cla.skipFailedInvocationCounts);1239    toggleFailureIfAllTestsWereSkipped(cla.failIfAllTestsSkipped);1240    setListenersToSkipFromBeingWiredInViaServiceLoaders(cla.spiListenersToSkip.split(","));1241    m_configuration.setOverrideIncludedMethods(cla.overrideIncludedMethods);1242    if (cla.parallelMode != null) {1243      setParallel(cla.parallelMode);1244    }1245    if (cla.configFailurePolicy != null) {1246      setConfigFailurePolicy(XmlSuite.FailurePolicy.getValidPolicy(cla.configFailurePolicy));1247    }1248    if (cla.threadCount != null) {1249      setThreadCount(cla.threadCount);1250    }1251    if (cla.dataProviderThreadCount != null) {1252      setDataProviderThreadCount(cla.dataProviderThreadCount);1253    }1254    if (cla.suiteName != null) {1255      setDefaultSuiteName(cla.suiteName);1256    }1257    if (cla.testName != null) {1258      setDefaultTestName(cla.testName);1259    }1260    if (cla.listener != null) {1261      String sep = ";";1262      if (cla.listener.contains(",")) {1263        sep = ",";1264      }1265      String[] strs = Utils.split(cla.listener, sep);1266      List<Class<? extends ITestNGListener>> classes = Lists.newArrayList();1267      for (String cls : strs) {1268        Class<?> clazz = ClassHelper.fileToClass(cls);1269        if (ITestNGListener.class.isAssignableFrom(clazz)) {1270          classes.add((Class<? extends ITestNGListener>) clazz);1271        }1272      }1273      setListenerClasses(classes);1274    }1275    if (null != cla.methodSelectors) {1276      String[] strs = Utils.split(cla.methodSelectors, ",");1277      for (String cls : strs) {1278        String[] sel = Utils.split(cls, ":");1279        try {1280          if (sel.length == 2) {1281            addMethodSelector(sel[0], Integer.parseInt(sel[1]));1282          } else {1283            error("Method selector value was not in the format org.example.Selector:4");1284          }1285        } catch (NumberFormatException nfe) {1286          error("Method selector value was not in the format org.example.Selector:4");1287        }1288      }1289    }1290    if (cla.objectFactory != null) {1291      setObjectFactory(ClassHelper.fileToClass(cla.objectFactory));1292    }1293    if (cla.testRunnerFactory != null) {1294      setTestRunnerFactoryClass(ClassHelper.fileToClass(cla.testRunnerFactory));1295    }1296    ReporterConfig reporterConfig = ReporterConfig.deserialize(cla.reporter);1297    if (reporterConfig != null) {1298      addReporter(reporterConfig);1299    }1300    if (cla.commandLineMethods.size() > 0) {1301      m_commandLineMethods = cla.commandLineMethods;1302    }1303    if (cla.suiteFiles != null) {1304      setTestSuites(cla.suiteFiles);1305    }1306    setSuiteThreadPoolSize(cla.suiteThreadPoolSize);1307    setRandomizeSuites(cla.randomizeSuites);1308    alwaysRunListeners(cla.alwaysRunListeners);1309  }1310  public void setSuiteThreadPoolSize(Integer suiteThreadPoolSize) {1311    m_suiteThreadPoolSize = suiteThreadPoolSize;1312  }1313  public Integer getSuiteThreadPoolSize() {1314    return m_suiteThreadPoolSize;1315  }1316  public void setRandomizeSuites(boolean randomizeSuites) {1317    m_randomizeSuites = randomizeSuites;1318  }1319  public void alwaysRunListeners(boolean alwaysRun) {1320    m_alwaysRun = alwaysRun;1321  }1322  /**1323   * This method is invoked by Maven's Surefire, only remove it once Surefire has been modified to1324   * no longer call it.1325   * @param path The path1326   * @deprecated1327   */1328  @Deprecated1329  public void setSourcePath(String path) {1330    // nop1331  }1332  private static int parseInt(Object value) {1333    if (value == null) {1334      return -1;1335    }1336    if (value instanceof String) {1337      return Integer.parseInt(String.valueOf(value));1338    }1339    if (value instanceof Integer) {1340      return (Integer) value;1341    }1342    throw new IllegalArgumentException("Unable to parse " + value + " as an Integer.");1343  }1344  /**1345   * This method is invoked by Maven's Surefire to configure the runner, do not remove unless you1346   * know for sure that Surefire has been updated to use the new configure(CommandLineArgs) method.1347   *1348   * @param cmdLineArgs The command line1349   * @deprecated use new configure(CommandLineArgs) method1350   */1351  @SuppressWarnings({"unchecked"})1352  @Deprecated1353  public void configure(Map cmdLineArgs) {1354    CommandLineArgs result = new CommandLineArgs();1355    int value = parseInt(cmdLineArgs.get(CommandLineArgs.LOG));1356    if (value != -1) {1357      result.verbose = value;1358    }1359    result.outputDirectory = (String) cmdLineArgs.get(CommandLineArgs.OUTPUT_DIRECTORY);1360    String testClasses = (String) cmdLineArgs.get(CommandLineArgs.TEST_CLASS);1361    if (null != testClasses) {1362      result.testClass = testClasses;1363    }1364    String testNames = (String) cmdLineArgs.get(CommandLineArgs.TEST_NAMES);1365    if (testNames != null) {1366      result.testNames = testNames;1367    }1368    String useDefaultListeners = (String) cmdLineArgs.get(CommandLineArgs.USE_DEFAULT_LISTENERS);1369    if (null != useDefaultListeners) {1370      result.useDefaultListeners = useDefaultListeners;1371    }1372    result.groups = (String) cmdLineArgs.get(CommandLineArgs.GROUPS);1373    result.excludedGroups = (String) cmdLineArgs.get(CommandLineArgs.EXCLUDED_GROUPS);1374    result.testJar = (String) cmdLineArgs.get(CommandLineArgs.TEST_JAR);1375    result.xmlPathInJar = (String) cmdLineArgs.get(CommandLineArgs.XML_PATH_IN_JAR);1376    result.junit = (Boolean) cmdLineArgs.get(CommandLineArgs.JUNIT);1377    result.mixed = (Boolean) cmdLineArgs.get(CommandLineArgs.MIXED);1378    result.skipFailedInvocationCounts =1379        (Boolean) cmdLineArgs.get(CommandLineArgs.SKIP_FAILED_INVOCATION_COUNTS);1380    result.failIfAllTestsSkipped = Boolean.parseBoolean(1381        cmdLineArgs.getOrDefault(CommandLineArgs.FAIL_IF_ALL_TESTS_SKIPPED, Boolean.FALSE).toString());1382    result.spiListenersToSkip = (String) cmdLineArgs.getOrDefault(CommandLineArgs.LISTENERS_TO_SKIP_VIA_SPI, "");1383    String parallelMode = (String) cmdLineArgs.get(CommandLineArgs.PARALLEL);1384    if (parallelMode != null) {1385      result.parallelMode = XmlSuite.ParallelMode.getValidParallel(parallelMode);1386    }1387    value = parseInt(cmdLineArgs.get(CommandLineArgs.THREAD_COUNT));1388    if (value != -1) {1389      result.threadCount = value;1390    }1391    // Not supported by Surefire yet1392    value = parseInt(cmdLineArgs.get(CommandLineArgs.DATA_PROVIDER_THREAD_COUNT));1393    if (value != -1) {1394      result.dataProviderThreadCount = value;1395    }1396    String defaultSuiteName = (String) cmdLineArgs.get(CommandLineArgs.SUITE_NAME);1397    if (defaultSuiteName != null) {1398      result.suiteName = defaultSuiteName;1399    }1400    String defaultTestName = (String) cmdLineArgs.get(CommandLineArgs.TEST_NAME);1401    if (defaultTestName != null) {1402      result.testName = defaultTestName;1403    }1404    Object listeners = cmdLineArgs.get(CommandLineArgs.LISTENER);1405    if (listeners instanceof List) {1406      result.listener = Utils.join((List<?>) listeners, ",");1407    } else {1408      result.listener = (String) listeners;1409    }1410    String ms = (String) cmdLineArgs.get(CommandLineArgs.METHOD_SELECTORS);1411    if (null != ms) {1412      result.methodSelectors = ms;1413    }1414    String objectFactory = (String) cmdLineArgs.get(CommandLineArgs.OBJECT_FACTORY);1415    if (null != objectFactory) {1416      result.objectFactory = objectFactory;1417    }1418    String runnerFactory = (String) cmdLineArgs.get(CommandLineArgs.TEST_RUNNER_FACTORY);1419    if (null != runnerFactory) {1420      result.testRunnerFactory = runnerFactory;1421    }1422    String reporterConfigs = (String) cmdLineArgs.get(CommandLineArgs.REPORTER);1423    if (reporterConfigs != null) {1424      result.reporter = reporterConfigs;1425    }1426    String failurePolicy = (String) cmdLineArgs.get(CommandLineArgs.CONFIG_FAILURE_POLICY);1427    if (failurePolicy != null) {1428      result.configFailurePolicy = failurePolicy;1429    }1430    value = parseInt(cmdLineArgs.get(CommandLineArgs.SUITE_THREAD_POOL_SIZE));1431    if (value != -1) {1432      result.suiteThreadPoolSize = value;1433    }1434    String dependencyInjectorFactoryClass = (String) cmdLineArgs.get(CommandLineArgs.DEPENDENCY_INJECTOR_FACTORY);1435    if (dependencyInjectorFactoryClass != null) {1436      result.dependencyInjectorFactoryClass = dependencyInjectorFactoryClass;1437    }1438    configure(result);1439  }1440  /** @param testNames Only run the specified tests from the suite. */1441  public void setTestNames(List<String> testNames) {1442    m_testNames = testNames;1443  }1444  public void setSkipFailedInvocationCounts(Boolean skip) {1445    m_skipFailedInvocationCounts = skip;1446  }1447  private void addReporter(ReporterConfig reporterConfig) {1448    IReporter instance = reporterConfig.newReporterInstance();1449    if (instance != null) {1450      addListener(instance);1451    } else {1452      LOGGER.warn("Could not find reporter class : " + reporterConfig.getClassName());1453    }1454  }1455  /**1456   * Specify if this run should be made in JUnit mode1457   *1458   * @param isJUnit - Specify if this run should be made in JUnit mode1459   */1460  public void setJUnit(Boolean isJUnit) {1461    m_isJUnit = isJUnit;1462  }1463  /** @param isMixed Specify if this run should be made in mixed mode */1464  public void setMixed(Boolean isMixed) {...Source:TestRunner.java  
...328      if (IClassListener.class.isAssignableFrom(c) && m_classListeners.containsKey(c)) {329        continue;330      }331      ITestNGListener listener = factory.createListener(c);332      addListener(listener);333    }334  }335  /** Initialize meta groups */336  private void initMetaGroups(XmlTest xmlTest) {337    Map<String, List<String>> metaGroups = xmlTest.getMetaGroups();338    for (Map.Entry<String, List<String>> entry : metaGroups.entrySet()) {339      addMetaGroup(entry.getKey(), entry.getValue());340    }341  }342  private void initRunInfo(final XmlTest xmlTest) {343    // Groups344    m_xmlMethodSelector.setIncludedGroups(createGroups(m_xmlTest.getIncludedGroups()));345    m_xmlMethodSelector.setExcludedGroups(createGroups(m_xmlTest.getExcludedGroups()));346    m_xmlMethodSelector.setScript(m_xmlTest.getScript());347    // Groups override348    m_xmlMethodSelector.setOverrideIncludedMethods(m_configuration.getOverrideIncludedMethods());349    // Methods350    m_xmlMethodSelector.setXmlClasses(m_xmlTest.getXmlClasses());351    m_runInfo.addMethodSelector(m_xmlMethodSelector, 10);352    // Add user-specified method selectors (only class selectors, we can ignore353    // script selectors here)354    if (null != xmlTest.getMethodSelectors()) {355      for (org.testng.xml.XmlMethodSelector selector : xmlTest.getMethodSelectors()) {356        if (selector.getClassName() != null) {357          IMethodSelector s = InstanceCreator.createSelector(selector);358          m_runInfo.addMethodSelector(s, selector.getPriority());359        }360      }361    }362  }363  private void initMethods() {364    //365    // Calculate all the methods we need to invoke366    //367    List<ITestNGMethod> beforeClassMethods = Lists.newArrayList();368    List<ITestNGMethod> testMethods = Lists.newArrayList();369    List<ITestNGMethod> afterClassMethods = Lists.newArrayList();370    List<ITestNGMethod> beforeSuiteMethods = Lists.newArrayList();371    List<ITestNGMethod> afterSuiteMethods = Lists.newArrayList();372    List<ITestNGMethod> beforeXmlTestMethods = Lists.newArrayList();373    List<ITestNGMethod> afterXmlTestMethods = Lists.newArrayList();374    ClassInfoMap classMap = new ClassInfoMap(m_testClassesFromXml);375    m_testClassFinder =376        new TestNGClassFinder(377            classMap, Maps.newHashMap(), m_configuration, this, holder);378    ITestMethodFinder testMethodFinder =379        new TestNGMethodFinder(m_runInfo, m_annotationFinder, comparator);380    m_runInfo.setTestMethods(testMethods);381    //382    // Initialize TestClasses383    //384    IClass[] classes = m_testClassFinder.findTestClasses();385    for (IClass ic : classes) {386      // Create TestClass387      ITestClass tc =388          new TestClass(389              ic,390              testMethodFinder,391              m_annotationFinder,392              m_xmlTest,393              classMap.getXmlClass(ic.getRealClass()), m_testClassFinder.getFactoryCreationFailedMessage());394      m_classMap.put(ic.getRealClass(), tc);395    }396    //397    // Calculate groups methods398    //399    Map<String, List<ITestNGMethod>> beforeGroupMethods =400        MethodGroupsHelper.findGroupsMethods(m_classMap.values(), true);401    Map<String, List<ITestNGMethod>> afterGroupMethods =402        MethodGroupsHelper.findGroupsMethods(m_classMap.values(), false);403    //404    // Walk through all the TestClasses, store their method405    // and initialize them with the correct ITestClass406    //407    for (ITestClass tc : m_classMap.values()) {408      fixMethodsWithClass(tc.getTestMethods(), tc, testMethods);409      fixMethodsWithClass(((ITestClassConfigInfo) tc).getAllBeforeClassMethods().toArray(new ITestNGMethod[0]), tc, beforeClassMethods);410      fixMethodsWithClass(tc.getBeforeTestMethods(), tc, null);411      fixMethodsWithClass(tc.getAfterTestMethods(), tc, null);412      fixMethodsWithClass(tc.getAfterClassMethods(), tc, afterClassMethods);413      fixMethodsWithClass(tc.getBeforeSuiteMethods(), tc, beforeSuiteMethods);414      fixMethodsWithClass(tc.getAfterSuiteMethods(), tc, afterSuiteMethods);415      fixMethodsWithClass(tc.getBeforeTestConfigurationMethods(), tc, beforeXmlTestMethods);416      fixMethodsWithClass(tc.getAfterTestConfigurationMethods(), tc, afterXmlTestMethods);417      fixMethodsWithClass(418          tc.getBeforeGroupsMethods(),419          tc,420          MethodHelper.uniqueMethodList(beforeGroupMethods.values()));421      fixMethodsWithClass(422          tc.getAfterGroupsMethods(),423          tc,424          MethodHelper.uniqueMethodList(afterGroupMethods.values()));425    }426    //427    // Sort the methods428    //429    m_beforeSuiteMethods =430        MethodHelper.collectAndOrderMethods(431            beforeSuiteMethods,432            false /* forTests */,433            m_runInfo,434            m_annotationFinder,435            true /* unique */,436            m_excludedMethods,437            comparator);438    m_beforeXmlTestMethods =439        MethodHelper.collectAndOrderMethods(440            beforeXmlTestMethods,441            false /* forTests */,442            m_runInfo,443            m_annotationFinder,444            true /* unique (CQ added by me)*/,445            m_excludedMethods,446            comparator);447    m_classMethodMap = new ClassMethodMap(Arrays.asList(testMethodsContainer.getItems()), m_xmlMethodSelector);448    m_groupMethods = new ConfigurationGroupMethods(testMethodsContainer, beforeGroupMethods, afterGroupMethods);449    m_afterXmlTestMethods =450        MethodHelper.collectAndOrderMethods(451            afterXmlTestMethods,452            false /* forTests */,453            m_runInfo,454            m_annotationFinder,455            true /* unique (CQ added by me)*/,456            m_excludedMethods,457            comparator);458    m_afterSuiteMethods =459        MethodHelper.collectAndOrderMethods(460            afterSuiteMethods,461            false /* forTests */,462            m_runInfo,463            m_annotationFinder,464            true /* unique */,465            m_excludedMethods,466            comparator);467  }468  private ITestNGMethod[] computeAndGetAllTestMethods() {469    List<ITestNGMethod> testMethods = Lists.newArrayList();470    for (ITestClass tc : m_classMap.values()) {471      fixMethodsWithClass(tc.getTestMethods(), tc, testMethods);472    }473    return MethodHelper.collectAndOrderMethods(474        testMethods,475        true /* forTest? */,476        m_runInfo,477        m_annotationFinder,478        false /* unique */,479        m_excludedMethods,480        comparator);481  }482  public Collection<ITestClass> getTestClasses() {483    return m_classMap.values();484  }485  public void setTestName(String name) {486    m_testName = name;487  }488  public void setOutputDirectory(String od) {489    m_outputDirectory = od;490  }491  private void addMetaGroup(String name, List<String> groupNames) {492    m_metaGroups.put(name, groupNames);493  }494  private Map<String, String> createGroups(List<String> groups) {495    return GroupsHelper.createGroups(m_metaGroups, groups);496  }497  /**498   * The main entry method for TestRunner.499   *500   * <p>This is where all the hard work is done: - Invoke configuration methods - Invoke test501   * methods - Catch exceptions - Collect results - Invoke listeners - etc...502   */503  public void run() {504    beforeRun();505    try {506      XmlTest test = getTest();507      if (test.isJUnit()) {508        privateRunJUnit();509      } else {510        privateRun(test);511      }512    } finally {513      afterRun();514      forgetHeavyReferencesIfNeeded();515    }516  }517  private void forgetHeavyReferencesIfNeeded() {518    if (RuntimeBehavior.isMemoryFriendlyMode()) {519      testMethodsContainer.clearItems();520      m_groupMethods = null;521      m_classMethodMap = null;522    }523  }524  /** Before run preparements. */525  private void beforeRun() {526    //527    // Log the start date528    //529    m_startDate = new Date(System.currentTimeMillis());530    // Log start531    logStart();532    // Invoke listeners533    fireEvent(true /*start*/);534    // invoke @BeforeTest535    ITestNGMethod[] testConfigurationMethods = getBeforeTestConfigurationMethods();536    invokeTestConfigurations(testConfigurationMethods);537  }538  private void invokeTestConfigurations(ITestNGMethod[] testConfigurationMethods) {539    if (null != testConfigurationMethods && testConfigurationMethods.length > 0) {540      ConfigMethodArguments arguments = new Builder()541          .usingConfigMethodsAs(testConfigurationMethods)542          .forSuite(m_xmlTest.getSuite())543          .usingParameters(m_xmlTest.getAllParameters())544          .build();545      m_invoker.getConfigInvoker().invokeConfigurations(arguments);546    }547  }548  private ITestNGMethod[] m_allJunitTestMethods = new ITestNGMethod[] {};549  private void privateRunJUnit() {550    final ClassInfoMap cim = new ClassInfoMap(m_testClassesFromXml, false);551    final Set<Class<?>> classes = cim.getClasses();552    final List<ITestNGMethod> runMethods = Lists.newArrayList();553    List<IWorker<ITestNGMethod>> workers = Lists.newArrayList();554    // FIXME: directly referencing JUnitTestRunner which uses JUnit classes555    // may result in an class resolution exception under different JVMs556    // The resolution process is not specified in the JVM spec with a specific implementation,557    // so it can be eager => failure558    workers.add(559        new IWorker<ITestNGMethod>() {560          /** @see TestMethodWorker#getTimeOut() */561          @Override562          public long getTimeOut() {563            return 0;564          }565          /** @see java.lang.Runnable#run() */566          @Override567          public void run() {568            for (Class<?> tc : classes) {569              List<XmlInclude> includedMethods = cim.getXmlClass(tc).getIncludedMethods();570              List<String> methods = Lists.newArrayList();571              for (XmlInclude inc : includedMethods) {572                methods.add(inc.getName());573              }574              IJUnitTestRunner tr = IJUnitTestRunner.createTestRunner(TestRunner.this);575              tr.setInvokedMethodListeners(m_invokedMethodListeners);576              try {577                tr.run(tc, methods.toArray(new String[0]));578              } catch (Exception ex) {579                LOGGER.error(ex.getMessage(), ex);580              } finally {581                runMethods.addAll(tr.getTestMethods());582              }583            }584          }585          @Override586          public List<ITestNGMethod> getTasks() {587            throw new TestNGException("JUnit not supported");588          }589          @Override590          public int getPriority() {591            if (m_allJunitTestMethods.length == 1) {592              return m_allJunitTestMethods[0].getPriority();593            } else {594              return 0;595            }596          }597          @Override598          public int compareTo(@Nonnull IWorker<ITestNGMethod> other) {599            return getPriority() - other.getPriority();600          }601        });602    runJUnitWorkers(workers);603    m_allJunitTestMethods = runMethods.toArray(new ITestNGMethod[0]);604  }605  private static Comparator<ITestNGMethod> newComparator(boolean needPrioritySort) {606    return needPrioritySort ? new TestMethodComparator() : null;607  }608  private boolean sortOnPriority(ITestNGMethod[] interceptedOrder) {609    return m_methodInterceptors.size() > 1 ||610        Arrays.stream(interceptedOrder).anyMatch(m -> m.getPriority() != 0);611  }612  // If any of the test methods specify a priority other than the default, we'll need to be able to sort them.613  private static BlockingQueue<Runnable> newQueue(boolean needPrioritySort) {614    return needPrioritySort ? new PriorityBlockingQueue<>() : new LinkedBlockingQueue<>();615  }616  /**617   * Main method that create a graph of methods and then pass it to the graph executor to run them.618   */619  private void privateRun(XmlTest xmlTest) {620    boolean parallel = xmlTest.getParallel().isParallel();621    // parallel622    int threadCount = parallel ? xmlTest.getThreadCount() : 1;623    // Make sure we create a graph based on the intercepted methods, otherwise an interceptor624    // removing methods would cause the graph never to terminate (because it would expect625    // termination from methods that never get invoked).626    ITestNGMethod[] interceptedOrder = intercept(getAllTestMethods());627    AtomicReference<IDynamicGraph<ITestNGMethod>> reference = new AtomicReference<>();628    TimeUtils.computeAndShowTime("DynamicGraphHelper.createDynamicGraph()",629        () -> {630          IDynamicGraph<ITestNGMethod> ref = DynamicGraphHelper631              .createDynamicGraph(interceptedOrder, getCurrentXmlTest());632          reference.set(ref);633        }634    );635    IDynamicGraph<ITestNGMethod> graph = reference.get();636    graph.setVisualisers(this.visualisers);637    // In some cases, additional sorting is needed to make sure tests run in the appropriate order.638    // If the user specified a method interceptor, or if we have any methods that have a non-default639    // priority on them, we need to sort.640    boolean needPrioritySort = sortOnPriority(interceptedOrder);641    Comparator<ITestNGMethod> methodComparator = newComparator(needPrioritySort);642    if (parallel) {643      if (graph.getNodeCount() <= 0) {644        return;645      }646      ITestNGThreadPoolExecutor executor =647          this.m_configuration.getExecutorFactory().newTestMethodExecutor(648              "test=" + xmlTest.getName(),649              graph,650              this,651              threadCount,652              threadCount,653              0,654              TimeUnit.MILLISECONDS,655              newQueue(needPrioritySort),656              methodComparator);657      executor.run();658      try {659        long timeOut = m_xmlTest.getTimeOut(XmlTest.DEFAULT_TIMEOUT_MS);660        Utils.log(661            "TestRunner",662            2,663            "Starting executor for test "664                + m_xmlTest.getName()665                + " with time out:"666                + timeOut667                + " milliseconds.");668        executor.awaitTermination(timeOut, TimeUnit.MILLISECONDS);669        executor.shutdownNow();670      } catch (InterruptedException handled) {671        LOGGER.error(handled.getMessage(), handled);672        Thread.currentThread().interrupt();673      }674      return;675    }676    List<ITestNGMethod> freeNodes = graph.getFreeNodes();677    if (graph.getNodeCount() > 0 && freeNodes.isEmpty()) {678      throw new TestNGException("No free nodes found in:" + graph);679    }680    while (!freeNodes.isEmpty()) {681      if (needPrioritySort) {682        freeNodes.sort(methodComparator);683        // Since this is sequential, let's run one at a time and fetch/sort freeNodes after each method.684        // Future task: To optimize this, we can only update freeNodes after running a test that another test is dependent upon.685        freeNodes = freeNodes.subList(0, 1);686      }687      createWorkers(freeNodes).forEach(Runnable::run);688      graph.setStatus(freeNodes, IDynamicGraph.Status.FINISHED);689      freeNodes = graph.getFreeNodes();690    }691  }692  /** Apply the method interceptor (if applicable) to the list of methods. */693  private ITestNGMethod[] intercept(ITestNGMethod[] methods) {694    List<IMethodInstance> methodInstances =695        MethodHelper.methodsToMethodInstances(Arrays.asList(methods));696    for (IMethodInterceptor m_methodInterceptor : m_methodInterceptors) {697      methodInstances = m_methodInterceptor.intercept(methodInstances, this);698    }699    List<ITestNGMethod> result = MethodHelper.methodInstancesToMethods(methodInstances);700    // Since an interceptor is involved, we would need to ensure that the ClassMethodMap object is701    // in sync with the702    // output of the interceptor, else @AfterClass doesn't get executed at all when interceptors are703    // involved.704    // so let's update the current classMethodMap object with the list of methods obtained from the705    // interceptor.706    this.m_classMethodMap = new ClassMethodMap(result, null);707    ITestNGMethod[] resultArray = result.toArray(new ITestNGMethod[0]);708    // Check if an interceptor had altered the effective test method count. If yes, then we need to709    // update our configurationGroupMethod object with that information.710    if (resultArray.length != testMethodsContainer.getItems().length) {711      m_groupMethods =712          new ConfigurationGroupMethods(713              new TestMethodContainer(() -> resultArray),714              m_groupMethods.getBeforeGroupsMethods(),715              m_groupMethods.getAfterGroupsMethods());716    }717    // If the user specified a method interceptor, whatever that returns is the order we're going718    // to run things in. Set the intercepted priority for that case.719    // There's a built-in interceptor, so look for more than one.720    if (m_methodInterceptors.size() > 1) {721      for (int i = 0; i < resultArray.length; ++i) {722        resultArray[i].setInterceptedPriority(i);723      }724    }725    return resultArray;726  }727  /**728   * Create a list of workers to run the methods passed in parameter. Each test method is run in its729   * own worker except in the following cases: - The method belongs to a class that730   * has @Test(sequential=true) - The parallel attribute is set to "classes" In both these cases,731   * all the methods belonging to that class will then be put in the same worker in order to run in732   * the same thread.733   */734  @Override735  public List<IWorker<ITestNGMethod>> createWorkers(List<ITestNGMethod> methods) {736    AbstractParallelWorker.Arguments args =737        new AbstractParallelWorker.Arguments.Builder()738            .classMethodMap(this.m_classMethodMap)739            .configMethods(this.m_groupMethods)740            .finder(this.m_annotationFinder)741            .invoker(this.m_invoker)742            .methods(methods)743            .testContext(this)744            .listeners(this.m_classListeners.values())745            .build();746    return AbstractParallelWorker.newWorker(m_xmlTest.getParallel(), m_xmlTest.getGroupByInstances()).createWorkers(args);747  }748  //749  // Invoke the workers750  //751  private void runJUnitWorkers(List<? extends IWorker<ITestNGMethod>> workers) {752    // Sequential run753    workers.forEach(Runnable::run);754  }755  private void afterRun() {756    // invoke @AfterTest757    ITestNGMethod[] testConfigurationMethods = getAfterTestConfigurationMethods();758    invokeTestConfigurations(testConfigurationMethods);759    //760    // Log the end date761    //762    m_endDate = new Date(System.currentTimeMillis());763    dumpInvokedMethods();764    // Invoke listeners765    fireEvent(false /*stop*/);766  }767  /** Logs the beginning of the {@link #beforeRun()} . */768  private void logStart() {769    log(770        "Running test "771            + m_testName772            + " on "773            + m_classMap.size()774            + " "775            + " classes, "776            + " included groups:["777            + Strings.valueOf(m_xmlMethodSelector.getIncludedGroups())778            + "] excluded groups:["779            + Strings.valueOf(m_xmlMethodSelector.getExcludedGroups())780            + "]");781    if (getVerbose() >= 3) {782      for (ITestClass tc : m_classMap.values()) {783        ((TestClass) tc).dump();784      }785    }786  }787  /**788   * Trigger the start/finish event.789   *790   * @param isStart <tt>true</tt> if the event is for start, <tt>false</tt> if the event is for791   *     finish792   */793  private void fireEvent(boolean isStart) {794    for (ITestListener itl : m_testListeners) {795      if (isStart) {796        itl.onStart(this);797      } else {798        itl.onFinish(this);799      }800    }801  }802  /////803  // ITestContext804  //805  @Override806  public String getName() {807    return m_testName;808  }809  /** @return Returns the startDate. */810  @Override811  public Date getStartDate() {812    return m_startDate;813  }814  /** @return Returns the endDate. */815  @Override816  public Date getEndDate() {817    return m_endDate;818  }819  @Override820  public IResultMap getPassedTests() {821    return m_passedTests;822  }823  @Override824  public IResultMap getSkippedTests() {825    return m_skippedTests;826  }827  @Override828  public IResultMap getFailedTests() {829    return m_failedTests;830  }831  @Override832  public IResultMap getFailedButWithinSuccessPercentageTests() {833    return m_failedButWithinSuccessPercentageTests;834  }835  @Override836  public String[] getIncludedGroups() {837    Map<String, String> ig = m_xmlMethodSelector.getIncludedGroups();838    return ig.values().toArray(new String[0]);839  }840  @Override841  public String[] getExcludedGroups() {842    Map<String, String> eg = m_xmlMethodSelector.getExcludedGroups();843    return eg.values().toArray(new String[0]);844  }845  @Override846  public String getOutputDirectory() {847    return m_outputDirectory;848  }849  /** @return Returns the suite. */850  @Override851  public ISuite getSuite() {852    return m_suite;853  }854  @Override855  public ITestNGMethod[] getAllTestMethods() {856    if (getTest().isJUnit()) {857      //This is true only when we are running JUnit mode858      return m_allJunitTestMethods;859    }860    return testMethodsContainer.getItems();861  }862  @Override863  public String getHost() {864    return m_host;865  }866  @Override867  public Collection<ITestNGMethod> getExcludedMethods() {868    Map<ITestNGMethod, ITestNGMethod> vResult = Maps.newHashMap();869    for (ITestNGMethod m : m_excludedMethods) {870      vResult.put(m, m);871    }872    return vResult.keySet();873  }874  /** @see org.testng.ITestContext#getFailedConfigurations() */875  @Override876  public IResultMap getFailedConfigurations() {877    return m_failedConfigurations;878  }879  @Override880  public IResultMap getConfigurationsScheduledForInvocation() {881    return m_configsToBeInvoked;882  }883  /** @see org.testng.ITestContext#getPassedConfigurations() */884  @Override885  public IResultMap getPassedConfigurations() {886    return m_passedConfigurations;887  }888  /** @see org.testng.ITestContext#getSkippedConfigurations() */889  @Override890  public IResultMap getSkippedConfigurations() {891    return m_skippedConfigurations;892  }893  @Override894  public void addPassedTest(ITestNGMethod tm, ITestResult tr) {895    m_passedTests.addResult(tr);896  }897  @Override898  public Set<ITestResult> getPassedTests(ITestNGMethod tm) {899    return m_passedTests.getResults(tm);900  }901  @Override902  public Set<ITestResult> getFailedTests(ITestNGMethod tm) {903    return m_failedTests.getResults(tm);904  }905  @Override906  public Set<ITestResult> getSkippedTests(ITestNGMethod tm) {907    return m_skippedTests.getResults(tm);908  }909  @Override910  public void addSkippedTest(ITestNGMethod tm, ITestResult tr) {911    m_skippedTests.addResult(tr);912  }913  @Override914  public void addFailedTest(ITestNGMethod testMethod, ITestResult result) {915    logFailedTest(result, false /* withinSuccessPercentage */);916  }917  @Override918  public void addFailedButWithinSuccessPercentageTest(919      ITestNGMethod testMethod, ITestResult result) {920    logFailedTest(result, true /* withinSuccessPercentage */);921  }922  @Override923  public XmlTest getTest() {924    return m_xmlTest;925  }926  @Override927  public List<ITestListener> getTestListeners() {928    return m_testListeners;929  }930  @Override931  public List<IConfigurationListener> getConfigurationListeners() {932    List<IConfigurationListener> listeners = Lists.newArrayList(m_configurationListeners);933    for (IConfigurationListener each : this.m_configuration.getConfigurationListeners()) {934      boolean duplicate = false;935      for (IConfigurationListener listener : listeners) {936        if (each.getClass().equals(listener.getClass())) {937          duplicate = true;938          break;939        }940      }941      if (!duplicate) {942        listeners.add(each);943      }944    }945    return Lists.newArrayList(listeners);946  }947  private void logFailedTest(ITestResult tr, boolean withinSuccessPercentage) {948    if (withinSuccessPercentage) {949      m_failedButWithinSuccessPercentageTests.addResult(tr);950    } else {951      m_failedTests.addResult(tr);952    }953  }954  private static void log(String s) {955    Utils.log("TestRunner", 3, s);956  }957  public static int getVerbose() {958    return m_verbose;959  }960  public void setVerbose(int n) {961    m_verbose = n;962  }963  // TODO: This method needs to be removed and we need to be leveraging addListener().964  // Investigate and fix this.965  void addTestListener(ITestListener listener) {966    Optional<ITestListener> found = m_testListeners.stream()967        .filter(iTestListener -> iTestListener.getClass().equals(listener.getClass()))968        .findAny();969    if (found.isPresent()) {970      return;971    }972    m_testListeners.add(listener);973  }974  public void addListener(ITestNGListener listener) {975    // TODO a listener may be added many times if it implements many interfaces976    if (listener instanceof IMethodInterceptor) {977      m_methodInterceptors.add((IMethodInterceptor) listener);978    }979    if (listener instanceof ITestListener) {980      // At this point, the field m_testListeners has already been used in the creation981      addTestListener((ITestListener) listener);982    }983    if (listener instanceof IClassListener) {984      IClassListener classListener = (IClassListener) listener;985      if (!m_classListeners.containsKey(classListener.getClass())) {986        m_classListeners.put(classListener.getClass(), classListener);987      }988    }989    if (listener instanceof IConfigurationListener) {990      addConfigurationListener((IConfigurationListener) listener);991    }992    if (listener instanceof IConfigurable) {993      m_configuration.setConfigurable((IConfigurable) listener);994    }995    if (listener instanceof IHookable) {996      m_configuration.setHookable((IHookable) listener);997    }998    if (listener instanceof IExecutionListener) {999      IExecutionListener iel = (IExecutionListener) listener;1000      if (m_configuration.addExecutionListenerIfAbsent(iel)) {1001        iel.onExecutionStart();1002      }1003    }1004    if (listener instanceof IDataProviderListener) {1005      IDataProviderListener dataProviderListener = (IDataProviderListener) listener;1006      holder.addListener(dataProviderListener);1007    }1008    if (listener instanceof IDataProviderInterceptor) {1009      IDataProviderInterceptor interceptor = (IDataProviderInterceptor) listener;1010      holder.addInterceptor(interceptor);1011    }1012    if (listener instanceof IExecutionVisualiser) {1013      IExecutionVisualiser l = (IExecutionVisualiser) listener;1014      visualisers.add(l);1015    }1016    m_suite.addListener(listener);1017  }1018  void addConfigurationListener(IConfigurationListener icl) {1019    m_configurationListeners.add(icl);1020  }1021  private void dumpInvokedMethods() {1022    MethodHelper.dumpInvokedMethodInfoToConsole(getAllTestMethods(), getVerbose());1023  }1024  private final IResultMap m_passedConfigurations = new ResultMap();1025  private final IResultMap m_skippedConfigurations = new ResultMap();1026  private final IResultMap m_failedConfigurations = new ResultMap();1027  private final IResultMap m_configsToBeInvoked = new ResultMap();1028  private class ConfigurationListener implements IConfigurationListener {1029    @Override1030    public void beforeConfiguration(ITestResult tr) {...Source:SuiteRunner.java  
...315      runTest(tr);316    }317  }318  private void runTest(TestRunner tr) {319    visualisers.forEach(tr::addListener);320    tr.run();321    ISuiteResult sr = new SuiteResult(xmlSuite, tr);322    synchronized (suiteResults) {323      suiteResults.put(tr.getName(), sr);324    }325  }326  /**327   * Implement <suite parallel="tests">. Since this kind of parallelism happens at the suite level,328   * we need a special code path to execute it. All the other parallelism strategies are implemented329   * at the test level in TestRunner#createParallelWorkers (but since this method deals with just330   * one <test> tag, it can't implement <suite parallel="tests">, which is why we're doing it here).331   */332  private void runInParallelTestMode() {333    List<Runnable> tasks = Lists.newArrayList(testRunners.size());334    for (TestRunner tr : testRunners) {335      tasks.add(new SuiteWorker(tr));336    }337    ThreadUtil.execute(338        "tests",339        tasks,340        xmlSuite.getThreadCount(),341        xmlSuite.getTimeOut(XmlTest.DEFAULT_TIMEOUT_MS)342    );343  }344  private class SuiteWorker implements Runnable {345    private final TestRunner testRunner;346    public SuiteWorker(TestRunner tr) {347      testRunner = tr;348    }349    @Override350    public void run() {351      Utils.log(352          "[SuiteWorker]",353          4,354          "Running XML Test '" + testRunner.getTest().getName() + "' in Parallel");355      runTest(testRunner);356    }357  }358  /** @param reporter The ISuiteListener interested in reporting the result of the current suite. */359  protected void addListener(ISuiteListener reporter) {360    if (!listeners.containsKey(reporter.getClass())) {361      listeners.put(reporter.getClass(), reporter);362    }363  }364  @Override365  public void addListener(ITestNGListener listener) {366    if (listener instanceof IInvokedMethodListener) {367      IInvokedMethodListener invokedMethodListener = (IInvokedMethodListener) listener;368      invokedMethodListeners.put(invokedMethodListener.getClass(), invokedMethodListener);369    }370    if (listener instanceof ISuiteListener) {371      addListener((ISuiteListener) listener);372    }373    if (listener instanceof IExecutionVisualiser) {374      addVisualiser((IExecutionVisualiser) listener);375    }376    if (listener instanceof IReporter) {377      addReporter((IReporter) listener);378    }379    if (listener instanceof IConfigurationListener) {380      addConfigurationListener((IConfigurationListener) listener);381    }382    if (listener instanceof IClassListener) {383      IClassListener classListener = (IClassListener) listener;384      if (!classListeners.containsKey(classListener.getClass())) {385        classListeners.put(classListener.getClass(), classListener);386      }387    }388    if (listener instanceof IDataProviderListener) {389      IDataProviderListener listenerObject = (IDataProviderListener) listener;390      this.holder.addListener(listenerObject);391    }392    if (listener instanceof IDataProviderInterceptor) {393      IDataProviderInterceptor interceptor = (IDataProviderInterceptor) listener;394      this.holder.addInterceptor(interceptor);395    }396    if (listener instanceof ITestListener) {397      for(TestRunner testRunner : testRunners) {398        testRunner.addTestListener((ITestListener) listener);399      }400    }401  }402  @Override403  public String getOutputDirectory() {404    return outputDir + File.separatorChar + getName();405  }406  @Override407  public Map<String, ISuiteResult> getResults() {408    return suiteResults;409  }410  /**411   * FIXME: should be removed?412   *413   * @see org.testng.ISuite#getParameter(java.lang.String)414   */415  @Override416  public String getParameter(String parameterName) {417    return xmlSuite.getParameter(parameterName);418  }419  /** @see org.testng.ISuite#getMethodsByGroups() */420  @Override421  public Map<String, Collection<ITestNGMethod>> getMethodsByGroups() {422    Map<String, Collection<ITestNGMethod>> result = Maps.newHashMap();423    for (TestRunner tr : testRunners) {424      ITestNGMethod[] methods = tr.getAllTestMethods();425      for (ITestNGMethod m : methods) {426        String[] groups = m.getGroups();427        for (String groupName : groups) {428          Collection<ITestNGMethod> testMethods =429              result.computeIfAbsent(groupName, k -> Lists.newArrayList());430          testMethods.add(m);431        }432      }433    }434    return result;435  }436  /** @see org.testng.ISuite#getExcludedMethods() */437  @Override438  public Collection<ITestNGMethod> getExcludedMethods() {439    return testRunners.stream()440        .flatMap(tr -> tr.getExcludedMethods().stream())441        .collect(Collectors.toList());442  }443  @Override444  public IObjectFactory getObjectFactory() {445    return objectFactory instanceof IObjectFactory ? (IObjectFactory) objectFactory : null;446  }447  @Override448  public IObjectFactory2 getObjectFactory2() {449    return objectFactory instanceof IObjectFactory2 ? (IObjectFactory2) objectFactory : null;450  }451  /**452   * Returns the annotation finder for the given annotation type.453   *454   * @return the annotation finder for the given annotation type.455   */456  @Override457  public IAnnotationFinder getAnnotationFinder() {458    return configuration.getAnnotationFinder();459  }460  public static void ppp(String s) {461    System.out.println("[SuiteRunner] " + s);462  }463  /** The default implementation of {@link ITestRunnerFactory}. */464  private static class DefaultTestRunnerFactory implements ITestRunnerFactory {465    private final ITestListener[] failureGenerators;466    private final boolean useDefaultListeners;467    private final boolean skipFailedInvocationCounts;468    private final IConfiguration configuration;469    private final Comparator<ITestNGMethod> comparator;470    public DefaultTestRunnerFactory(471        IConfiguration configuration,472        ITestListener[] failureListeners,473        boolean useDefaultListeners,474        boolean skipFailedInvocationCounts,475        Comparator<ITestNGMethod> comparator) {476      this.configuration = configuration;477      this.failureGenerators = failureListeners;478      this.useDefaultListeners = useDefaultListeners;479      this.skipFailedInvocationCounts = skipFailedInvocationCounts;480      this.comparator = comparator;481    }482    @Override483    public TestRunner newTestRunner(484        ISuite suite,485        XmlTest test,486        Collection<IInvokedMethodListener> listeners,487        List<IClassListener> classListeners) {488      return newTestRunner(suite, test, listeners, classListeners, Collections.emptyMap());489    }490    @Override491    public TestRunner newTestRunner(492        ISuite suite,493        XmlTest test,494        Collection<IInvokedMethodListener> listeners,495        List<IClassListener> classListeners,496        Map<Class<? extends IDataProviderListener>, IDataProviderListener> dataProviderListeners) {497      DataProviderHolder holder = new DataProviderHolder();498      holder.addListeners(dataProviderListeners.values());499      return newTestRunner(suite, test, listeners, classListeners, holder);500    }501    @Override502    public TestRunner newTestRunner(ISuite suite, XmlTest test,503        Collection<IInvokedMethodListener> listeners, List<IClassListener> classListeners,504        DataProviderHolder holder) {505      boolean skip = skipFailedInvocationCounts;506      if (!skip) {507        skip = test.skipFailedInvocationCounts();508      }509      TestRunner testRunner =510          new TestRunner(511              configuration,512              suite,513              test,514              suite.getOutputDirectory(),515              suite.getAnnotationFinder(),516              skip,517              listeners,518              classListeners,519              comparator, holder);520      if (useDefaultListeners) {521        testRunner.addListener(new TestHTMLReporter());522        testRunner.addListener(new JUnitXMLReporter());523        // TODO: Moved these here because maven2 has output reporters running524        // already, the output from these causes directories to be created with525        // files. This is not the desired behaviour of running tests in maven2.526        // Don't know what to do about this though, are people relying on these527        // to be added even with defaultListeners set to false?528        testRunner.addListener(new TextReporter(testRunner.getName(), TestRunner.getVerbose()));529      }530      for (ITestListener itl : failureGenerators) {531        testRunner.addTestListener(itl);532      }533      for (IConfigurationListener cl : configuration.getConfigurationListeners()) {534        testRunner.addConfigurationListener(cl);535      }536      return testRunner;537    }538  }539  private static class ProxyTestRunnerFactory implements ITestRunnerFactory {540    private final ITestListener[] failureGenerators;541    private final ITestRunnerFactory target;542    public ProxyTestRunnerFactory(ITestListener[] failureListeners, ITestRunnerFactory target) {543      failureGenerators = failureListeners;544      this.target = target;545    }546    @Override547    public TestRunner newTestRunner(548        ISuite suite,549        XmlTest test,550        Collection<IInvokedMethodListener> listeners,551        List<IClassListener> classListeners) {552      return newTestRunner(suite, test, listeners, classListeners, Collections.emptyMap());553    }554    @Override555    public TestRunner newTestRunner(556        ISuite suite,557        XmlTest test,558        Collection<IInvokedMethodListener> listeners,559        List<IClassListener> classListeners,560        Map<Class<? extends IDataProviderListener>, IDataProviderListener> dataProviderListeners) {561      DataProviderHolder holder = new DataProviderHolder();562      holder.addListeners(dataProviderListeners.values());563      return newTestRunner(suite, test, listeners, classListeners, holder);564    }565    @Override566    public TestRunner newTestRunner(ISuite suite, XmlTest test,567        Collection<IInvokedMethodListener> listeners, List<IClassListener> classListeners,568        DataProviderHolder holder) {569      TestRunner testRunner = target.newTestRunner(suite, test, listeners, classListeners, holder);570      testRunner.addListener(new TextReporter(testRunner.getName(), TestRunner.getVerbose()));571      for (ITestListener itl : failureGenerators) {572        testRunner.addListener(itl);573      }574      return testRunner;575    }576  }577  public void setHost(String host) {578    remoteHost = host;579  }580  @Override581  public String getHost() {582    return remoteHost;583  }584  /** @see org.testng.ISuite#getSuiteState() */585  @Override586  public SuiteRunState getSuiteState() {...Source:FactoryMethod.java  
...49        obj = InstanceCreator.newInstanceOrNull(listener);50      }51      if (obj != null) {52        if (IDataProviderListener.class.isAssignableFrom(obj.getClass())) {53          holder.addListener((IDataProviderListener) obj);54        }55        if (IDataProviderInterceptor.class.isAssignableFrom(obj.getClass())) {56          holder.addInterceptor((IDataProviderInterceptor) obj);57        }58      }59    }60  }61  // This constructor is intentionally created with package visibility because we dont have any62  // callers of this63  // constructor outside of this package.64  FactoryMethod(65      ConstructorOrMethod com,66      Object instance,67      IAnnotationFinder annotationFinder,...Source:DataProviderHolder.java  
...14  }15  public Collection<IDataProviderInterceptor> getInterceptors() {16    return Collections.unmodifiableCollection(interceptors);17  }18  public void addListeners(Collection<IDataProviderListener> listeners) {19    listeners.forEach(this::addListener);20  }21  public void addListener(IDataProviderListener listener) {22    listeners.add(listener);23  }24  public void addInterceptors(Collection<IDataProviderInterceptor> interceptors) {25    interceptors.forEach(this::addInterceptor);26  }27  public void addInterceptor(IDataProviderInterceptor interceptor) {28    interceptors.add(interceptor);29  }30  public void merge(DataProviderHolder other) {31    this.listeners.addAll(other.getListeners());32    this.interceptors.addAll(other.getInterceptors());33  }34}...addListener
Using AI Code Generation
1import org.testng.annotations.DataProvider;2import org.testng.annotations.Test;3public class DataProviderTest {4    @DataProvider(name = "data-provider")5    public Object[][] dataProviderMethod() {6        return new Object[][] { { "data one" }, { "data two" } };7    }8    @Test(dataProvider = "data-provider")9    public void testMethod(String data) {10        System.out.println("Data is: " + data);11    }12}13import org.testng.annotations.DataProvider;14import org.testng.annotations.Test;15public class DataProviderTest {16    @DataProvider(name = "data-provider")17    public Object[][] dataProviderMethod() {18        return new Object[][] { { "data one" }, { "data two" } };19    }20    @Test(dataProvider = "data-provider")21    public void testMethod(String data) {22        System.out.println("Data is: " + data);23    }24}25import org.testng.annotations.DataProvider;26import org.testng.annotations.Test;27public class DataProviderTest {28    @DataProvider(name = "data-provider")29    public Object[][] dataProviderMethod() {30        return new Object[][] { { "data one" }, { "data two" } };31    }32    @Test(dataProvider = "data-provider")33    public void testMethod(String data) {34        System.out.println("Data is: " + data);35    }36}37import org.testng.annotations.DataProvider;38import org.testng.annotations.Test;39public class DataProviderTest {40    @DataProvider(name = "data-provider")41    public Object[][] dataProviderMethod() {42        return new Object[][] { { "data one" }, { "data two" } };43    }44    @Test(dataProvider = "data-provider")45    public void testMethod(String data) {46        System.out.println("Data is: " + data);47    }48}49import org.testng.annotations.DataProvider;50import org.testng.annotations.Test;51public class DataProviderTest {52    @DataProvider(name = "data-provider")53    public Object[][] dataProviderMethod() {54        return new Object[][] { { "data one" }, { "data two" } };55    }56    @Test(dataProvider = "data-provider")addListener
Using AI Code Generation
1package com.packt.testng.chapter4;2import org.testng.annotations.DataProvider;3import org.testng.annotations.Test;4public class DataProviderTest {5    @DataProvider(name = "data-provider")6    public Object[][] dataProviderMethod() {7        return new Object[][] { { "data one" }, { "data two" } };8    }9    @Test(dataProvider = "data-provider")10    public void testMethod(String data) {11        System.out.println("Data is: " + data);12    }13}14package com.packt.testng.chapter4;15import org.testng.annotations.DataProvider;16import org.testng.annotations.Test;17public class DataProviderTest {18    @DataProvider(name = "data-provider")19    public Object[][] dataProviderMethod() {20        return new Object[][] { { "data one" }, { "data two" } };21    }22    @Test(dataProvider = "data-provider")23    public void testMethod(String data) {24        System.out.println("Data is: " + data);25    }26}27package com.packt.testng.chapter4;28import java.util.Iterator;29import org.testng.annotations.DataProvider;30import org.testng.annotations.Test;31public class DataProviderTest {32    @DataProvider(name = "data-provider")33    public Iterator<Object[]> dataProviderMethod() {34        return new MyDataProvider().iterator();35    }36    @Test(dataProvider = "data-provider")37    public void testMethod(String data) {38        System.out.println("Data is: " + data);39    }40}41package com.packt.testng.chapter4;42import java.util.Iterator;43import java.util.LinkedList;44import java.util.List;45public class MyDataProvider implements Iterable<Object[]> {46    private List<Object[]> data = new LinkedList<Object[]>();47    public MyDataProvider() {48        data.add(new Object[] { "data one" });49        data.add(new Object[] { "data two" });50    }51    public Iterator<Object[]> iterator() {52        return data.iterator();53    }54}55package com.packt.testng.chapter4;56import java.util.Iterator;57import java.util.LinkedList;58import java.util.List;TestNG is a Java-based open-source framework for test automation that includes various test types, such as unit testing, functional testing, E2E testing, etc. TestNG is in many ways similar to JUnit and NUnit. But in contrast to its competitors, its extensive features make it a lot more reliable framework. One of the major reasons for its popularity is its ability to structure tests and improve the scripts' readability and maintainability. Another reason can be the important characteristics like the convenience of using multiple annotations, reliance, and priority that make this framework popular among developers and testers for test design. You can refer to the TestNG tutorial to learn why you should choose the TestNG framework.
You can push your abilities to do automated testing using TestNG and advance your career by earning a TestNG certification. Check out our TestNG certification.
Watch this complete tutorial to learn how you can leverage the capabilities of the TestNG framework for Selenium automation testing.
Get 100 minutes of automation test minutes FREE!!
