GUI interface testing using NUnit.Forms - c#

I'm trying to write some tests for testing GUI interface. I decided to choose NUnit.Forms. But the tests fall with the following error:
TearDown : System.ComponentModel.Win32Exception : The requested resource is in use
I have two versions of the source code tests.
First:
using System.Windows.Forms;
using NUnit.Extensions.Forms;
using NUnit.Framework;
using YAMP;
namespace Tests.GUITests
{
[TestFixture]
public class GuiTest : NUnitFormTest
{
private FrmMain _frm;
//[SetUp] // or it is still needed
public override void Setup()
{
base.Setup();
_frm = new FrmMain();
_frm.Show();
}
[Test]
public void TestData()
{
var txtInput = new TextBoxTester("txtInput") {["Text"] = "2+2"};
var txtOutput = new TextBoxTester("txtOutput");
Assert.AreEqual("2+2", txtInput.Text);
var btnRes = new ButtonTester("btnRes");
btnRes.Click();
Assert.AreEqual("4", txtOutput.Text);
}
}
}
Second:
using System.Windows.Forms;
using NUnit.Extensions.Forms;
using NUnit.Framework;
using YAMP;
namespace Tests.GUITests
{
[TestFixture]
public class GuiTest : NUnitFormTest
{
private FrmMain _frm;
//[SetUp] // or it is still needed
public override void Setup()
{
base.Setup();
_frm = new FrmMain();
_frm.Show();
}
[TearDown]
public override void TearDown()
{
_frm.Close();
_frm.Dispose();
}
[Test]
public void TestData()
{
var txtInput = new TextBoxTester("txtInput") {["Text"] = "2+2"};
var txtOutput = new TextBoxTester("txtOutput");
Assert.AreEqual("2+2", txtInput.Text);
var btnRes = new ButtonTester("btnRes");
btnRes.Click();
Assert.AreEqual("4", txtOutput.Text);
}
}
}
And there are two different versions of the method TestNoData:
public void TestFormNoDataHandler()
{
var messageBoxTester = new MessageBoxTester("Message");
messageBoxTester.ClickOk();
}
[Test]
public void TestNoData()
{
ExpectModal("Message", TestFormNoDataHandler);
var txtInput = new TextBoxTester("txtInput") {["Text"] = string.Empty};
Assert.AreEqual(string.Empty, txtInput.Text);
var btnRes = new ButtonTester("btnRes");
btnRes.Click();
Assert.IsFalse(_frm.DialogResult == DialogResult.OK);
}
[Test]
public void TestNoData()
{
var txtInput = new TextBoxTester("txtInput") {["Text"] = string.Empty };
Assert.AreEqual(string.Empty, txtInput.Text);
var btnRes = new ButtonTester("btnRes");
btnRes.Click();
Assert.IsFalse(_frm.Enable);
}
Testable form is very simple. There are two TextBox - "txtInput", "txtOutput" and button - "btnRes". In "txtInput" introduced a mathematical expression, and "txtOutput" output response. The decision of expression occurs when you press "btnRes". If the field "txtInput" empty, the button is disabled and you can not click on it.
When searching for solutions to this problem came on the following links:
AutomaticChainsaw: WinForms testing using NUnitForms
c# - I need to create a windows form from within a NUnit test - Stack Overflow
Unfortunately I can attach only 2 links. But the information I learned is very different. Especially the part of writing methods Setup and TearDown.
In any case, I specify the version I use:
Visual Studio 2015 Community
NUnit - 2.6.4.14350
NUnitForms - 1.3.1771.29165
Because it seems to me that the problem might be too recent versions of frameworks, as article I learned quite old.
Thank you for any suggestion.

UseHidden Property: Tests are run on a separate hidden desktop. This makes them much faster and it works for any tests that are not using the keyboard or mouse controllers. They are less disruptive and input tests cannot interfere with other applications.
UseHidden property controls whether a separate desktop is used at all.
Though tests on the separate desktop are faster and safer (There is no danger of keyboard or mouse input going to separate running applications.), however for some operating systems or environments the separate desktop does not work. And the tests throw up errors like:
System.ComponentModel.Win32Exception : The requested resource is in use
--TearDown
at NUnit.Extensions.Forms.Desktop.Destroy()
at NUnit.Extensions.Forms.Desktop.Dispose()
at NUnit.Extensions.Forms.NUnitFormTest.Verify()
In that case you can override UseHidden property from test class and set it to return false. This will cause the tests to run on original, standard desktop.

