首页 > 解决方案 > WPF:如何测试应用程序是否在 Appium 中最小化

问题描述

在我的项目中,我想使用 appium 和 WinAppDriver 测试我的应用程序的 ui(用 C# .net-core-5.0/WPF 编写)。

第一步是为我的应用程序实现无边框设计,因此我使用了 windowChrome 功能并构建了一个带有最小化、恢复和关闭按钮的自定义标题栏。对于这个按钮,我现在想编写测试用例。

测试代码应该是直截了当的......点击最小化,使用提供的 appium 驱动程序最大化按钮并测试 Window 对象具有的 windowState 属性。但我不知道如何提取 windowState 属性。

[TestMethod]
public void TestMinimizeWindow()
{
    session.FindElementByAccessibilityId("MinimizeButton").Click();
    //how to extract the information whether the app is minmized, maximized or normal
    var actualWindowState = ...
    Assert.AreEqual(WindowState.Minimized,actualWindowState);
}

谁知道如何用 appium/WinAppDriver 提取属性?或者有人对此案有其他解决方案吗?

标签: c#wpfappium

解决方案


正如Arkane的帖子中所建议的那样,我创建了一个进程句柄,我可以从中确定状态

namespace codedui_test
{
    public enum ShowWindowCommands : int
    {
        Hide = 0,
        Normal = 1,
        Minimized = 2,
        Maximized = 3,
    }

    [Serializable]
    [StructLayout(LayoutKind.Sequential)]
    public struct WINDOWPLACEMENT
    {
        public int length;
        public int flags;
        public ShowWindowCommands showCmd;
        public System.Drawing.Point ptMinPosition;
        public System.Drawing.Point ptMaxPosition;
        public System.Drawing.Rectangle rcNormalPosition;
    }

    public class ProcessManager
    {
        protected Process process;

        public ProcessManager(string processToWatch)
        {
            
            //get Handle of window to extract it's position and styles
            Process[] processes = Process.GetProcesses();
            foreach (Process proc in processes)
            {
                if (proc.ProcessName == processToWatch)
                {
                    process = proc;
                    break;
                }
            }
        }

        public WINDOWPLACEMENT GetPlacement()
        {
            IntPtr hwnd = process.MainWindowHandle;
            WINDOWPLACEMENT placement = new WINDOWPLACEMENT();
            placement.length = Marshal.SizeOf(placement);
            GetWindowPlacement(hwnd, ref placement);
            return placement;
        }

        [DllImport("user32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);
    }
}

在我的 Testclass 中,我现在可以创建一个 processobject,我可以从中获取位置:

using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Appium.Windows;

namespace codedui_test
{
    [TestClass]
    public class MainWindowTest
    {
        protected static ProcessManager dSProcess;

        [ClassInitialize]
        public static void ClassInitialize(TestContext context)
        {
            //Setup Handle to Window to be able to determine it's size
            dSProcess = new ProcessManager("ProgramName");
        }

        [TestMethod]
        public void TestWindowControl()
        {
            session.FindElementByAccessibilityId("MaximizeButton").Click();
            var placement = dSProcess.GetPlacement();
            Assert.AreEqual("Maximized", placement.showCmd.ToString());
            session.FindElementByAccessibilityId("RestoreButton").Click();
            placement = dSProcess.GetPlacement();
            Assert.AreEqual("Normal", placement.showCmd.ToString());
            session.FindElementByAccessibilityId("MinimizeButton").Click();
            placement = dSProcess.GetPlacement();
            Assert.AreEqual("Minimized", placement.showCmd.ToString());
        }

        ....further methods

    }

}

此解决方案的草稿来自Arkane 发布的源


推荐阅读