// Main entry point for the program. public static int Main(String[] args) { int numArgs = args.Length; int argNum = 0; String arg; bool stopAtFail = false; bool showOnlyFailed = false; bool listTests = false; String filename; String typeName = null; Assembly assembly; Type type; MethodInfo method; Test test; Test specificTest; TestResult result; // Parse the command-line options. while (argNum < numArgs && args[argNum].StartsWith("-")) { arg = args[argNum]; if (arg == "-s" || arg == "--stop-at-fail") { stopAtFail = true; } else if (arg == "-f" || arg == "--show-failed") { showOnlyFailed = true; } else if (arg == "-l" || arg == "--list") { listTests = true; } else if (arg == "-t" || arg == "--type-name") { if ((argNum + 1) >= numArgs) { ShowUsage(); return(1); } ++argNum; typeName = args[argNum]; } else if (arg.StartsWith("-t")) { typeName = arg.Substring(2); } else if (arg == "-v" || arg == "--version") { ShowVersion(); return(0); } else { ShowUsage(); return(1); } ++argNum; } // Get the filename for the test assembly. if (argNum >= numArgs) { ShowUsage(); return(1); } filename = args[argNum++]; // If the type name is not specified, then derive it // from the name of the test assembly. if (typeName == null) { int index; if (filename.EndsWith(".dll")) { typeName = filename.Substring(0, filename.Length - 4); } else { typeName = filename; } index = typeName.LastIndexOf('/'); if (index == -1) { index = typeName.LastIndexOf('\\'); } if (index != -1) { typeName = typeName.Substring(index + 1); } } // Load the test assembly. This will throw an // exception if something went wrong, which will // cause the program to exit with an explaination. // Use "Assembly.LoadFrom" if present (it may not // be present if mscorilb.dll is ECMA-compatible, // so we have to be careful how we invoke it). MethodInfo loadFrom = typeof(Assembly).GetMethod ("LoadFrom", new Type [] { typeof(String) }); if (loadFrom != null) { Object[] invokeArgs = new Object [1]; invokeArgs[0] = filename; assembly = (Assembly)(loadFrom.Invoke(null, invokeArgs)); } else { assembly = Assembly.Load("file://" + filename); } // Look for the test type within the assembly. try { type = assembly.GetType(typeName); } catch (TypeLoadException) { type = null; } if (type == null) { ErrorWriteLine (typeName + ": type does not exist in " + filename); return(1); } // Call the "type.Suite()" method to construct the // top-level test object, which is normally a suite. method = type.GetMethod("Suite", BindingFlags.Public | BindingFlags.Static, null, Type.EmptyTypes, null); if (method == null) { // Try again, in case the user prefers lower case names. method = type.GetMethod("suite", Type.EmptyTypes); } if (method == null) { ErrorWriteLine (typeName + ".Suite(): method does not exist in " + filename); return(1); } test = (Test)(method.Invoke(null, null)); if (test == null) { ErrorWriteLine (typeName + ".Suite(): method returned null"); return(1); } // Construct the TestResult class to collect up the results. result = new TestWriterResult (ConsoleOut, stopAtFail, showOnlyFailed); // List or run the tests. if (listTests) { if (argNum < numArgs) { // List only the specified tests. while (argNum < numArgs) { specificTest = test.Find(args[argNum]); if (specificTest == null) { ErrorWriteLine (args[argNum] + ": unknown test name"); } else { specificTest.List(result); } ++argNum; } } else { // List all tests. test.List(result); } } else if (argNum < numArgs) { // Run only the specified tests. try { while (argNum < numArgs) { specificTest = test.Find(args[argNum]); if (specificTest == null) { ErrorWriteLine (args[argNum] + ": unknown test name"); } else { specificTest.Run(result); } ++argNum; } } catch (TestStop) { // Thrown by "TestWriterResult" to stop // testing at the first failure. } result.ReportSummary(); } else { // Run all tests. try { test.Run(result); } catch (TestStop) { // Thrown by "TestWriterResult" to stop // testing at the first failure. } result.ReportSummary(); } // Done. return(result.HadFailures ? 1 : 0); }
// Main entry point for the program. public static int Main(String[] args) { int numArgs = args.Length; int argNum = 0; String arg; bool stopAtFail = false; bool showOnlyFailed = false; bool listTests = false; String filename; String typeName = null; Assembly assembly; Type type; MethodInfo method; Test test; Test specificTest; TestResult result; // Parse the command-line options. while(argNum < numArgs && args[argNum].StartsWith("-")) { arg = args[argNum]; if(arg == "-s" || arg == "--stop-at-fail") { stopAtFail = true; } else if(arg == "-f" || arg == "--show-failed") { showOnlyFailed = true; } else if(arg == "-l" || arg == "--list") { listTests = true; } else if(arg == "-t" || arg == "--type-name") { if((argNum + 1) >= numArgs) { ShowUsage(); return 1; } ++argNum; typeName = args[argNum]; } else if(arg.StartsWith("-t")) { typeName = arg.Substring(2); } else if(arg == "-v" || arg == "--version") { ShowVersion(); return 0; } else { ShowUsage(); return 1; } ++argNum; } // Get the filename for the test assembly. if(argNum >= numArgs) { ShowUsage(); return 1; } filename = args[argNum++]; // If the type name is not specified, then derive it // from the name of the test assembly. if(typeName == null) { int index; if(filename.EndsWith(".dll")) { typeName = filename.Substring(0, filename.Length - 4); } else { typeName = filename; } index = typeName.LastIndexOf('/'); if(index == -1) { index = typeName.LastIndexOf('\\'); } if(index != -1) { typeName = typeName.Substring(index + 1); } } // Load the test assembly. This will throw an // exception if something went wrong, which will // cause the program to exit with an explaination. // Use "Assembly.LoadFrom" if present (it may not // be present if mscorilb.dll is ECMA-compatible, // so we have to be careful how we invoke it). MethodInfo loadFrom = typeof(Assembly).GetMethod ("LoadFrom", new Type [] {typeof(String)}); if(loadFrom != null) { Object[] invokeArgs = new Object [1]; invokeArgs[0] = filename; assembly = (Assembly)(loadFrom.Invoke(null, invokeArgs)); } else { assembly = Assembly.Load("file://" + filename); } // Look for the test type within the assembly. try { type = assembly.GetType(typeName); } catch(TypeLoadException) { type = null; } if(type == null) { ErrorWriteLine (typeName + ": type does not exist in " + filename); return 1; } // Call the "type.Suite()" method to construct the // top-level test object, which is normally a suite. method = type.GetMethod("Suite", BindingFlags.Public | BindingFlags.Static, null, Type.EmptyTypes, null); if(method == null) { // Try again, in case the user prefers lower case names. method = type.GetMethod("suite", Type.EmptyTypes); } if(method == null) { ErrorWriteLine (typeName + ".Suite(): method does not exist in " + filename); return 1; } test = (Test)(method.Invoke(null, null)); if(test == null) { ErrorWriteLine (typeName + ".Suite(): method returned null"); return 1; } // Construct the TestResult class to collect up the results. result = new TestWriterResult (ConsoleOut, stopAtFail, showOnlyFailed); // List or run the tests. if(listTests) { if(argNum < numArgs) { // List only the specified tests. while(argNum < numArgs) { specificTest = test.Find(args[argNum]); if(specificTest == null) { ErrorWriteLine (args[argNum] + ": unknown test name"); } else { specificTest.List(result); } ++argNum; } } else { // List all tests. test.List(result); } } else if(argNum < numArgs) { // Run only the specified tests. try { while(argNum < numArgs) { specificTest = test.Find(args[argNum]); if(specificTest == null) { ErrorWriteLine (args[argNum] + ": unknown test name"); } else { specificTest.Run(result); } ++argNum; } } catch(TestStop) { // Thrown by "TestWriterResult" to stop // testing at the first failure. } result.ReportSummary(); } else { // Run all tests. try { test.Run(result); } catch(TestStop) { // Thrown by "TestWriterResult" to stop // testing at the first failure. } result.ReportSummary(); } // Done. return (result.HadFailures ? 1 : 0); }