[英]UI automation testing of WPF controls seems to ignore bindings
我目前正在尝试弄清楚如何为我的WPF应用程序自动化UI测试,但是我很难使它正常工作。
MyControl
的XAML(扩展了UserControl
)包含以下CheckBox
:
<CheckBox Name="IsFooCheckBox"
IsChecked="{Binding Path=IsFoo, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
绑定指向实现INotifyPropertyChanged
并包含以下属性的自定义数据上下文:
private bool _isFoo;
public bool IsFoo
{
get { return _isFoo; }
set
{
_isFoo = value;
OnPropertyChanged("IsFoo");
}
}
绑定正在生产中使用(在调试器中,只要切换复选框,就可以看到_isFoo
已更新)。
我现在想进行一次测试,以切换复选框并检查数据上下文是否已更新(或检查在后面代码中实现的逻辑)。 WPF UI自动化框架似乎正是我要寻找的,因此我编写了以下NUnit测试:
var myContext = ...
var sut = new MyControl
{
DataContext = myContext
};
var peer = new CheckBoxAutomationPeer(sut.IsFooCheckBox);
var pattern = peer.GetPattern(PatternInterface.Toggle) as IToggleProvider;
pattern.Toggle();
Assert.That(sut.IsProvidingProfileCheckBox.IsChecked.Value); // works
Assert.That(myContext.IsFoo); // fails
当第一个Assert
通过时,第二个失败。 我不明白为什么会发生这种情况。似乎XAML文件中的绑定被忽略或未触发更新。 有人建议如何修复我的考试吗? 这有可能吗?
问题起源于此
public bool IsFoo
{
get { return _IsFoo; }
set
{
_isFoo = value;
OnPropertyChanged("IsFoo");
}
}
一旦调用
pattern.Toggle();
您隐式调用IsFoo的setter,它引发PropertyChanged事件,并反过来强制刷新具有与IsFoo相关联的绑定的UI元素-简而言之,调用getter,而不是_isFoo,它返回_IsFoo 。 你误认为变量。
尝试避免使用显式属性名称调用OnPropertyChanged方法。 而不是使用CallerMemberName属性来获取属性名称。
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
然后,您仅需要以下调用。
OnPropertyChanged();
我有类似的问题。 我正在用以下代码填充文本框:
ValuePattern valuePattern = promptBox.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
valuePattern.SetValue(value);
并且根据文本框中的值,另一个按钮状态应该从“禁用”更改为“启用”。
我注意到在执行了上面的自动化代码之后,手动单击窗口会触发绑定以进行评估。
所以我刚刚添加
System.Windows.Forms.SendKeys.SendWait("{TAB}");
在SetValue之后,它开始正常工作。
我花了一些时间弄清楚这一点,但最后,它很明显,并且在Internet上的许多地方都有描述。 我想只要知道要寻找的东西,一切都会变得很容易。
编码的UI测试的问题是绑定不会自动解决。 必须通过调用Window.ShowWindow
来启动解析。
我扩展了测试并添加了以下代码段:
Window window = new Window
{
Content = sut // the control to test
};
window.Show();
添加此调用可立即修复我在帖子中描述的奇怪测试行为。
直接的跟进问题是此调用需要一个活动的UI线程。 因此,要使测试在连续集成环境中的构建服务器上运行可能会很棘手。 但是,这取决于环境(尤其是构建服务器),这是一个不同的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.