예제 #1
0
        /// <summary>
        /// Deserializes the results.xml file to CoverageSession
        /// </summary>
        /// <returns>OpenCover execution results</returns>
        internal CoverageSession GetExecutionResults()
        {
            CoverageSession coverageSession = null;

            try
            {
                var serializer = new XmlSerializer(typeof(CoverageSession), new[] { typeof(Module), typeof(OpenCover.Framework.Model.File), typeof(Class) });
                using (var stream = System.IO.File.Open(_openCoverResultsFile, FileMode.Open))
                {
                    coverageSession = serializer.Deserialize(stream) as CoverageSession;
                }

                if (_commandLineParameterReader.ReadConfiguration(_currentWorkingDirectory))
                {
                    ExecuteTestResultPostProcessor(_testResultsFile);
                    ExecuteCoverageResultPostProcessor(_openCoverResultsFile);
                }

                if (!System.Diagnostics.Debugger.IsAttached)
                {
                    System.IO.File.Delete(_openCoverResultsFile);
                }
            }
            catch (Exception ex)
            {
                IDEHelper.WriteToOutputWindow(ex.Message);
                IDEHelper.WriteToOutputWindow(ex.StackTrace);
            }

            return(coverageSession);
        }
        /// <summary>
        /// Reads the test results file.
        /// </summary>
        protected override void ReadTestResults()
        {
            try
            {
                if (File.Exists(_testResultsFile))
                {
                    var testResultsFile = XDocument.Load(_testResultsFile);

                    _executionStatus.Clear();

                    var assemblies = GetElementsByAttribute(testResultsFile, "test-suite", "type", "Assembly");

                    foreach (var assembly in assemblies)
                    {
                        var testCases   = GetElementsByAttribute(assembly, "test-suite", "type", "TestFixture");
                        var testMethods = testCases.Elements("results").Elements("test-case").Select(tc => GetTestResult(tc, null));
                        testMethods = testMethods.Union(testCases.Elements("results").Elements("test-suite").Select(ts => ReadTestCase(ts)));

                        _executionStatus.Add(assembly.Attribute("name").Value, testMethods);
                    }
                }
                else
                {
                    IDEHelper.WriteToOutputWindow("Test Results File does not exist: {0}", _testResultsFile);
                }
            }
            catch (Exception ex)
            {
                IDEHelper.WriteToOutputWindow(ex.Message);
                IDEHelper.WriteToOutputWindow(ex.StackTrace);
            }
        }
예제 #3
0
        /// <summary>
        /// Reads the test results file.
        /// </summary>
        protected override void ReadTestResults()
        {
            try
            {
                if (File.Exists(_testResultsFile))
                {
                    var testResultsFile = XDocument.Load(_testResultsFile);

                    _executionStatus.Clear();

                    var rootAssemblies = testResultsFile.Elements("assemblies");
                    var assemblies     = rootAssemblies.Elements().Where(e => e.Name == "assembly");

                    foreach (var assembly in assemblies)
                    {
                        var testCases   = assembly.Elements("collection");
                        var testMethods = testCases.Elements("test").Select(tc => GetTestResult(tc, null));
                        _executionStatus.Add(assembly.Attribute("name").Value.ToLower(), testMethods);
                    }
                }
                else
                {
                    IDEHelper.WriteToOutputWindow("Test Results File does not exist: {0}", _testResultsFile);
                }
            }
            catch (Exception ex)
            {
                IDEHelper.WriteToOutputWindow(ex.Message);
                IDEHelper.WriteToOutputWindow(ex.StackTrace);
            }
        }
예제 #4
0
        /// <summary>
        /// Starts OpenCover.Console.exe to start CodeCoverage session.
        /// </summary>
        /// <returns>Test results (trx) and OpenCover results files' paths</returns>
        internal Tuple <string, string> Execute()
        {
            var openCoverStartInfo = GetOpenCoverProcessInfo(_commandLineArguments);

            if (!System.IO.File.Exists(openCoverStartInfo.FileName))
            {
                MessageBox.Show("Please install OpenCover and execute tests!", "OpenCover not found!", MessageBoxButton.OK);
                return(null);
            }

            Process process = Process.Start(openCoverStartInfo);

            var consoleOutputReaderBuilder = new StringBuilder();

            // TODO: See if this loop has any performance bottlenecks
            while (true)
            {
                if (process.HasExited)
                {
                    break;
                }

                string nextLine = process.StandardOutput.ReadLine();
                IDEHelper.WriteToOutputWindow(nextLine);
                consoleOutputReaderBuilder.AppendLine(nextLine);
            }

            process.WaitForExit();

            IDEHelper.WriteToOutputWindow(process.StandardError.ReadToEnd());

            ReadTestResults();

            return(new Tuple <string, string>(_testResultsFile, _openCoverResultsFile));
        }
예제 #5
0
        /// <summary>
        /// Discovers all tests in the selected assemblies.
        /// </summary>
        /// <returns></returns>
        public void Discover(Action <List <TestClass> > discoveryDone)
        {
            if (_dlls != null)
            {
                var assemblyPath       = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                var testDiscovererPath = Path.Combine(assemblyPath, "OpenCover.UI.TestDiscoverer.exe");

                if (File.Exists(testDiscovererPath))
                {
                    var builder = new StringBuilder();

                    foreach (var dll in _dlls)
                    {
                        builder.AppendFormat("\"{0}\" ", dll);
                    }

                    if (builder.Length == 0)
                    {
                        return;
                    }

                    StartTestDiscovery(discoveryDone, testDiscovererPath, builder.ToString());
                }
                else
                {
                    IDEHelper.WriteToOutputWindow("{0} not found. OpenCover cannot discover tests", testDiscovererPath);
                }
            }

            return;
        }
예제 #6
0
        /// <summary>
        /// Starts the test discovery by starting the process OpenCover.UI.TestDiscoverer.exe.
        /// </summary>
        /// <param name="discoveryDone">The delegate that needs to be called after test discovery is done.</param>
        /// <param name="testDiscovererPath">The test discoverer path.</param>
        /// <param name="tests">The tests.</param>
        private void StartTestDiscovery(Action <List <TestClass> > discoveryDone, string testDiscovererPath, String testsDLLs)
        {
            List <TestClass> tests    = new List <TestClass>();
            string           pipeGuid = Guid.NewGuid().ToString();
            var pipeServer            = new NamedPipeServerStream(pipeGuid, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous);

            pipeServer.BeginWaitForConnection(res =>
            {
                if (res.IsCompleted)
                {
                    pipeServer.EndWaitForConnection(res);

                    var newTests = ReadObject <OpenCover.UI.Model.Test.TestClass[]>(pipeServer);
                    if (newTests != null && newTests.Length > 0)
                    {
                        tests.AddRange(newTests);
                    }

                    tests.ForEach(TestMethodWrapper => TestMethodWrapper.UpdateChildren());

                    IDEHelper.WriteToOutputWindow("{0} tests found", tests.Sum(test => test.TestMethods != null ? test.TestMethods.Length : 0));
                    discoveryDone(tests);
                }
            }, null);

            var processInfo = new ProcessStartInfo(testDiscovererPath, String.Format("{0} {1}", pipeGuid, testsDLLs))
            {
                CreateNoWindow  = true,
                UseShellExecute = false
            };

            Process.Start(processInfo);
        }
예제 #7
0
        /// <summary>
        /// Starts OpenCover.Console.exe to start CodeCoverage session.
        /// </summary>
        /// <returns>Test results (trx) and OpenCover results files' paths</returns>
        public Tuple <string, string> Execute()
        {
            var     openCoverStartInfo = GetOpenCoverProcessInfo();
            Process process            = Process.Start(openCoverStartInfo);

            var consoleOutputReaderBuilder = new StringBuilder();

            // TODO: See if this loop has any performance bottlenecks
            while (true)
            {
                if (process.HasExited)
                {
                    break;
                }

                string nextLine = process.StandardOutput.ReadLine();
                if (!String.IsNullOrWhiteSpace(nextLine) && nextLine.StartsWith("Results File:"))
                {
                    _testResultsFile = nextLine.Replace("Results File: ", "");
                }

                Debug.WriteLine(nextLine);
                consoleOutputReaderBuilder.AppendLine(nextLine);
            }

            process.WaitForExit();

            Debug.WriteLine(process.StandardError.ReadToEnd());

            IDEHelper.OpenFile(_package.DTE, _testResultsFile);

            return(new Tuple <string, string>(_testResultsFile, _openCoverResultsFile));
        }
