Взаимодействие с несколькими экземплярами приложения в кодированном интерфейсе
Сценарий, с которым я сталкиваюсь, заключается в том, что я пытаюсь написать один тест, который будет использовать кодированный пользовательский интерфейс для взаимодействия с несколькими экземплярами одного и того же приложения, в данном случае Microsoft Excel. Другими словами, в нескольких окнах будет открыто несколько книг Excel, и мне нужно иметь возможность направлять кодированный интерфейс для программного взаимодействия с конкретным экземпляром. Я изначально думал, что этот тип управления экземплярами будет функцией ApplicationUnderTest
класс, но не очевидно, как этот класс достиг бы этого.
Взаимодействия будут включать в себя один и тот же UIMap для всех экземпляров (на самом деле каждому экземпляру, возможно, потребуется несколько UIMap, но ради простоты, которую можно игнорировать для этого вопроса, если только он не имеет существенного значения для ответа).
Я уже знаю пару подходов к решению:
- Минимизируйте и максимизируйте экземпляры, чтобы в данный момент был виден только тот, который используется в данный момент. В идеале я бы хотел этого избежать. С одной стороны, это может в конечном итоге стать требованием, чтобы два окна были видны одновременно во время испытаний.
- Динамически изменяйте свойства поиска, чтобы всегда включать некоторый уникальный идентификатор при каждом доступе к карте пользовательского интерфейса. Я не уверен, что лучший кандидат для поиска недвижимости будет здесь.
В идеале я хотел бы, чтобы в Coded UI было что-то более интегрированное, чем любой из этих вариантов, хотя, возможно, последнего будет достаточно при необходимости. Буду признателен за любые указания о том, есть ли другие возможные подходы.
1 ответ
Вы можете попробовать создать несколько экземпляров элемента управления пользовательского интерфейса (класс, сгенерированный в UIMap) и установить для них свойство поиска Instance (если у вас есть какие-либо другие уникальные свойства поиска, вы также можете использовать их). Вам нужно установить их только в начале теста.
Я использовал калькулятор для этого примера. Это должен быть Namespace.UIControl, а не UIMap.UIControl. Вам нужен класс, а не собственность.
var a1 = new UICalculatorWindow();
a1.SearchProperties["Instance"] = "1";
var a2 = new UICalculatorWindow();
a2.SearchProperties["Instance"] = "2";
a1.Find();
a2.Find();
После нахождения этих окон их дескриптор окна будет связан с объектом управления, поэтому вам больше не придется беспокоиться об их порядке.
Другое решение - получить все текущие дескрипторы окон с помощью функции pinvoke, отфильтровать их, чтобы получить нужные окна, а затем использовать UITestControlFactory
создать свои элементы управления.
Изменить: или вы можете использовать метод FindMatchingControls.
var a = new UICalculatorWindow().FindMatchingControls();
Затем вы можете получить живое управление из возвращенного списка. Эти решения немного обходные, но я не думаю, что это можно решить на уровне UIMap, если все экземпляры элемента управления не записаны как уникальные элементы управления пользовательского интерфейса.
Редактировать: CUIT ищет в списке дескрипторов окна, которые он получает от вызова WinApi (EnumWindows
) и по умолчанию возвращает первое окно из списка, которое соответствует заданным свойствам поиска. Если Instance
свойство устанавливается, затем оно пропускает первые n-1 окон (которые соответствуют критериям поиска) и возвращает вам n-ное окно.
Когда вы звоните Find()
на UITestControl
он будет искать окно с заданными свойствами поиска и, если окно найдено, UITestControl
сохраняет ссылку на дескриптор окна этого окна или AccessibleObject
это досталось из этого окна.
Порядок дескрипторов окна может меняться довольно часто, например, если вы установите фокус на окно, оно будет ближе к началу списка. Поэтому, когда у вас все окна открыты, вы должны создать UITestControl
s, установите свойство Instance и вызовите Find()
на всех них, чтобы они не перепутали во время теста.
Если вы найдете окно с Instance
установить в 1, а затем смешать порядок окон, то при поиске окна с Instance
при значении 2 вы можете найти окно, которое вы уже нашли, заканчивая двумя UITestControl
с тем же окном.
Я понятия не имею, как OrderOfInvocation
работает, я не мог заставить его работать еще.