Related

C# COM events are not fired

I am trying to fetch events from the TaiPan Realtime COM server. I am able to extract other data from there. Accessing keys is working correctly.
But when i try to fetch events, the function is not fired somehow. Hopefully this is a small mistake. For better readability i made a small test code, which is easyer to read for you. After adding those ids to the Stream the Visual Basic debugger is working and it show cpu activity for com_test.
So i gues events are there but i made mistake in eventhandling somehow.
Thanks for help.
using System;
using System.Collections.Generic;
using TaiPanRTLib;
namespace com_test
{
class Program
{
static void Main(string[] args)
{
var handle = new handle();
handle.start();
Console.ReadLine();
}
}
public class handle
{
public int counter;
// this is a list contains the internal numbers of the taipan Software
public static List<int> numbercodes = new List<int>(new int[] { 78379670, 78379685, 78379692, 78379669, 78379729, 78379672, 78379674, 78379698, 78379682, 78379681, 78379704, 78379689, 78379694, 78379673, 78379697, 78379687, 78379702, 78379690, 78379668, 78379671, 78379715, 78379666, 78379706, 78379727, 78379679, 127289939, 78379677, 78379693, 78379676, 78379678, 78379680, 78379688, 78379726, 78379686, 78379696, 78379675, 78379667, 78379703, 78379691, 78379684, 78379700, 78379699, 78379705, 78379695, 78379701, 78379664, 78379716, 78379982, 78379665, 78379707, 78379728, 78379717, 78379719, 7837971 });
void TPRTDataStream_Bezahlt(int SymbolNr, float Kurs, float Volume, DateTime Zeit)
{
Console.WriteLine("peng"); // never see this in window - so not fired?
counter += 1;
}
public void start()
{
TaiPanRealtime TPRTObject = new TaiPanRealtime(); // connects to launches Application
DataStream TPRTDataStream = (DataStream)TPRTObject.DataStream; // attach to the DataStream Object.
foreach (int db_num in numbercodes)
{
TPRTDataStream.Add(db_num, 0); // This adds the internal dbnumber to the Stream
}
TPRTDataStream.Bezahlt+=new _IDataStreamEvents_BezahltEventHandler(TPRTDataStream_Bezahlt);
while (true)
{
Console.WriteLine(counter); // counter stays 0 all the time
System.Threading.Thread.Sleep(1000);
};
}
}
}
I want to post the solution TaiPan service found out. To handle the events correctly you need to set "Embed Interop Types" to false in the reference properties of visual basic. here is a screenshot:
screenshot properties
hope this helps others.

Dynamically create executing code in C#

So, I have strange question (maybe so stupid), but...
So, my task.
I have same class which gives me same functionality. So, in the main program, which I realize (yes, it's client-server app)) , I want to dynamically create ".exe wrapper" for this class - simplest code like this:
class Program
{
private SameClass mySameClass;
static void Main(string[] args)
{
mySameClass = new mySameClass(args);
Console.Readline();
}
}
In general, I want to create main app which creates slaves in the independent proccesses via dynamically code generation.
So, how to make it and control it?
Thank you.
So SameClass is supposed to contain the same functions and functionality as the process you want to have run multiple times... I guess what you need are Threads.
Not too sure what you mean by dynamically but let's say you have an event that triggers whenever you need a new SameClass process. Just run
SameClass newClone = new SameClass(args);
Trhead _thread = new Thread(new ThreadStart(newClone.Start));
_trhead.Start();
You can probably do this a little more elegant and refactor within SameClass but it's pretty hard to understand your question, so I guess this is the best I can do you hopefully answer your question.
Found solution based on CodeDom. Yes, It doesn't need reflection, sorry.
Code example:
using System;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Diagnostics;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
var compiler = new CSharpCodeProvider();
var parameters = new CompilerParameters(new[] { "mscorlib.dll", "System.Core.dll" }, "foo.exe", true);
parameters.CompilerOptions = "/platform:x64";
parameters.GenerateExecutable = true;
CompilerResults results = compiler.CompileAssemblyFromSource(parameters,
#"using System;
class Program {
public static void Main(string[] args) {
Console.WriteLine(""Hello world!"");
Console.ReadLine();
}
}");
var testProcess = new Process();
testProcess.StartInfo.FileName = results.CompiledAssembly.CodeBase;
testProcess.Start();
Console.WriteLine("I've run slave!");
Console.ReadLine();
}
}
}

