Programatically finding a message box and generating a click on a button - c#

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?

I'd advise treating the underlying disease rather than the symptom.
Take a few minutes to read these
the Humble Dialog box by Michael Feathers
User Interrogator by Tim Haughton
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 ...

codeplex.com/white - Free
testautomationfx.com - Commercial but very good

You probably will have to use WinAPI calls (FindWindowEx, ect) and send a messages of LMB down and up to a button handle.

If you know the caption (and it is unique) you can loop through Application.OpenForms to find it.

One of the best free tools is AutoHotKey.

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..

Related

Capturing Dialog-Windows with SpecFlow

I am fairly new to testing still, but have been using SpecFlow for a a few months. I am not entirely sure if what I am going to ask is possible, but maybe someone will have a suggestion to go about the problem.
Synopsis: My feature file makes a call to a method that creates a dialog window stored in a variable created in that method. The user would then need to fill out the dialog window (it is basically picking a file, and then clicking ok). The rest of the method relies on the information provided by the dialog window.
Problem: Since the window is created in the method and the result is stored in a variable created at that moment, I can not provide my information into the variable. But in order for my behavior tests to finish, I need to provide this information.
Example code:
Feature File:
Given I initialize the class
And I click on change selected item
Steps File:
[Given(#"I initialize the class")]
public void GivenIInitializeTheClass()
{
DoStuff();
SomeClass testClass = new SomeClasee();
}
[Given(#"IClickOnChangeSelectedItem")]
public void GivenIClickOnChangeSelectItem()
{
testClass.ChangeItem();
}
Method From Class:
public void ChangeItem()
{
var window = new SomeDialogWindow();
var result = window.ShowDialog();
if (result.HasValue && result.Value)
{
NewItem = window.SelectedItem;
}
}
I would know how to go about this if I could change the method in the class, but, in this example, I can make no changes to the class itself. Again I do not know if it is possible to assign anything to the result, or control the window since the variables for both are created within the method.
Depending on what you want to do this is quite a common pattern and fairly easy to solve, but first lets consider what kind of testing you might want to be running.
Unit tests - In a unit test that only wants to test the implementation of SomeClass we don't care about the implementation of other classes including SomeDialogWindow. Alternatively we could be writing tests that care solely about the implementation of SomeDialogWindow, or even just the implementation of SomeClass::ChangeItem and nothing else. How fine do you want to go? These tests are there to pinpoint exactly where some of your code is broken.
Acceptance tests - We build these to test how everything works together. They do care about the interaction between different units and as such will show up things that unit tests don't find. Subtle configuration issues, or more complicated interactions between units. Unfortunately they cover huge swathes of code, so leave you needing something more precise to find out what is wrong.
In a Test driven development project, we might write a single acceptance test so we can see when we are done, then we will write many unit tests one at a time, each unit test used to add a small piece of functionality to the codebase, and confirm it works before moving to the next.
Now for how to do it. As long as you are able to modify SomeClass its not a huge change, in fact all you really need is to add virtual to the ChangeItem method to make
public virtual void ChangeItem()
...
What this now allows you do is to replace the method with a different implementation when you are testing it. In the simplest form you can then declare something like,
namespace xxx.Tests
{
public class TestableSomeClass : SomeClass
{
public Item TestItem {get;set;}
public override void ChangeItem()
{
NewItem = TestItem;
}
}
}
This is a very common pattern and known as a stub. We've reduced the functionality in ChangeItem down to its bare essentials so its just a minimal stub of its original intent. We aren't testing ChangeItem anymore, just the other parts of our code.
In fact this pattern this pattern is so common there are libraries there to help us to Mock the function instead. I tend to use one called Moq and it would now look like this.
//Given
var desiredItem = ...
Mock<SomeClass> myMock = new Mock<SomeClass>();
myMock.Setup(x=>x.ChangeItem).Returns(desiredItem);
var testClass = myMock.Object;
//When
testClass.ChangeItem();
//Then
testClass.NewItem.ShouldEqual(....);
You will notice that in both these examples we have gotten rid of the GUI part of the codebase so that we can concentrate on your functionality. I would personally recommend this approach for getting 90% to get your codebase covered and end up with rapid uncomplicated testing. However sometimes you need Acceptance tests that even test the UI, and then we come to an altogether more complicated beast.
For eaxmple, your UI will include blocking calls when it displays the visual elements, such as SomeDialogWindow.ShowDialog() and these have to occur on what is commonly referred to as the UI thread. Fortunately while only one thread can be the UI thread, any thread can be the UI thread if it gets there first, but you will need to have at least one thread displaying the UI and another running the tests. You can steal a pattern from web based testing and create driver classes that control your UI, and these will end up on the test running thread performing the click operations and polling to see if the operations are complete.
If you need to go to these lengths then don't start with this as you learn how to use the testing frameworks, start with the simple stuff.

Creating a message box in C# with custom buttons

Would like to know if it is possible to create a MessageBox with custom buttons similar to what one would achieve with showOptionDialog in java?
String[]colors = {"Red", "Green", "Blue"};
int color = JOptionPane.showOptionDialog(null, "Please choose color", "Color please", 0, JOptionPane.INFORMATION_MESSAGE,null, colors, colors[0]);
if(color == 0)
{
JOptionPane.showMessageDialog(null, "Red it is");
}
What would the equivalent for this be in C#?
I'm afraid that the answer is: you can't.
There is no way to alter the MessageBox as far as I know. You will need to code your own dialog (is not that hard).
Probably the MessageBox class is making a WinApi call at the end and that could be the main reason.
I think this does what you want:
http://snipplr.com/view/14245/custom-messagebox-buttons/
Here is similar approach, in C++, but with more explanation:
http://www.codeproject.com/Articles/10037/How-to-change-the-MessageBox-window-Add-controls-a
NOTE: Just be aware that the WinApi messagebox is optimized to be able to display even under very low memory conditions. So the OS can display messages in a crash or low memory condition.
If you mess with it, like above, you may lose some of that robustness.
I don't think you can. The messagebox class has only private constructor so you can't derive from it. However, as SoMoS already wrote, you could make your own custom message box by using a windows form and its showdialog() method. Hope it helped

List-based publish subscribe pattern in c# (Wordpress hooks / filters)

I come from a PHP background and have used Wordpress quite a lot, I love how their plugin architecture works and the ability to hook events to event names. One of the best parts I like about it is being able to *add_filter()* to any database value just before it gets shown to the end user. My question is multi-part on how to replicate the whole plugin architecture in a C#.NET environment?
Part 1:
To create plug-ins I have researched the MEF framework would probably be the best (Managed Extensibility Framework -http://mef.codeplex.com/). This is designed specifically to take the grunt work out by giving you the ability to monitor directories for new plug-ins, tracking dependencies and other normal things. MEF ships with .NET 3.5+
Part 2
Hooking events? I can't seem to find much information about replicating a global channel based event system. From what I have upto yet I need a publish/subscribe pattern (which isn't that hard to make as you just create some concrete objects and give them events). The hard part is giving each event a 'channel' name and for all the events in the whole system to be part of a global collection (Mediator pattern).
To replicate: (http://codex.wordpress.org/Function_Reference/add_filter)
Example 1
// Add's my button to the end of the content
add_filter('the_content', 'my_plugin_button');
function my_plugin_button( $content ) {
// Add's my button to the end of the content
return $content . "<a href='#'>My button</a>";
}
OR
Example 2
// Add a new admin menu item by hooking in
add_action('admin_menu', 'my_plugin_menu');
function my_plugin_menu() {
add_options_page('My Plugin Options', 'My Plugin', 'manage_options', 'my-unique-identifier', 'my_plugin_options');
}
I hope your all with me upto yet? I have managed to replicate the functionality I need in Javascript and even jQuery has their .on() event function... same thing but channel or list based...
My 2 examples:
http://jsfiddle.net/AaronLayton/U3ucS/53/
http://jsfiddle.net/AaronLayton/eyNre/33/
Can anyone point me in the correct direction or is this the totaly wrong approach for c#?
I think NServiceBus can help you a lot with these issues. Udi Dahan which is the author of NServiceBus has also written a lot of articles about Domain Event pattern, which is a publish/subscribe mechanism.
Know it's been a long time since you posted this and you probably built something already. However I have been thinking about something like this myself. There are 2 options - really forget WordPress and try and build something much cleaner - it's a mess at the bottom of WordPress' code :D
Or this:
function the_content()
{
var result = get_the_content();
// do other stuff...if you want to.
execute_filters(ref result);
execute_actions(ref result);
return result;
}
function execute_filters(ref string result, string action_name)
{
var filters = get_pre_filters(action_name);
filters.ForEach(filter =>
{
/// somehow call the method name in filter. PHP is generally global. C# namespaced,
/// so you would need to think about that.
}
}
function execute_actions(ref string result, string action_name)
{
/// and so on....
}
When building something to mimic WordPress, you need to remember many of the issues of WordPress' plugin architecture (in my personal opinion)... It seems to want to run every plugin near enough on every page even if that page has nothing to do with that plugin. I onced installed a plugin that added 60 database queries to each page call, and it wasn't used.
Try and think smart about it when you are building it. Try and add a way to only have the plugins that are going to get used on the page/post of your new setup to be run e.g. in your database have a "Plugins" field on the post/page object with a list of plugins allowed to run on that page. That way you won't need to check all the plugins each time to see if it wants to run.
Anyways. Hope you got something working.

How to create IDLE -like functionality to WinForms application

I'd like to add "IDLE-like functionality" to C# WinForms application, but I don't quite have an idea how to do that and couldn't find anything useful with Google.
So basically I want interactive command line interface, where user could enter some Python code and execute it (not just expressions, should be possible to define new functions).
So, where to start? Are there any good tutorials or samples available?
If my memory serves me correctly there's a chapter on embedding Python in the book Python in a Nutshell. Perhaps you can find some useful information there, but since the book is not Windows specific, you may have to adapt it yourself.
I would setyp my WinForm like this: add 2 textboxes.
1: for output. Set the multiline property of the first to true, and make it read only.
2: for input. Use KeyUp Or KeyPress Event for e.g. the return key and use the text to do what you want: add command to output textbox, launch code against the engine and capture output of interpreter
This link (http://groups.google.com/group/ironpy/browse_thread/thread/5e61a944c7c94d4b/0cbf29ec0f5fbb64?pli=1) might give some answers about launching commands agains a python engine.
IronRuby comes with a command line interpreter. Doesn't IronPython also have one? If so, the source code would be a good start :)
Oh, and if it doesn't, be sure to look at the IronRuby interpreter, because both languages are based on the DLR and are therefore similar enough to learn from both.
Thru IronPython mailing list I found IronTextBox2, which is good example how things are done. It needs a little tweaking, to get it running, but otherwise is good solution.
Here go my most generic solution:
Point cursorPoint;
int minutesIdle=0;
private bool isIdle(int minutes)
{
return minutesIdle >= minutes;
}
private void idleTimer_Tick(object sender, EventArgs e)
{
if (Cursor.Position != cursorPoint)
{
// The mouse moved since last check
minutesIdle = 0;
}
else
{
// Mouse still stoped
minutesIdle++;
}
// Save current position
cursorPoint = Cursor.Position;
}
You can setup a timer running on 60000 interval. By this way you will just know how many minutes the user don't move the mice. You can also call "isIdle" on the Tick event itself to check on each interval.

lightweight instrumentation for winforms app

I have a winforms app and i want to keep track of every time a user clicks certain buttons, etc as well as other actions. What is the best way for me to keep track of this information and then put it together so i can run metrics on most used features, etc.
This is a winforms app and I have users around the world.
There are 2 big issues your design has to be sure to address
Privacy (what Don alluded to) - You must be crystal clear what information you are collecting and sending up to your central server, ideally the users should be able to inspect the exact data you are sending back to the central server (if they wish to) - For any public software there should be a very easy way to opt out.
Performance and Scalability - You have to estimate how much data you really need on the server side and look at all sort of tricks that aggregate and compress the data client side (as well as have hard limits on the amount of traffic you will be sending and how often you will be sending it)
As to the client side implementation, I would recommend investigating Sqlite.net or another embedded DB. Using an embedded DB to store this information on the client will give you lots of flexibility with aggregations and will have the advantage of being transactional, fast and simple to implement. Sqlite has a very generous public domain license so from a legal perspective its really easy to use in public apps.
Try doing a google scholar search. There are some interesting ideas by Ben Liblit and co-authors, and another series of ideas by Alex Orso and co-authors (disclaimer - I'm one of Alex Orso's co-authors) based on taking a sample of runtime information from each user, and putting it together in an interesting way.
http://theory.stanford.edu/~aiken/publications/papers/pldi03b.pdf
and
http://www.cs.umd.edu/class/fall2006/cmsc838p/Ramss/remoteClassJournal.pdf
are two (not necessarily the best) examples of such papers/ideas.
I'd try something like this:
// execute this method once all forms have been created
public static void HookButtons()
{
foreach( Form f in Application.OpenForms )
{
EnumerateControls( f.Controls );
}
}
public static void EnumerateControls( ICollection controls )
{
foreach( Control ctrl in controls )
{
if( ctrl.Controls.Count > 0 )
{
EnumerateControls( ctrl.Controls );
}
if( ctrl is ButtonBase )
{
ctrl.MouseClick +=new MouseEventHandler( ctrl_MouseClick );
}
}
}
static void ctrl_MouseClick( object sender, MouseEventArgs e )
{
ButtonBase clicked = ((ButtonBase)sender);
// do something with the click information here
}
Be careful how you handle this. Some companies have gotten user backlash from collecting too much information or not being clear what was collected. The safest way is to ask the user before enabling any "phone home" features. Allowing the user to see the actual data before you send it seems good, too.
I've wondered if there's some way to piggyback on the one-click deployment call that happens whenever a one-click app starts up and checks for updates. I haven't investigated yet, though.
As for collecting the actual numbers, perhaps the user settings are the easiest place. If you're not familiar with them, just check out the project properties and go to the Settings tab.

Categories

Resources