예제 #8
0
        private T AddToolWindow <T>() where T : ToolWindowPane
        {
            try
            {
                T toolWindow = FindToolWindow(typeof(T), 0, true) as T;

                ToolWindows.Add(toolWindow);

                if (toolWindow == null || toolWindow.Frame == null)
                {
                    throw new NotSupportedException(Resources.CanNotCreateWindow);
                }
                else
                {
                    ((IVsWindowFrame)toolWindow.Frame).ShowNoActivate();
                }

                return(toolWindow);
            }
            catch (Exception ex)
            {
                IDEHelper.WriteToOutputWindow(ex.Message);
                IDEHelper.WriteToOutputWindow(ex.StackTrace);
            }

            return(null);
        }
 /// <summary>
 /// Initializes the control by adding handlers to BuildDone, SolutionOpened & SolutionClosing events.
 /// </summary>
 /// <param name="package">The package.</param>
 internal void Initialize(OpenCoverUIPackage package)
 {
     _package = package;
     _package.VSEventsHandler.BuildSucceeded  += DiscoverTests;
     _package.VSEventsHandler.BuildFailed     += () => { IDEHelper.WriteToOutputWindow("Build failed. Please make sure your solution builds properly before refreshing this window."); };
     _package.VSEventsHandler.SolutionOpened  += DiscoverTests;
     _package.VSEventsHandler.SolutionClosing += ClearTestsTreeViewChildren;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="ExecuteSelectedTestsCommand"/> class.
 /// </summary>
 /// <param name="package">The Visual Studio Extension Package.</param>
 public ExecuteSelectedTestsCommand(OpenCoverUIPackage package, IVsUIShell uiShell)
     : base(package, new CommandID(GuidList.GuidOpenCoverUICmdSet, (int)PkgCmdIDList.CmdidCoverWithOpenCover))
 {
     this._package         = package;
     this._uiShell         = uiShell;
     this._testTreeControl = IDEHelper.GetTestTreeControl(_uiShell);
     this._testTreeControl.LayoutUpdated += EnableDisableCommand;
     base.Enabled = false;
 }
예제 #11
0
		/// <summary>
		/// Returns the word spans based on covered lines.
		/// </summary>
		/// <param name="snapshot">The text snapshot of file being opened.</param>
		/// <returns>Collection of word spans</returns>
		private List<SnapshotSpan> GetWordSpans(ITextSnapshot snapshot)
		{
			var wordSpans = new List<SnapshotSpan>();

			// If the file was opened by CodeCoverageResultsControl,
			if (_codeCoverageResultsControl != null && _codeCoverageResultsControl.IsFileOpening)
			{
				// Get covered sequence points
				try
				{
					var sequencePoints = _codeCoverageResultsControl.GetActiveDocumentSequencePoints();

					if (sequencePoints != null)
					{
						var covered = false;

						foreach (var sequencePoint in sequencePoints)
						{
							if (sequencePoint.VisitCount == 0)
							{
								covered = false;
							}
							else
							{
								covered = true;
							}

							int sequencePointStartLine = sequencePoint.StartLine - 1;
							int sequencePointEndLine = sequencePoint.EndLine - 1;

							var startLine = snapshot.Lines.FirstOrDefault(line => line.LineNumber == sequencePointStartLine);

							if (sequencePoint.EndLine == sequencePoint.StartLine)
							{
								AddWordSpan(wordSpans, snapshot,
											startLine.Extent.Start.Position + sequencePoint.StartColumn - 1,
											sequencePoint.EndColumn - sequencePoint.StartColumn + 1, covered);
							}
							else
							{
								// Get selected lines
								AddWordSpansForSequencePointsCoveringMultipleLines(snapshot, wordSpans, sequencePoint,
																					sequencePointStartLine, sequencePointEndLine, covered);
							}
						}
					}
				}
				catch (Exception ex)
				{
					IDEHelper.WriteToOutputWindow(ex.Message);
					IDEHelper.WriteToOutputWindow(ex.StackTrace);
				}
			}

			return (wordSpans);
		}
        /// <summary>
        /// Discovers the tests.
        /// </summary>
        private void DiscoverTests()
        {
            System.Threading.Tasks.Task.Factory.StartNew(new Action(() =>
            {
                var potentialTestDLLs = IDEHelper.GetPotentialTestDLLs();
                var testDiscoverer    = new Discoverer(potentialTestDLLs);

                testDiscoverer.Discover(UpdateTreeView);
            }));
        }
 /// <summary>
 /// Gets the coverage infor (sequence points) for the editor's document
 /// </summary>
 /// <returns></returns>
 protected IEnumerable <SequencePoint> GetSequencePointsForActiveDocument()
 {
     // Get the sequence points of the current file
     if (_codeCoverageResultsControl != null && _codeCoverageResultsControl.CoverageSession != null)
     {
         return(_codeCoverageResultsControl.CoverageSession.GetSequencePoints(IDEHelper.GetFileName(_textView)));
     }
     else
     {
         return(new List <SequencePoint>());
     }
 }
예제 #14
0
        /// <summary>
        /// Returns start information to launch OpenCover.Console.exe
        /// </summary>
        /// <returns>Open Cover process start information</returns>
        private ProcessStartInfo GetOpenCoverProcessInfo(string arguments)
        {
            var openCoverStartInfo = new ProcessStartInfo(_openCoverPath, arguments)
            {
                RedirectStandardOutput = true,
                RedirectStandardError  = true,
                UseShellExecute        = false,
                CreateNoWindow         = true,
                WorkingDirectory       = _currentTestWorkingDirectory.FullName
            };

            IDEHelper.WriteToOutputWindow(openCoverStartInfo.Arguments);

            return(openCoverStartInfo);
        }
예제 #15
0
        /// <summary>
        /// Runs OpenCover for gathering code coverage details. This testResult gets called after the build is completed
        /// </summary>
        private void RunOpenCover()
        {
            // TODO: Check validity of tests
            Task.Factory.StartNew(
                () =>
            {
                var control       = _package.GetToolWindow <CodeCoverageResultsToolWindow>().CodeCoverageResultsControl;
                var testsExplorer = _package.GetToolWindow <TestExplorerToolWindow>().TestExplorerControl;

                try
                {
                    control.IsLoading            = true;
                    Tuple <string, string> files = _testExecutor.Execute();
                    var finalResults             = _testExecutor.GetExecutionResults();
                    _testExecutor.UpdateTestMethodsExecution(TestExplorer.Tests);

                    testsExplorer.ChangeGroupBy(TestMethodGroupingField.Outcome);

                    if (finalResults != null)
                    {
                        control.UpdateCoverageResults(finalResults);

                        // if the tool window is hidden, show it again.
                        ShowCodeCoverageResultsToolWindow();
                    }
                    else
                    {
                        control.IsLoading = false;
                    }
                }
                catch (Exception ex)
                {
                    IDEHelper.WriteToOutputWindow(ex.Message);
                    IDEHelper.WriteToOutputWindow(ex.StackTrace);

                    MessageBox.Show(String.Format("An exception occured: {0}\nPlease refer to output window for more details", ex.Message), Resources.MessageBoxTitle, MessageBoxButton.OK);

                    control.IsLoading = false;
                }
                finally
                {
                    Enabled = true;
                    _isRunningCodeCoverage = false;
                }
            });

            _package.VSEventsHandler.BuildDone -= RunOpenCover;
        }
예제 #16
0
        internal override void UpdateTestMethodsExecution(IEnumerable <TestClass> tests)
        {
            var executedTests = tests.SelectMany(t => t.TestMethods)
                                .Join(_execution,
                                      t => new { d = t.Class.DLLPath, n = t.FullyQualifiedName },
                                      t => new { d = t.Item1, n = t.Item2.MethodName },
                                      (testMethod, result) => new { TestMethod = testMethod, Result = result });

            foreach (var test in executedTests)
            {
                test.TestMethod.ExecutionResult = test.Result.Item2;
            }

            if (File.Exists(_testResultsFile))
            {
                IDEHelper.OpenFile(OpenCoverUIPackage.Instance.DTE, _testResultsFile);
            }
        }
예제 #17
0
        /// <summary>
        /// TreeViewItem double click event handler.
        /// Opens the corresponding file if the clicked node represents either a class or a method.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="MouseButtonEventArgs"/> instance containing the event data.</param>
        private void TreeViewItemDoubleClicked(object sender, MouseButtonEventArgs e)
        {
            Method method = null;

            var treeView = sender as ICSharpCode.TreeView.SharpTreeView;

            if (treeView.SelectedItem is ClassNode)
            {
                method = (treeView.SelectedItem as ClassNode).Class.Methods.FirstOrDefault();
            }
            else if (treeView.SelectedItem is MethodNode)
            {
                method = (treeView.SelectedItem as MethodNode).Method;
            }

            if (method != null)
            {
                var sequencePoints = CoverageSession.GetSequencePoints().Where(ig => ig.Key == method.FileRef.UniqueId);

                var coveredFiles = CoverageSession.GetFiles();

                if (coveredFiles != null)
                {
                    try
                    {
                        var file = coveredFiles.FirstOrDefault(f => f.UniqueId == method.FileRef.UniqueId);

                        IDEHelper.CloseFile(_package.DTE, file.FullPath);

                        _fileOpening      = true;
                        _lastSelectedFile = file.FullPath;


                        IDEHelper.OpenFile(_package.DTE, file.FullPath);
                        IDEHelper.GoToLine(_package.DTE, method.SequencePoints.FirstOrDefault().StartLine);
                    }
                    catch { }
                }

                e.Handled = true;
            }
        }
        private void TestsTreeView_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            try
            {
                var treeView     = sender as ICSharpCode.TreeView.SharpTreeView;
                var selectedItem = treeView.SelectedItem;

                var testMethod = selectedItem as TestMethod;
                if (testMethod != null)
                {
                    var fullyQualifiedMethodName = testMethod.FullyQualifiedName;
                    IDEHelper.WriteToOutputWindow("Navigating to test method: {0}", fullyQualifiedMethodName);

                    IDEHelper.OpenFileByFullyQualifiedMethodName(fullyQualifiedMethodName);
                }
            }
            catch (Exception exception)
            {
                IDEHelper.WriteToOutputWindow(exception.Message);
            }
        }
