Reputation: 36679
I am trying to automate testing of a winform application. I am running it in the same process as the test code, so it is fairly easy to find the .Net controls and simulate user action on them. I got however stuck a bit with a message box (created using the standard MessageBox.Show method). How can I get hold of it and simulate that a button is pressed?
Upvotes: 3
Views: 3352
Reputation: 12711
While it's true (as some users suggested) that for Unit testing and even integration testing you should rather try to design the code in a way that you shouldn't have to deal in the testing process with the MessageBox.
However in functional and end to end testing you would most probably indeed be interested in testing the actual message box as well.
You can nowadays use many different libraries to perform this (I understand that this question is very old already, but StackOverflow is actually meant for anyone in the future as well).
Here is sample code using the FlaUI.UI3 library (code is based on FlaUI own test code but modified):
using var automation = new UIA3Automation();
var desk = automation.GetDesktop();
var searchFunc = () => desk.FindFirstChild(cf =>
cf.ByProcessId(Process.GetCurrentProcess().Id)
// This is the className for the windows MessageBox
.And(cf.ByClassName("#32770")))
.AsWindow();
var msgBox = Retry.WhileNull(searchFunc, TimeSpan.FromSeconds(10)).Result;
msgBox.Should().NotBeNull();
var buttonName = "OK"; // Assuming the button you wish is the OK button
var yesButton = msgBox.FindFirstChild(cf => cf.ByName(buttonName )).AsButton();
yesButton.Should().NotBeNull();
yesButton.Invoke();
Upvotes: 0
Reputation: 4259
You can use autoit script system.
But i am suggest to separate the GUI and implementation, because basic principle of unit testing is "unit", where unit is class that separated from other classes or real world.
This principle give you good class design and help to avoid software eruption and lot of other good stuff..
Upvotes: 0
Reputation: 136673
I'd advise treating the underlying disease rather than the symptom. Take a few minutes to read these
In short, use an interface to separate out all modal dialog pop-ups - which are a pain in the neck for UI test automation. You can then substitute a mock implementation of the interface that does nothing or returns predetermined test values. The real implementation of course pops up the actual dialog modally... something like this (from the 2nd link)
public class UserInterrogator : IUserInterrogator
{
private Form owner;
public UserInterrogator(Form owner)
{ this.owner = owner; }
public Font GetFontFromUser() // member of the IUserInterrogator interface
{
FontDialog fd = new FontDialog();
fd.ShowDialog( owner );
return fd.Font;
}
}
The easier approach is of course to write some code that finds the dialog and closes/kills it. I've seen some people have some success with Win32 APIs and NUnitForms ...
Upvotes: 6
Reputation: 273784
If you know the caption (and it is unique) you can loop through Application.OpenForms to find it.
Upvotes: 2
Reputation: 1585
You probably will have to use WinAPI calls (FindWindowEx, ect) and send a messages of LMB down and up to a button handle.
Upvotes: 2
Reputation: 61893
codeplex.com/white - Free
testautomationfx.com - Commercial but very good
Upvotes: 3