【问题标题】:Integration Testing of WPF GUI: How do I identify that current work was finishedWPF GUI 的集成测试:如何确定当前工作已完成
【发布时间】:2015-05-14 12:02:18
【问题描述】:

我想在我的 WPF 应用程序上运行集成 UI 测试,但我不确定如何检测当前测试何时完成,以便继续进行下一个测试。

简化,假设我的窗口上有一个按钮。单击按钮时,我将其禁用,然后修改模型,然后重新启用该按钮。一旦检测到模型已更改,WPF 就会更改屏幕上的视图。

现在我想运行一个模拟一次又一次单击按钮的测试。要单击按钮,我将使用自动化,如 in this SO question 所述。但是我怎么知道什么时候工作完成,显示更新,以便再次“点击”按钮?我是钩住按钮的 IsEnabledChanged,还是有一些全局指示表明当前的处理周期已经完成?

编辑:我的描述中缺少的是我希望用户在屏幕上看到中间结果。例如,如果测试有 10 个阶段,我希望用户在屏幕上看到类似 Step Counter 标签,其值为 1 .. 10,而不仅仅是数字立即从 1 变为 10。请参阅下面的答案。

【问题讨论】:

  • 用户如何知道操作已经完成?

标签: wpf integration-testing gui-testing


【解决方案1】:

这是我设法让它工作的方法。这可能是微不足道的 - 我是 GUI 新手。我只是在这里发布它,希望它可以帮助像我这样的其他新手:)

无论如何,我使用的是两个按钮的解决方案:测试和步骤。 Test 启动测试序列,Step 运行测试的每个步骤。 Step 按钮与 Integration Tester By Steps 助手交互。

helper 接收一个带有 Number Of Commands 作为参数的 Init,(目前 helper 自己生成随机命令,所以它只需要知道要生成多少个命令)。 helpe 提供了一个 Step 方法来执行下一个命令,以及一个 Needs More Steps 属性来指示是否应该继续测试。

帮助程序从 INotifyPropertyChanged 派生并具有显示在主窗口上的 Counter 依赖项属性。

Test 和 Step 按钮的状态由三个辅助方法控制:SetButtonsFor_OutsideTesting、SetButtonsFor_InsideTestingOutsideAnyStep 和 SetButtonsFor_InsideTestingInsideAStep。

首先,我验证了一切都在手动运行,然后我添加了一个计时器,并使用 how to programmatically click a button in WPF 上的 Stack Overflow 建议以及如何制作 WPF Timer Like C# Timer 来自动化该过程。

现在,这是主窗口的代码:

     private void Test_Click(object sender, RoutedEventArgs e)
    {
        SetButtonsFor_InsideTestingOutsideAnyStep();
        RunTheTestBySteps();
    }


    public readonly IntegrationTesterBySteps _integrationTesterBySteps =
                                            new IntegrationTesterBySteps();

    void RunTheTestBySteps()
    {
        SetButtonsFor_InsideTestingOutsideAnyStep();
        IntegrationTesterBySteps.Init(10);
        StartTheTimer();
    }

    private void StartTheTimer()
    {
        DispatcherTimer = new DispatcherTimer();
        DispatcherTimer.Tick += DispatcherTimer_Tick;
        DispatcherTimer.Interval = new TimeSpan(0, 0, 1);
        DispatcherTimer.Start();
    }

    private void StopTheTimer()
    {
        DispatcherTimer.Stop();
        DispatcherTimer.Tick -= DispatcherTimer_Tick;
    }

    private DispatcherTimer DispatcherTimer { get; set; }

    private void DispatcherTimer_Tick(object sender, EventArgs e)
    {
        if (!BtnStep.IsEnabled) return;
        ClickTheStepButton();
        CommandManager.InvalidateRequerySuggested();
    }

    private void BtnStep_Click(object sender, RoutedEventArgs e)
    {
        SetButtonsFor_InsideTestingInsideAStep();

        IntegrationTesterBySteps.Step();

        if (this.IntegrationTesterBySteps.NeedsMoreSteps)
            SetButtonsFor_InsideTestingOutsideAnyStep();
        else
        {
            SetButtonsFor_OutsideTesting();
            StopTheTimer();
        }
    }

    private void ClickTheStepButton()
    {
        var peer = new ButtonAutomationPeer(BtnStep);
        var invokeProv = peer.GetPattern(PatternInterface.Invoke)
                                              as IInvokeProvider;
        if (invokeProv != null)
            invokeProv.Invoke();
    }

    void SetButtonsFor_InsideTestingInsideAStep()
    {
        BtnTest.IsEnabled = false;
        BtnStep.IsEnabled = false;
    }

    void SetButtonsFor_InsideTestingOutsideAnyStep()
    {
        BtnTest.IsEnabled = false;
        BtnStep.IsEnabled = true;
    }

    void SetButtonsFor_OutsideTesting()
    {
        BtnTest.IsEnabled = true;
        BtnStep.IsEnabled = false;
    }

【讨论】:

    【解决方案2】:

    我如何知道工作完成和显示更新,以便再次“点击”按钮?

    根据你的描述,你说当按钮被点击我禁用它,我修改模型,然后我重新启用按钮。

    因此,我只能假设当模型发生变化时,Button 将被重新启用。因此,您可以将处理程序附加到模型的 NotifyPropertyChanged 事件,或者按照您的建议,为 IsEnabledChanged 事件添加处理程序。

    【讨论】:

    • 屏幕更新,如果发生的话,发生得太快了,我无法确定屏幕在中间测试步骤之间是否更新。我正在投票赞成您的答案,但我不确定这是正确的方法。查看我的编辑。
    猜你喜欢
    • 2018-04-15
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    • 2021-04-15
    • 2014-04-25
    相关资源
    最近更新 更多