在python中使用menuStrip及其项目

时间:2014-09-24 10:21:45

标签: python winforms automated-tests ui-automation

我必须为WinForms应用程序构建自动化ui测试。我正在使用python 3.4和python for windows extension和pywinauto。

需要进行测试才能访问应用程序的菜单并单击其中一个子菜单项。

我使用下面的代码尝试找到菜单。

#arrays to store the controls found
classes = []
objects = []

#recursive method to get all the controls
def getClasses(childHwnd, lparam):
    objects.append(childHwnd)
    classes.append(win32gui.GetWindowText(childHwnd))
    return 1

#find handle of the main window
hwnd = win32gui.FindWindow(None, 'Form1')

#get all controls
win32gui.EnumChildWindows(hwnd, getClasses, "a")

# Result:    
# objects [1509794, 3344468] 
# classes ['Test', 'menuStrip1']

#trying to get the menu of the form
win32gui.GetMenu(hwnd) #Returns 0

我在上面测试代码的表单图片:

Image of the form used for the tests above

正如你所看到的,发现了menuStrip1,但是我还没有办法找到它的孩子(Meniu 1,Meniu 2)。

有关如何查找菜单及其子项的任何想法吗?

3 个答案:

答案 0 :(得分:2)

对于Menustrip项目,一个简单的解决方法是使用pywinauto基本鼠标输入模块。 通过使用它,您可以使用(x,y)坐标移动到屏幕的特定位置。

例如:

public Startup(IConfiguration configuration) {
    Configuration = configuration;
}
public IConfiguration Configuration {
    get;
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) {
    services.AddDbContext < ApplicationDbContext > (options = >
        options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
    services.AddIdentity < ApplicationUser, IdentityRole > ()
        .AddEntityFrameworkStores < ApplicationDbContext > ()
        .AddDefaultTokenProviders();
    // Add application services.
    services.AddTransient < IEmailSender, EmailSender > ();
    services.AddAuthentication().AddGoogle(googleOptions = > {
        googleOptions.ClientId = Configuration["GoogleID"];
        googleOptions.ClientSecret = Configuration["GoogleSecret"];
    });
    services.Configure < MvcOptions > (options = > {
        options.Filters.Add(new RequireHttpsAttribute());
    });
    services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
    if (env.IsDevelopment()) {
        app.UseBrowserLink();
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();
    } else {
        app.UseExceptionHandler("/Home/Error");
    }
    app.UseStaticFiles();
    app.UseAuthentication();
    var options = new RewriteOptions().AddRedirectToHttps(301, 5001);
    app.UseRewriter(options);
    app.UseMvc(routes = > {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

答案 1 :(得分:1)

尝试使用python 3.4与python for windows extension和pywinauto后,没有成功地为各个项目创建自动化测试。我查看了其他工具,最后选择了一个名为Sikul i的工具,它是一个基于屏幕上元素图像识别的自动化工具。它可能不是完美的工具,但对我来说已经足够了。

关于用于Windows扩展和pywinauto的python的其他观察:

  • 只能用于他们知道的控件(例如,不能使用) toolstripmenuitem)
  • 无法测试自定义控件(对于 原因)

关于Sikuli的观察:

  • 所有脚本都是用python编写的
  • 它可能不会使用最新的python语法
  • 在我使用它的那一刻,它有一些小错误

答案 2 :(得分:0)

虽然已经为替代解决方案发布了答案,但我想添加一个可以在pywinauto中使用的解决方法。

在Windows上,ALT键可用于访问菜单。对于我的具体示例,我有一个设置选项“设置 - &gt;远程登录”。如果我想单击此菜单选项,我首先必须发送ALT + S,然后键入L.要使用pywinauto执行此操作,假设您已经有对该窗口的引用,您可以这样做:

myWindow.SetFocus()
myWindow.TypeKeys("%s") #Clicks Settings
myWindow.TypeKeys("l") #Clicks Login Remotely

'%'字符用于表示键盘上的'ALT'键。另外需要注意的是,如果您有多个以相同字母开头的菜单选项,则可能需要多次发送该键才能找到所需的键,然后发送回车键。如果没有歧义(在这种情况下,只有一个子菜单选项以L开头),则会自动选择它。

这需要您很好地了解您的菜单,以及以何种顺序,但只要它没有改变,这应该适合您。