예제 #19
0
        /// <summary>
        /// Executes the post processor.
        /// </summary>
        /// <param name="command">The command.</param>
        /// <param name="resultsFile">The results file.</param>
        private void ExecutePostProcessor(string command, string resultsFile)
        {
            var normalizedCommand = Path.Combine(_currentWorkingDirectory.FullName, command);

            if (System.IO.File.Exists(normalizedCommand) && System.IO.File.Exists(resultsFile))
            {
                if (!String.IsNullOrWhiteSpace(String.Format("cmd /C {0}", normalizedCommand)))
                {
                    var postProcessorInfo = new ProcessStartInfo(normalizedCommand, resultsFile)
                    {
                        RedirectStandardOutput = true,
                        RedirectStandardError  = true,
                        UseShellExecute        = false,
                        CreateNoWindow         = true,
                        WorkingDirectory       = _currentWorkingDirectory.FullName
                    };

                    IDEHelper.WriteToOutputWindow("{0} {1}", command, postProcessorInfo.Arguments);

                    Process process = Process.Start(postProcessorInfo);
                    Debug.Assert(process != null, "process != null");
                    while (!process.HasExited)
                    {
                        var nextLine = process.StandardOutput.ReadLine();
                        IDEHelper.WriteToOutputWindow(nextLine);
                    }

                    process.WaitForExit();

                    IDEHelper.WriteToOutputWindow(process.StandardError.ReadToEnd());
                }
            }
            else
            {
                IDEHelper.WriteToOutputWindow("Cannot find '{0}', when executing on {1}", normalizedCommand, resultsFile);
            }
        }
예제 #20
0
 /// <summary>
 /// Converts a value.
 /// </summary>
 /// <param name="value">The value produced by the binding source.</param>
 /// <param name="targetType">The type of the binding target property.</param>
 /// <param name="parameter">The converter parameter to use.</param>
 /// <param name="culture">The culture to use in the converter.</param>
 /// <returns>
 /// A converted value. If the method returns null, the valid null value is used.
 /// </returns>
 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
 {
     return(IDEHelper.GetImageURL(IDEHelper.GetIcon((TestExecutionStatus)value)));
 }