How do i read the Title property of a GDK.Window

I'm converting an .NET Windows application for Mono to run on Linux (Ubuntu). One of the features depends on a native library (user32.dll). The Mono guide that talks about conversion of applications (Linux Platform Differences) suggests that one approach would be to modify this code.
I'm trying to use GDK to access the Title of a Gdk.Window that I had access through the property Gdk.Global.ActiveWindow. But I found this error at compile time:
Error CS0154: The property or indexer `Gdk.Window.Title` cannot be used in this context because it lacks the `get` accessor (CS0154) (GetActiveWindow)
If i remove the code that reads de Title property of activeW, everything works fine. There is another way to read this property?
Here my unit of work:
using System;
using Gtk;
using Gdk;
using System.Threading;
namespace GetActiveWindow
{
class GdkApp : Gtk.Window
{
public static void Main ()
{
Application.Init ();
new GdkApp ();
Application.Run ();
}
public GdkApp () : base("Simple App")
{
SetDefaultSize (150, 150);
ShowAll();
while (true) {
var activeW = Gdk.Global.ActiveWindow;
Console.WriteLine("Active Window: {0}",activeW.Title); // Where my compile error happens.
Console.WriteLine("Simple App Window: {0}",this.Title); // This code works perfectily.
Thread.Sleep(1000);
}
}
}
}
I think that with Gdk is imposible. Try it with Wnck library giving to a C compiler this '-DWNCK_I_KNOW_THIS_IS_UNSTABLE' and works but with a warning: Unhandled action type _OB_WM_ACTION_UNDECORATE
Sorry I have used genie instead vala.
//valac *.gs --pkg gtk+-3.0 --pkg libwnck-3.0 -X '-DWNCK_I_KNOW_THIS_IS_UNSTABLE'
init
Gtk.init(ref args)
var ventana= new win()
ventana.inicio()
ventana.printinfo()
Gtk.main()
class win:Gtk.Window
won:weak GLib.List of Wnck.Window
def inicio()
var button= new Gtk.Button()
button.clicked.connect(printinfo)
this.add(button)
this.show_all()
def printinfo()
won= Wnck.Screen.get_default().get_windows()
won.foreach(allwin)
def allwin(w:Wnck.Window)
if w.is_skip_tasklist() or w.is_skip_pager()
pass
else
print w.get_name()

TDD - Using properties to auto-generate code

