public override TestableChallengeResult TestImplementation(ICalculator implementation) { var testResult = new TestableChallengeResult(); var random = new Random(); // Some random numbers var a = random.Next(1000); var b = random.Next(1000); try { // Test ADD method var addResult = implementation.Add(a, b); var addPassed = false; if (a + b == addResult) { addPassed = true; } else { testResult.AddMessage("Add method failed", string.Format("Tested with a = {0} and b = {1}, and yielded result: {2}", a, b, addResult)); } // Test the SUBTRACT method var subtractResult = implementation.Subtract(a, b); var subtractPassed = false; if (a - b == subtractResult) { subtractPassed = true; } else { testResult.AddMessage("Subtract method failed", string.Format("Tested with a = {0} and b = {1}, and yielded result: {2}", a, b, subtractResult)); } // Test the MULTIPLY method var multiplyResult = implementation.Multiply(a, b); var multiplyPassed = false; if (a * b == multiplyResult) { multiplyPassed = true; } else { testResult.AddMessage("Multiply method failed", string.Format("Tested with a = {0} and b = {1}, and yielded result: {2}", a, b, multiplyResult)); } // Test the DIVIDE method var divideResult = implementation.Divide(a, b); var dividePassed = false; if ((a * 1f) / (b * 1f) == divideResult) { dividePassed = true; } else { testResult.AddMessage("Divide method failed", string.Format("Tested with a = {0} and b = {1}, and yielded result: {2}", a, b, divideResult)); } testResult.IsPassed = addPassed && subtractPassed && multiplyPassed && dividePassed; } catch { testResult.AddMessage("Challenge testing failed", "One of more methods threw an exception"); } return(testResult); }
static void Main(string[] args) { var testResult = new TestableChallengeResult(); try { if (args.Length != 2) { throw new ArgumentException("Two arguments were not supplied"); } var targetDirectory = args[0].Replace("*", " "); var targetChallenge = args[1]; // Load all assemblies in targetDirectory var assemblies = new List <string>(); // Some directory listing hackery assemblies.AddRange(Directory.GetFiles(targetDirectory, "*.dll", SearchOption.AllDirectories) .Where(file => file.IndexOf("vshost") < 0)); assemblies.AddRange(Directory.GetFiles(targetDirectory, "*.exe", SearchOption.AllDirectories) .Where(file => file.IndexOf("vshost") < 0)); Type targetType = null; // Find targetChallenge-type in the found assemblies foreach (var file in assemblies) { var assembly = Assembly.LoadFrom(file); var types = assembly.GetTypes(); targetType = types.SingleOrDefault(a => a.FullName == targetChallenge); if (targetType != null) { break; } } var methodInfo = targetType.GetMethod("TestChallenge"); if (methodInfo == null) { throw new Exception("The TestChallenge method was not found in the target type: " + targetType.FullName); } var instance = Activator.CreateInstance(targetType); var invokeResult = methodInfo.Invoke(instance, new[] { targetDirectory }); // Deep Clone the result into a TestableChallengeResult. // We need to do it like this (instead of just casting it to TestableChallengeResult), // because the TestableChallengeResult type of the invoked result is from another assembly. // This is not allowed in .NET Framework. // It will however serialize into a TestableChallengeResult just fine, because they // (by the way the solution is structured), can be guaranteed to be identical. testResult = DeepClone <TestableChallengeResult>(invokeResult); } catch (Exception e) { testResult.Error = e.Message + "\r\n" + e.StackTrace; } // XmlSerialize the challenge result, so it can be transported to the strokes extension via standard output. var serializer = new XmlSerializer(typeof(TestableChallengeResult)); serializer.Serialize(Console.Out, testResult); }