diff --git a/src/TestCentric/testcentric.gui/Presenters/DisplayStrategy.cs b/src/TestCentric/testcentric.gui/Presenters/DisplayStrategy.cs index a40179b4..4715339a 100644 --- a/src/TestCentric/testcentric.gui/Presenters/DisplayStrategy.cs +++ b/src/TestCentric/testcentric.gui/Presenters/DisplayStrategy.cs @@ -81,12 +81,16 @@ public virtual void OnTestFinished(ResultNode result) { int imageIndex = CalcImageIndex(result.Outcome); foreach (TreeNode treeNode in GetTreeNodesForTest(result)) + { _view.SetImageIndex(treeNode, imageIndex); + UpdateTreeNodeName(treeNode); + } } public virtual void OnTestRunStarting() { _view.ResetAllTreeNodeImages(); + UpdateTreeNodeNames(); } public virtual void OnTestRunFinished() @@ -132,7 +136,8 @@ protected TreeNode MakeTreeNode(TestGroup group, bool recursive) public TreeNode MakeTreeNode(TestNode testNode, bool recursive) { - TreeNode treeNode = new TreeNode(testNode.Name); + string treeNodeName = GetTestNodeDisplayName(testNode); + TreeNode treeNode = new TreeNode(treeNodeName); treeNode.Tag = testNode; int imageIndex = TestTreeView.SkippedIndex; @@ -171,6 +176,46 @@ public string GroupDisplayName(TestGroup group) return string.Format("{0} ({1})", group.Name, group.Count()); } + private string GetTestNodeDisplayName(TestNode testNode) + { + string treeNodeName = testNode.Name; + + // Check if test result is available for this node + ResultNode result = _model.GetResultForTest(testNode.Id); + if (_settings.Gui.TestTree.ShowTestDuration && result != null) + treeNodeName = testNode.Name + $" [{result.Duration:0.000}s]"; + + return treeNodeName; + } + + /// + /// Update all tree node names + /// If setting 'ShowDuration' is active and test results are available, show test duration in tree node. + /// + public void UpdateTreeNodeNames() + { + UpdateTreeNodeNames(_view.Nodes); + } + + private void UpdateTreeNodeNames(TreeNodeCollection nodes) + { + foreach (TreeNode treeNode in nodes) + { + UpdateTreeNodeName(treeNode); + UpdateTreeNodeNames(treeNode.Nodes); + } + } + + private void UpdateTreeNodeName(TreeNode treeNode) + { + TestNode testNode = treeNode.Tag as TestNode; // Update for TestFixture or Testcase nodes only + if (testNode == null) + return; + + string treeNodeName = GetTestNodeDisplayName(testNode); + _view.InvokeIfRequired(() => treeNode.Text = treeNodeName); + } + public static int CalcImageIndex(ResultState outcome) { switch (outcome.Status) diff --git a/src/TestCentric/testcentric.gui/Presenters/ITreeDisplayStrategy.cs b/src/TestCentric/testcentric.gui/Presenters/ITreeDisplayStrategy.cs index b1c9026d..64d567f0 100644 --- a/src/TestCentric/testcentric.gui/Presenters/ITreeDisplayStrategy.cs +++ b/src/TestCentric/testcentric.gui/Presenters/ITreeDisplayStrategy.cs @@ -49,5 +49,11 @@ public interface ITreeDisplayStrategy /// Collapse all tree nodes beneath the fixture nodes /// void CollapseToFixtures(); + + /// + /// Update all tree node names + /// If setting 'ShowDuration' is active and test results are available, show test duration in tree node. + /// + void UpdateTreeNodeNames(); } } diff --git a/src/TestCentric/testcentric.gui/Presenters/TreeViewPresenter.cs b/src/TestCentric/testcentric.gui/Presenters/TreeViewPresenter.cs index e74a467e..bb5515d1 100644 --- a/src/TestCentric/testcentric.gui/Presenters/TreeViewPresenter.cs +++ b/src/TestCentric/testcentric.gui/Presenters/TreeViewPresenter.cs @@ -42,6 +42,7 @@ public TreeViewPresenter(ITestTreeView treeView, ITestModel model, ITreeDisplayS _treeSettings = _model.Settings.Gui.TestTree; _view.ShowCheckBoxes.Checked = _view.CheckBoxes = _treeSettings.ShowCheckBoxes; + _view.ShowTestDuration.Checked = _treeSettings.ShowTestDuration; _view.AlternateImageSet = _treeSettings.AlternateImageSet; WireUpEvents(); @@ -154,6 +155,12 @@ private void WireUpEvents() _view.CheckBoxes = _view.ShowCheckBoxes.Checked; }; + _view.ShowTestDuration.CheckedChanged += () => + { + _treeSettings.ShowTestDuration = _view.ShowTestDuration.Checked; + Strategy?.UpdateTreeNodeNames(); + }; + _view.RunContextCommand.Execute += () => { if (_view.ContextNode != null) diff --git a/src/TestCentric/testcentric.gui/Views/ITestTreeView.cs b/src/TestCentric/testcentric.gui/Views/ITestTreeView.cs index 528ea514..a9fd38b7 100644 --- a/src/TestCentric/testcentric.gui/Views/ITestTreeView.cs +++ b/src/TestCentric/testcentric.gui/Views/ITestTreeView.cs @@ -28,6 +28,7 @@ public interface ITestTreeView : IView ICommand DebugContextCommand { get; } IToolStripMenu ActiveConfiguration { get; } IChecked ShowCheckBoxes { get; } + IChecked ShowTestDuration { get; } ICommand ExpandAllCommand { get; } ICommand CollapseAllCommand { get; } ICommand CollapseToFixturesCommand { get; } diff --git a/src/TestCentric/testcentric.gui/Views/TestTreeView.Designer.cs b/src/TestCentric/testcentric.gui/Views/TestTreeView.Designer.cs index 863eeffa..0b8269f9 100644 --- a/src/TestCentric/testcentric.gui/Views/TestTreeView.Designer.cs +++ b/src/TestCentric/testcentric.gui/Views/TestTreeView.Designer.cs @@ -40,6 +40,7 @@ private void InitializeComponent() this.activeConfigMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.contextMenuSeparator2 = new System.Windows.Forms.ToolStripSeparator(); this.showCheckboxesMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.showTestDurationMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.expandAllMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.collapseAllMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.collapseToFixturesMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -71,6 +72,7 @@ private void InitializeComponent() this.activeConfigMenuItem, this.contextMenuSeparator2, this.showCheckboxesMenuItem, + this.showTestDurationMenuItem, this.expandAllMenuItem, this.collapseAllMenuItem, this.collapseToFixturesMenuItem}); @@ -124,6 +126,13 @@ private void InitializeComponent() this.showCheckboxesMenuItem.Size = new System.Drawing.Size(190, 22); this.showCheckboxesMenuItem.Text = "Show Checkboxes"; // + // showTestDurationMenuItem + // + this.showTestDurationMenuItem.CheckOnClick = true; + this.showTestDurationMenuItem.Name = "showTestDurationMenuItem"; + this.showTestDurationMenuItem.Size = new System.Drawing.Size(190, 22); + this.showTestDurationMenuItem.Text = "Show Test Duration"; + // // expandAllMenuItem // this.expandAllMenuItem.Name = "expandAllMenuItem"; @@ -174,6 +183,7 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem collapseToFixturesMenuItem; private System.Windows.Forms.ImageList treeImages; private System.Windows.Forms.ToolStripMenuItem showCheckboxesMenuItem; + private System.Windows.Forms.ToolStripMenuItem showTestDurationMenuItem; private System.Windows.Forms.ToolStripMenuItem debugMenuItem; private System.Windows.Forms.ToolStripMenuItem activeConfigMenuItem; private System.Windows.Forms.ToolStripSeparator contextMenuSeparator2; diff --git a/src/TestCentric/testcentric.gui/Views/TestTreeView.cs b/src/TestCentric/testcentric.gui/Views/TestTreeView.cs index 8187dc64..4cc69e23 100644 --- a/src/TestCentric/testcentric.gui/Views/TestTreeView.cs +++ b/src/TestCentric/testcentric.gui/Views/TestTreeView.cs @@ -42,6 +42,7 @@ public TestTreeView() DebugContextCommand = new CommandMenuElement(this.debugMenuItem); ActiveConfiguration = new PopupMenuElement(this.activeConfigMenuItem); ShowCheckBoxes = new CheckedMenuElement(showCheckboxesMenuItem); + ShowTestDuration = new CheckedMenuElement(showTestDurationMenuItem); ExpandAllCommand = new CommandMenuElement(expandAllMenuItem); CollapseAllCommand = new CommandMenuElement(collapseAllMenuItem); CollapseToFixturesCommand = new CommandMenuElement(collapseToFixturesMenuItem); @@ -115,6 +116,7 @@ public bool CheckBoxes public ICommand DebugContextCommand { get; private set; } public IToolStripMenu ActiveConfiguration { get; private set; } public IChecked ShowCheckBoxes { get; private set; } + public IChecked ShowTestDuration { get; private set; } public ICommand ExpandAllCommand { get; private set; } public ICommand CollapseAllCommand { get; private set; } public ICommand CollapseToFixturesCommand { get; private set; } diff --git a/src/TestCentric/tests/Presenters/NUnitTreeDisplayStrategyTests.cs b/src/TestCentric/tests/Presenters/NUnitTreeDisplayStrategyTests.cs index 8506ee05..4f8f8d3c 100644 --- a/src/TestCentric/tests/Presenters/NUnitTreeDisplayStrategyTests.cs +++ b/src/TestCentric/tests/Presenters/NUnitTreeDisplayStrategyTests.cs @@ -68,8 +68,121 @@ protected override DisplayStrategy GetDisplayStrategy() { return new NUnitTreeDisplayStrategy(_view, _model); } + + [Test] + public void OnTestRunStarting_ResetAllTreeNodeImages_IsInvoked() + { + // Act + _strategy.OnTestRunStarting(); + + // Assert + _view.Received().ResetAllTreeNodeImages(); + } + + [Test] + public void OnTestRunStarting_UpdateTreeNodeNames_IsInvoked() + { + // Assert + TestNode testNode = new TestNode(""); + var treeNode = _strategy.MakeTreeNode(testNode, false); + _view.InvokeIfRequired(Arg.Do(x => x.Invoke())); + _view.Nodes.Add(treeNode); + + // Act + _strategy.OnTestRunStarting(); + + // Assert + Assert.That(treeNode.Text, Does.Match("Test1")); + } + + [TestCase("Skipped", 0)] + [TestCase("Inconclusive", 1)] + [TestCase("Passed", 2)] + [TestCase("Warning", 3)] + [TestCase("Failed", 4)] + public void OnTestFinished_TreeNodeImage_IsUpdated(string testResult, int expectedImageIndex) + { + // Arrange + TestNode testNode = new TestNode(""); + var treeNode = _strategy.MakeTreeNode(testNode, false); + ResultNode result = new ResultNode($""); + + // Act + _strategy.OnTestFinished(result); + + // Assert + _view.Received().SetImageIndex(treeNode, expectedImageIndex); + } + + [Test] + public void OnTestFinished_ShowDurationIsInactive_TreeNodeName_IsUpdated() + { + // Arrange + TestNode testNode = new TestNode(""); + var treeNode = _strategy.MakeTreeNode(testNode, false); + ResultNode result = new ResultNode($""); + _model.GetResultForTest(testNode.Id).Returns(result); + _view.InvokeIfRequired(Arg.Do(x => x.Invoke())); + + // Act + _strategy.OnTestFinished(result); + + // Assert + Assert.That(treeNode.Text, Is.EqualTo("Test1")); + } + + [Test] + public void OnTestFinished_ShowDurationIsActive_TreeNodeName_IsUpdated() + { + // Arrange + _settings.Gui.TestTree.ShowTestDuration = true; + TestNode testNode = new TestNode(""); + var treeNode = _strategy.MakeTreeNode(testNode, false); + ResultNode result = new ResultNode($""); + _model.GetResultForTest(testNode.Id).Returns(result); + _view.InvokeIfRequired(Arg.Do(x => x.Invoke())); + + // Act + _strategy.OnTestFinished(result); + + // Assert + Assert.That(treeNode.Text, Does.Match(@"Test1 \[1[,.]500s\]")); + } + + [Test] + public void MakeTreeNode_ShowDurationIsActive_TreeNodeName_ContainsDuration() + { + // Arrange + _settings.Gui.TestTree.ShowTestDuration = true; + TestNode testNode = new TestNode(""); + ResultNode result = new ResultNode($""); + _model.GetResultForTest(testNode.Id).Returns(result); + + // Act + var treeNode = _strategy.MakeTreeNode(testNode, false); + + // Assert + Assert.That(treeNode.Text, Does.Match(@"Test1 \[1[,.]500s\]")); + } + + [Test] + public void MakeTreeNode_ShowDurationIsInactive_TreeNodeName_ContainsTestName() + { + // Arrange + _settings.Gui.TestTree.ShowTestDuration = false; + TestNode testNode = new TestNode(""); + ResultNode result = new ResultNode($""); + _model.GetResultForTest(testNode.Id).Returns(result); + + // Act + var treeNode = _strategy.MakeTreeNode(testNode, false); + + // Assert + Assert.That(treeNode.Text, Does.Match(@"Test1")); + } } + //public class NUnitTestListStrategyTests : DisplayStrategyTests //{ // protected override DisplayStrategy GetDisplayStrategy() diff --git a/src/TestCentric/tests/Presenters/TestTree/TreeViewPresenterTests.cs b/src/TestCentric/tests/Presenters/TestTree/TreeViewPresenterTests.cs index c4205da6..03863f79 100644 --- a/src/TestCentric/tests/Presenters/TestTree/TreeViewPresenterTests.cs +++ b/src/TestCentric/tests/Presenters/TestTree/TreeViewPresenterTests.cs @@ -12,6 +12,7 @@ using TestCentric.Gui.Views; using System.Collections.Generic; using System.Linq; +using TestCentric.Gui.Elements; namespace TestCentric.Gui.Presenters.TestTree { @@ -35,6 +36,20 @@ public void WhenSettingsAreChanged_AlternateImageSet_NewSettingIsApplied(string Assert.That(_view.AlternateImageSet, Is.EqualTo(imageSet)); } + [TestCase(false)] + [TestCase(true)] + public void WhenContextMenu_ShowTestDuration_IsClicked_SettingsIsUpdated(bool showTestDuration) + { + // 1. Arrange + _view.ShowTestDuration.Checked = showTestDuration; + + // 2. Act + _view.ShowTestDuration.CheckedChanged += Raise.Event(); + + // 3. Assert + Assert.That(_model.Settings.Gui.TestTree.ShowTestDuration, Is.EqualTo(showTestDuration)); + } + [Test] public void WhenContextMenuIsDisplayed_GuiMiniLayout_TestPropertiesContextMenu_IsVisible() { diff --git a/src/TestCentric/tests/Presenters/TestTree/WhenPresenterIsCreated.cs b/src/TestCentric/tests/Presenters/TestTree/WhenPresenterIsCreated.cs index 63f0e05b..7417a315 100644 --- a/src/TestCentric/tests/Presenters/TestTree/WhenPresenterIsCreated.cs +++ b/src/TestCentric/tests/Presenters/TestTree/WhenPresenterIsCreated.cs @@ -24,6 +24,13 @@ public void ShowCheckBoxesIsSet() _view.ShowCheckBoxes.Received().Checked = showCheckBoxes; } + [Test] + public void ShowTestDurationIsSet() + { + bool showTestDuration = _settings.Gui.TestTree.ShowTestDuration; + _view.ShowTestDuration.Received().Checked = showTestDuration; + } + //[Test] //public void StrategyIsSet() //{ diff --git a/src/TestModel/model/Settings/TestTreeSettings.cs b/src/TestModel/model/Settings/TestTreeSettings.cs index 2c6c69cf..ee2b5c2e 100644 --- a/src/TestModel/model/Settings/TestTreeSettings.cs +++ b/src/TestModel/model/Settings/TestTreeSettings.cs @@ -38,6 +38,12 @@ public bool ShowCheckBoxes set { SaveSetting(nameof(ShowCheckBoxes), value); } } + public bool ShowTestDuration + { + get { return GetSetting(nameof(ShowTestDuration), false); } + set { SaveSetting(nameof(ShowTestDuration), value); } + } + public string DisplayFormat { get { return GetSetting(nameof(DisplayFormat), "NUNIT_TREE"); }