welcome to Qijie's Blog 薛其杰

When doing UI testing of Win Form with .NET, there is an easy way to automate it. It is reflection in .NET.

There is a tool integrated in VSTS, named Spy++, using it you can get any win form caption in your desk.

Following are the code for UI testing by reflection, key code refered <<.NET Test Automation Recipes: A problem-Solution Approach>>, all codes Copyright by Qijie Xue(v-qixue@microsoft.com)

 

using System;
using System.Threading;
using System.Reflection;
using System.Windows.Forms;
using System.Text;

namespace WinFC
{
    
/// <summary>
    
/// Qijie Xue
    
/// Writed at 8/13/2011
    
/// </summary>
    public class FormClass
    {
        
static AutoResetEvent are = new AutoResetEvent(false);
        
const BindingFlags bindFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;

        
#region get, set, invoke methods
        
/// <summary>
        
/// Get Form property
        
/// </summary>
        
/// <param name="theForm">the form you want to get property</param>
        
/// <param name="propertyName">the property name of the form</param>
        
/// <returns>the value for the property of the form</returns>
        delegate object getFormPropertyHandler(Form theForm, string propertyName);
        
public object GetFormPropertyByPropertyName(Form theForm, string propertyName)
        {
            
if (theForm == null)
                
return null;
            
if (theForm.InvokeRequired)
            {
                getFormPropertyHandler phandler 
= new getFormPropertyHandler(GetFormPropertyByPropertyName);
                
object result = null;
                
object[] oparams = new object[] {theForm , propertyName};
                result 
= theForm.Invoke(phandler, oparams );
                are.WaitOne();
                
return result;
            }
            
else
            {
                
object result = null;
                Type t 
= theForm.GetType();
                PropertyInfo pi 
= t.GetProperty(propertyName);
                
if (pi == null)
                {
                    are.Set();
                    
return null;
                }
                
else
                {
                    result 
= pi.GetValue(theForm, null);
                    are.Set();
                    
return result;
                }
            }
        }

        
/// <summary>
        
/// Set Form Property
        
/// </summary>
        
/// <param name="theForm">the form you want to set property</param>
        
/// <param name="propertyName">the propery name of form</param>
        
/// <param name="newValue">the new value of this propery you want to set</param>
        delegate void setFormPropertyHandler(Form theForm, string propertyName, object newValue);
        
public void SetFormPropertyByPropertyName(Form theForm, string propertyName, object newValue)
        {
            
if (theForm == null)
                
return;
            
if (theForm.InvokeRequired)
            {
                setFormPropertyHandler setHandler 
= new setFormPropertyHandler(SetFormPropertyByPropertyName);
                
object oparams = new object[] { theForm, propertyName, newValue };
                theForm.Invoke(setHandler, oparams);
                are.WaitOne();
            }
            
else
            {
                Type t 
= theForm.GetType();
                PropertyInfo pi 
= t.GetProperty(propertyName);
                
if (pi == null)
                {
                    are.Set();
                    
return;
                }
                
else
                {
                    
try
                    {
                        pi.SetValue(theForm, newValue, 
null);
                    }
                    
catch
                    {
                        
//it's a invalid value for this property
                        return;
                    }
                    
finally
                    {
                        are.Set();
                    }
                }
            }
        }

        
/// <summary>
        
/// Get Control property
        
/// </summary>
        
/// <param name="theForm">the form which the control belongs to</param>
        
/// <param name="controlName">the control name which you want to get</param>
        
/// <param name="controlPropertyName">the property name of the control you want to get</param>
        
/// <returns>the value for the property of the control</returns>
        delegate object getControlPropertyHandler(Form theForm, string controlName, string controlPropertyName);
        
public object GetControlPropertyByPropertyName(Form theForm, string controlName, string controlPropertyName)
        {
            
if (theForm == null)
                
return null;
            
if (theForm.InvokeRequired)
            {
                getControlPropertyHandler getHandler 
= new getControlPropertyHandler(GetControlPropertyByPropertyName);
                
object result = null;
                
object oparams = new object[] {theForm , controlName , controlPropertyName };
                result 
= theForm.Invoke(getHandler, oparams);
                are.WaitOne();
                
return result;
            }
            
else
            {
                Type tForm 
= theForm.GetType();
                FieldInfo fi 
= tForm.GetField(controlName, bindFlags);
                
if (fi == null)
                {
                    are.Set();
                    
return null;
                }
                
else
                {
                    
object theControl = fi.GetValue(theForm);
                    Type tControl 
= theControl.GetType();
                    PropertyInfo pi 
= tControl.GetProperty(controlPropertyName);
                    
object result = null;
                    
if (pi == null)
                    {
                        are.Set();
                        
return null;
                    }
                    
else
                    {
                        result 
= pi.GetValue(theControl, null);
                        are.Set();
                        
return result;
                    }
                }
            }
        }

        
/// <summary>
        
/// Set Control Property
        
/// </summary>
        
/// <param name="theForm">the form which your control belongs to</param>
        
/// <param name="controlName">the control name you want to set value</param>
        
/// <param name="controlPropertyName">the property name of the control</param>
        
/// <param name="newValue">the new value you want to set for the property of the control</param>
        delegate void setControlPropertyHandler(Form theForm, string controlName, string controlPropertyName, object newValue);
        
public void SetControlPropertyByPropertyName(Form theForm, string controlName, string controlPropertyName, object newValue)
        {
            
if (theForm == null)
                
return;
            
if (theForm.InvokeRequired)
            {
                setControlPropertyHandler setHandler 
= new setControlPropertyHandler(SetControlPropertyByPropertyName);
                
object oparams = new object[] {theForm ,controlName , controlPropertyName , newValue  };
                theForm.Invoke(setHandler, oparams);
                are.WaitOne();
            }
            
else
            {
                Type tForm 
= theForm.GetType();
                FieldInfo fi 
= tForm.GetField(controlName,bindFlags );
                
if (fi == null)
                {
                    are.Set();
                    
return;
                }
                
else
                {
                    
object theControl = fi.GetValue(theForm);
                    Type tControl 
= theControl.GetType();
                    PropertyInfo pi 
= tControl.GetProperty(controlPropertyName);
                    
if (pi == null)
                    {
                        are.Set();
                        
return;
                    }
                    
else
                    {
                        
try
                        {
                            pi.SetValue(theControl, newValue, 
null);
                        }
                        
catch
                        {
                            
//it's a invalid value for the property
                            return;
                        }
                        
finally
                        {
                            are.Set();
                        }
                    }
                }
            }
        }

        
/// <summary>
        
/// Invoke a Method, such as "button_click" event
        
/// </summary>
        
/// <param name="theForm">the form which the method belongs to</param>
        
/// <param name="methodName">the method name you want to invoke</param>
        
/// <param name="parameters">the parameters the method needed</param>
        delegate void invokeMethodHandler(Form theForm, string methodName, params object[] parameters);
        
public void InvokeMethod(Form theForm, string methodName, params object[] parameters)
        {
            
if (theForm == null)
                
return;
            
if (theForm.InvokeRequired)
            {
                invokeMethodHandler invokeHandler 
= new invokeMethodHandler(InvokeMethod);
                
object oparams = new object[] {theForm, methodName, parameters};
                theForm.Invoke(invokeHandler, oparams);
                are.WaitOne();
            }
            
else
            {
                Type tForm 
= theForm.GetType();
                MethodInfo mi 
= tForm.GetMethod(methodName, bindFlags);
                
if (mi == null)
                {
                    are.Set();
                    
return;
                }
                
else
                {
                    
try
                    {
                        mi.Invoke(theForm, parameters);
                    }
                    
catch
                    {
                        
return;
                    }
                    
finally
                    {
                        are.Set();
                    }
                }
            }
        }
        
#endregion

        
/// <summary>
        
/// To launch the Application under test(AUT)
        
/// return the Form
        
/// </summary>
        
/// <param name="appPath">the path of exe file</param>
        
/// <param name="formName">the form name of which you want to get</param>
        
/// <returns>the form you want to get</returns>
        public Form LaunchApp(string appPath, string formName)
        {
            Form theForm 
= null;
            
if (!System.IO.File.Exists(appPath))
                
return null;
            
string theFormName = formName;
            Assembly ass 
= Assembly.LoadFrom(appPath);
            Type tForm 
= ass.GetType(formName);
            
if (tForm == null)
                
return null;
            theForm 
= (Form)ass.CreateInstance(tForm.FullName);
            
if (theForm == null)
                
return null;

            AppState aState 
= new AppState(theForm);
            ThreadStart ts 
= new ThreadStart(aState.Run);
            Thread theThread 
= new Thread(ts);
            theThread.IsBackground 
= true;
            theThread.SetApartmentState (ApartmentState.STA);
            theThread.Start();
            
return theForm;
        }
    }
    
//this is a wrapper class for ThreadStart method call
    class AppState
    {
        Form theForm;
        
public AppState(Form form)
        {
            theForm 
= form;
        }
        
public void Run()
        {
            Application.Run(theForm);
        }
    }
}

 

posted on 2011-08-13 20:16  零点零一  阅读(1145)  评论(0编辑  收藏  举报