65.9K
CodeProject 正在变化。 阅读更多。
Home

自动化测试系统:第 I 部分

2009年3月17日

GPL3

2分钟阅读

viewsIcon

31677

downloadIcon

539

本文旨在演示在 .NET 框架中进行测试的一种方法。这只是一个关于如何使用 C# .NET 进行自动化测试的演示。

引言

本文仅演示了如何开始开发自动化测试系统。欢迎所有人贡献并使其更有价值。另外,请注意您需要同时拥有 ATS.zipTestapp.zip

背景

我一直在寻找自动化测试系统工具,但找不到可靠的。所以我想为什么不尝试自己开发一些东西呢。

main.png

使用代码

任何对 .NET 框架中的 Reflection 命名空间有基本了解的人都可以使用该代码。这个想法基于市场上任何其他的反射器,例如 Reflector,或者安装 .NET 框架时附带的 ILDASM

我在这里尝试使用了相同的想法。大部分可用的代码位于 ATSMainForm.cs 中。一旦我们进入应用程序

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

我们需要选择目标程序集/可执行文件并点击“启动”。我们在启动中执行的操作如下所示

///**********************************************************************
/// <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

在这里可以观察到 Reflection 的优点。.NET Reflection 允许您列出所有方法/属性/事件/类……事实上,与此应用程序相关的所有内容。

方法如下

//**********************************************************************
/// <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

同样,也可以列出事件和属性/字段。这是编写您自己的反射器或 ILDASM 的方法之一 :)

testapp.png

接下来,用户可以开始单击方法名称,这将启用/禁用 invoke 方法文本框,然后我们可以调用任何方法(例如 button1_click),如 testapp.zip 中所示。

关注点

pass.png

一个有趣的点是测试的运行方式。现在,方法名称是硬编码的,但稍后我们可能希望从某个 Excel 文件或其他文件中读取这些名称,然后使用这些方法名称。

历史

  1. 修改了一些代码,以便从用户那里获取启动表单输入。表单的名称将是其全名,即 NameSpaceName.FormName
  2. 查看最新的二进制文件。我很快就会上传更新的代码和文档。

© . All rights reserved.