I am practicing TDD using MsTest together with RhinoMocks, and I am trying to be as lazy as humanly possible, i.e. make use of VS2012 auto-generation wherever I can. But it doesn't always feel right to create an entire test method with the Arrange-Act-Assert methodology, just to set up my class and its constructors and properties.
Currently, I find it easiest to create some properties in my test class - even if I don't use them - solely for the purpose of code generation. My question is, is this a bad habit, and is there a better/easier way to do it? Any commentary, good or bad is welcome; Thank you!
[TestClass]
public class MainViewModelTest
{
private MainViewModel MainViewModel
{
get
{
var facilityDataEntity = MockRepository.GenerateStub<FacilityDataEntity>();
var viewModel = new MainViewModel(facilityDataEntity)
{
FacilityValue = string.Empty,
FacilityLabel = string.Empty
};
return viewModel;
}
}
private MainViewModel MainViewModelWithFacilityAndShopOrderData
{
get
{
var facilityDataEntity = MockRepository.GenerateStub<FacilityDataEntity>();
var shopOrderDataEntity = MockRepository.GenerateStub<ShopOrderDataEntity>();
var viewModel = new MainViewModel(facilityDataEntity, shopOrderDataEntity)
{
FacilityValue = string.Empty,
FacilityLabel = string.Empty,
ShopOrder = 99999999,
RequiredQuantity = 0M,
ItemCode = string.Empty,
ItemDescription = string.Empty
};
return viewModel;
}
}
[TestMethod]
public void MainViewModel_TranslateDataEntityListMethodReturnsMainViewModelRecords()
{
// Arrange
var facilityDataEntityList = MockRepository.GenerateStub<IEnumerable<FacilityDataEntity>>();
var shopOrderDataEntityList = MockRepository.GenerateStub<IEnumerable<ShopOrderDataEntity>>();
// Act
IEnumerable<MainViewModel> facilityResults = MainViewModel.TranslateDataEntityList(facilityDataEntityList);
IEnumerable<MainViewModel> shopOrderResults = MainViewModel.TranslateDataEntityList(facilityDataEntityList, shopOrderDataEntityList);
// Assert
Assert.IsInstanceOfType(facilityResults, typeof(IEnumerable<MainViewModel>));
Assert.IsInstanceOfType(shopOrderResults, typeof(IEnumerable<MainViewModel>));
}
}
It's not wrong to wrap up common code within your test classes, but I would avoid potentially sharing state between your tests.
There are two approaches you can use here.
Class/Test Initialization
As Peter mentions in his comments, it's easy enough to include initialization methods to do this sort of stuff for you.
//Only runs once per test run
[ClassInitialize]
public void InitClass(){
//Ideally this should be reserved for expensive operations
// or for setting properties that are static throughout
// the lifetime of your test.
}
//Runs for every test
[TestInitialize]
public void TestInit(){
//Here you can setup common stub/mock behavior
// that will be common for every test, but ensure
// it is clean for each test run
}
Setup/Factory Methods
Another option is to create specialized setup or factory methods that can be used to reduce repeated test code and make the intent of your test clearer.
[TestMethod]
public void ShouldFailIfUserNameIsTed(){
var user = SetupUserScenario("Ted");
var result = _myUserService.Validate(user);
Assert.IsFalse(result);
}
private User SetupUserScenario(String username){
var user = new User();
user.Name = username;
//Do a bunch of other necessary setup
return user;
}
Hopefully this all makes sense, but I would also caution you not to go too crazy with this. If you put too much stuff into setup methods, then your tests will be less clear. You should be able to read the test and figure out what is going on without having to inspect a bunch of other places in the code.
That's what the ClassInitialize functionality is for. I would choose expected and recommended means of doing something before anything else. It's more easily recognizable and takes less time to grok the code.

How to find places in code that must be covered with unit tests

I know it's not so good to write tests after you actually wrote code. I'm unit-testing newbie and feel that unit-testing may deliver many good advantages so I obsessed with an idea to cover as much as possible.
For instance, let we have this code:
public class ProjectsPresenter : IProjectsViewObserver
{
private readonly IProjectsView _view;
private readonly IProjectsRepository _repository;
public ProjectsPresenter(IProjectsRepository repository, IProjectsView view)
{
_view = view;
_repository = repository;
Start();
}
public void Start()
{
_view.projects = _repository.FetchAll();
_view.AttachPresenter(this);
}
}
So looking on code above could you answer me what tests typically I should write on that piece of the code above?
I'm rolling on write tests on constructor to make sure that repository's FetchAll was called and on the view site AttachPresenter is called.
POST EDIT
Here is a my view interface:
public interface IProjectsView
{
List<Project> projects { set; }
Project project { set; }
void AttachPresenter(IProjectsViewObserver projectsPresenter);
}
Here is a view:
public partial class ProjectsForm : DockContent, IProjectsView
{
private IProjectsViewObserver _presenter;
public ProjectsForm()
{
InitializeComponent();
}
public Project project
{
set
{
listBoxProjects.SelectedItem = value;
}
}
public List<Project> projects
{
set
{
listBoxProjects.Items.Clear();
if ((value != null) && (value.Count() > 0))
listBoxProjects.Items.AddRange(value.ToArray());
}
}
public void AttachPresenter(IProjectsViewObserver projectsPresenter)
{
if (projectsPresenter == null)
throw new ArgumentNullException("projectsPresenter");
_presenter = projectsPresenter;
}
private void listBoxProjects_SelectedValueChanged(object sender, EventArgs e)
{
if (_presenter != null)
_presenter.SelectedProjectChanged((Project)listBoxProjects.SelectedItem);
}
}
POST EDIT #2
This is how I test interaction with repository. Is everything allright?
[Test]
public void ProjectsPresenter_RegularProjectsProcessing_ViewProjectsAreSetCorrectly()
{
// Arrange
MockRepository mocks = new MockRepository();
var view = mocks.StrictMock<IProjectsView>();
var repository = mocks.StrictMock<IProjectsRepository>();
List<Project> projList = new List<Project> {
new Project { ID = 1, Name = "test1", CreateTimestamp = DateTime.Now },
new Project { ID = 2, Name = "test2", CreateTimestamp = DateTime.Now }
};
Expect.Call(repository.FetchAll()).Return(projList);
Expect.Call(view.projects = projList);
Expect.Call(delegate { view.AttachPresenter(null); }).IgnoreArguments();
mocks.ReplayAll();
// Act
ProjectsPresenter presenter = new ProjectsPresenter(repository, view);
// Assert
mocks.VerifyAll();
}
I know it's not so good to write tests after you actually wrote code
It's better than not writing tests at all.
Your method works with two external components and that interaction should be verified (in addition to mentioned arguments validation). Checking whether FetchAll was called gives you no value (or checking it returns something - this belongs to ProjectsRepository tests itself) - you want to check that view's projects are set (which will indirectly check whether FetchAll was called). Tests you need are:
verify that view projects are set to expected value
verify that presenter is attached
validate input arguments
Edit: example of how you would test first case (projects are set)
// "RegularProcessing" in test name feels a bit forced;
// in such cases, you can simply skip 'conditions' part of test name
public void ProjectsPresenter_SetsViewProjectsCorrectly()
{
var view = MockRepository.GenerateMock<IProjectView>();
var repository = MockRepository.GenerateMock<IProjectsRepository>();
// Don't even need content;
// reference comparison will be enough
List<Project> projects = new List<Project>();
// We use repository in stub mode;
// it will simply provide data and that's all
repository.Stub(r => r.FetchAll()).Return(projects);
view.Expect(v => v.projects = projects);
ProjectsPresenter presenter = new ProjectsPresenter(repository, view);
view.VerifyAllExpecations();
}
In second case, you'll set expectations on view that its AttachPresenter is called with valid object:
public void ProjectsPresenter_AttachesPresenterToView()
{
// Arrange
var view = MockRepository.GenerateMock<IProjectView>();
view.Expect(v => v.AttachPresenter(Arg<IProjectsViewObserver>.Is.Anything));
var repository = MockRepository.GenerateMock<IProjectsRepository>();
// Act
var presenter = new ProjectsPresenter(repository, view);
// Assert
view.VerifyAllExpectations();
}
I would add simple tests at start , like:
null reference checks
FetchAll() returns any value
Do not add a lot of test code at first time, but refine them after as your dev code mutates.
I would add tests for exception e.g. ArgumentException, corner cases and usual ones of FetchAll().
PS. Does start have to be public?
Pex is an interesting tool that's worth checking out. It can generate suites of unit tests with high code coverage: http://research.microsoft.com/en-us/projects/pex/. It doesn't replace your own knowledge of your code - and which test scenarios are more important to you than others - but it's a nice addition to that.
The purpose of writing tests before writing production code is first and foremost to put you (the developer) in the mind-set of "how will i know when my code works?" When your development is focused on what the result of what working code will look like and not the code itself you are focused on the actual business value obtained by your code and not extraneous concerns (millions of man hours have been spent building and maintaining features users never asked for, wanted, or needed). When you do this you are doing "test driven development".
If you are doing pure TDD the answer is 100% code coverage. That is you do not write a single line of production code that is not already covered by a line of unit test code.
In Visual Studio if you go to Test->Analyze Code Coverage it will show you all of the lines of code that you do not have covered.
Practically speaking its not always feasible to enforce 100% code coverage. Also there are some lines of code that are much more important then others. Determining which depends once again on the business value provided by each line and the consequence of that line failing. Some lines (like logging) may have a smaller consequence then others.

Categories