1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.cts.testng; 18 19 import org.testng.TestNG; 20 import org.testng.xml.XmlClass; 21 import org.testng.xml.XmlInclude; 22 import org.testng.xml.XmlSuite; 23 import org.testng.xml.XmlTest; 24 25 import java.util.ArrayList; 26 import java.util.List; 27 28 /** 29 * Test runner to run a single TestNG test. It will output either [PASSED] or [FAILED] at the end. 30 */ 31 public class SingleTestNGTestRunner { 32 private static String mUsage = "Usage: java -cp <classpath> SingleTestNGTestRunner" + 33 " class#testMethod"; 34 private static final String PASSED_TEST_MARKER = "[ PASSED ]"; 35 private static final String FAILED_TEST_MARKER = "[ FAILED ]"; 36 main(String... args)37 public static void main(String... args) { 38 if (args.length != 1) { 39 throw new IllegalArgumentException(mUsage); 40 } 41 String[] classAndMethod = args[0].split("#"); 42 if (classAndMethod.length != 2) { 43 throw new IllegalArgumentException(mUsage); 44 } 45 46 TestNG testng = createTestNG(classAndMethod[0], classAndMethod[1]); 47 testng.run(); 48 String status = (!testng.hasFailure()) ? PASSED_TEST_MARKER : FAILED_TEST_MARKER; 49 System.out.println(String.format("%s %s.%s", status, 50 classAndMethod[0], classAndMethod[1])); 51 } 52 createTestNG(String klass, String method)53 private static org.testng.TestNG createTestNG(String klass, String method) { 54 org.testng.TestNG testng = new org.testng.TestNG(); 55 testng.setUseDefaultListeners(false); // Don't create the testng-specific HTML/XML reports. 56 testng.addListener(new SingleTestNGTestRunListener()); 57 58 /* Construct the following equivalent XML configuration: 59 * 60 * <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > 61 * <suite> 62 * <test> 63 * <classes> 64 * <class name="$klass"> 65 * <include name="$method" /> 66 * </class> 67 * </classes> 68 * </test> 69 * </suite> 70 * 71 * This will ensure that only a single klass/method is being run by testng. 72 * (It can still be run multiple times due to @DataProvider, with different parameters 73 * each time) 74 */ 75 List<XmlSuite> suites = new ArrayList<>(); 76 XmlSuite the_suite = new XmlSuite(); 77 XmlTest the_test = new XmlTest(the_suite); 78 XmlClass the_class = new XmlClass(klass); 79 XmlInclude the_include = new XmlInclude(method); 80 81 the_class.getIncludedMethods().add(the_include); 82 the_test.getXmlClasses().add(the_class); 83 suites.add(the_suite); 84 testng.setXmlSuites(suites); 85 86 return testng; 87 } 88 } 89