Click here to Skip to main content
Click here to Skip to main content

Automated Test System: Part I

By , 17 Mar 2009
 

Introduction

This article presents just a demonstration of how we can start an automated test system development. It's open to all to contribute and make it more worthy. Also, kindly note that you will require both the ATS.zip and Testapp.zip.

Background

I had been looking for an automated test system tool for quite some time, but could not find something which was reliable. So I thought why not try and develop something myself.

main.png

Using the code

The code can be used by anyone who has a basic understanding of the Reflection namespace in the .NET framework. The sole idea is based on any other reflector available in the market, for example Reflector, or the ILDASM that ships with the installation of the .NET framework.

I have tried to use the same idea here. Most of the usable code resides in ATSMainForm.cs. Once we are inside the application:

/// ********************************************************************
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main ()
{
    Application.Run (new ATSMainForm ());
}

We will need to select the target assembly/executable and hit on Launch. What we do in launch is shown here:

///**********************************************************************
/// <summary>
/// Click event handler for the launch button.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="ea">An <see cref="EventArgs"/> object
/// that contains the event data.</param>
/// <remarks>
/// Launches the target application selected via browse button.
/// </remarks> 
private void launchBtn_Click (object sender, System.EventArgs ea)
{
    // Enable/Disable controls
    this.m_mainTv.Nodes.Clear ();
    this.m_mainPnl.Enabled = true;
    this.m_invokeMethodBtn.Enabled = false;
    this.m_methodNameTxtBox.Enabled = false;

    try
    {
        this.m_testAssembly = Assembly.LoadFrom (this.m_appPathTxtBox.Text);
        // Get the available types (controls)
        Type[] types = m_testAssembly.GetTypes ();

        // Try resolving the types and add relevent ones to the treeview
        ResolveTypes (types);

        // Find the entry method and launch the application.
        // TODO: If the default constructor is private, we need to find out
        // how the application can still be launched.
        MethodInfo entryMethod = m_testAssembly.EntryPoint;

        this.m_testForm = m_testAssembly.CreateInstance (
            entryMethod.DeclaringType.FullName,
            true,
            this.m_bindingFlags,
            null,
            null,
            System.Globalization.CultureInfo.InvariantCulture,
            null);
        // Constructor created, try launching??
        ThreadPool.QueueUserWorkItem (new WaitCallback (RunApp), m_testForm);
    }
    catch (Exception ex)
    {
        {
            Form errForm = new ATSError (ex);
            errForm.ShowDialog ();
        }
    }
} // end launchBtn_Click

The good thing about Reflection can be observed here. .NET Reflection allows you to list down all methods/properties/events/classes .. in fact, every thing that is related to this application.

Here is how:

//**********************************************************************
/// <summary>
/// Tries resolving the methods and adds relevent ones to the treeview.
/// <param name="types"> An array of types defined in the loaded assembly
/// </param>
/// <param name="nodeRank"> The index of current <see cref="TreeNode"/>
/// </param>
///</summary>
private void AddMethods (int nodeRank, Type[] types)
{
    MethodInfo[] methods = types[nodeRank].GetMethods (m_bindingFlags);
    this.m_mainTv.Nodes[nodeRank].Nodes.Add ("Methods");

    this.m_mainTv.Nodes[nodeRank].Nodes[1].ImageIndex = 2;
    this.m_mainTv.Nodes[nodeRank].Nodes[1].SelectedImageIndex = 2;

    this.m_tsStatus.Text = "Analysing Methods...";
    this.m_tsProgressBar.ProgressBar.Maximum = methods.Length;

    int nodeCount = 0;

    for (int iMethodCount =0; iMethodCount < methods.Length; iMethodCount++)
    {
        this.m_tsProgressBar.ProgressBar.Value = (int) (iMethodCount/methods.Length * 100);
        this.m_tsStatus.Invalidate ();
        MethodInfo method = (MethodInfo) methods.GetValue (iMethodCount);
        MethodAttributes methodAttrib = method.Attributes;
        if ((method.DeclaringType.FullName == types[nodeRank].FullName.ToString ()) && 
                !(methodAttrib.ToString ().Contains ("SpecialName")))
        {
            this.m_mainTv.Nodes[nodeRank].Nodes[1].Nodes.Add (method.ToString ());
            this.m_mainTv.Nodes[nodeRank].Nodes[1].Nodes[nodeCount].ImageIndex = 2;
            this.m_mainTv.Nodes[nodeRank].Nodes[1].Nodes[nodeCount].SelectedImageIndex = 2;
            this.m_mainTv.Nodes[nodeRank].Nodes[1].Nodes[nodeCount].Tag = method;
            nodeCount++;

        }
    }

    this.m_tsProgressBar.ProgressBar.Value = 0;

} // end AddMethods

Similarly, the events and properties/fields can also be listed. This is one of the approaches that can be followed to write your own reflector or ILDASM :)

testapp.png

Next, the user can start clicking on the method names by which the invoke method textbox is enabled/disabled and then we can invoke any method (say button1_click) as demonstrated in testapp.zip.

Points of interest

pass.png

An interesting point is the way the test is run. Right now, the method names are hard-coded, but later we might like to have these read from some Excel file or something and then use those method names instead.

History

  1. Modified the code a bit to have the start-up form input from the user. The name of the form will be its fully qualified name, i.e., NameSpaceName.FormName.
  2. Check out the latest binaries. I'll upload the updated code and documentation very soon.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

About the Author

GamePlanner
Software Developer
United States United States
Member
"Gameplanner" is an independent software developer. He has been doing software development for many years and has worked with international clients to deliver high quality products.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy idersmemberAlphaXu20 Apr '09 - 16:56 
GeneralRe: My idersmemberAlphaXu20 Apr '09 - 17:13 
General[My vote of 2] what unique item were you trying to testmemberDonsw16 Apr '09 - 7:41 
Questionwhy not nunit?memberrkeron24 Mar '09 - 6:21 
GeneralGood One...memberBhagaban122 Mar '09 - 22:37 
GeneralYou can test some issue but not allmemberwegenerb17 Mar '09 - 8:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 17 Mar 2009
Article Copyright 2009 by GamePlanner
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid