Может ли RubberDuck проверить работу программы? - PullRequest
0 голосов
/ 26 декабря 2018

Я занимаюсь разработкой тестов с RubberDuck и хотел бы проверить выходные данные MsgBox из программы.Уловка в том, что программа заканчивается сразу после вывода MsgBox - буквально есть оператор «End».

При выполнении теста RubberDuck и использовании Fakes.MsgBox.Returns появляется неубедительный желтый результат с сообщением «Неожиданное исключение COM при выполнении тестов»

Я пытался разместить «Assert.Fail».«в конце теста;однако кажется, что окончание программы сбрасывает все с толку.

Возможно ли, чтобы тест в RubberDuck обнаружил, что программа заканчивается?

1 Ответ

0 голосов
/ 26 декабря 2018

tldr;Нет

Модульные тесты Rubberduck выполняются в контексте среды выполнения VBA, т. Е. Код модульного теста VBA выполняется изнутри хост-приложения.Результаты тестирования возвращаются в Rubberduck через его API.Если вы посмотрите на код VBA, сгенерированный при вставке тестового модуля, он дает базовое представление об архитектуре того, как выполняются тесты.Возьмем, к примеру, этот модульный тест из нашего набора интеграционных тестов:

'HERE BE DRAGONS.  Save your work in ALL open windows.
'@TestModule
'@Folder("Tests")

Private Assert As New Rubberduck.AssertClass
Private Fakes As New Rubberduck.FakesProvider

'@TestMethod
Public Sub InputBoxFakeWorks()
    On Error GoTo TestFail

    Dim userInput As String
    With Fakes.InputBox
        .Returns vbNullString, 1
        .ReturnsWhen "Prompt", "Second", "User entry 2", 2
        userInput = InputBox("First")
        Assert.IsTrue userInput = vbNullString
        userInput = InputBox("Second")
        Assert.IsTrue userInput = "User entry 2"
    End With

TestExit:
    Exit Sub
TestFail:
    Assert.Fail "Test raised an error: #" & Err.Number & " - " & Err.Description
End Sub

Broken down:

Это создает управляемый класс, который «прослушивает» утверждения в тестируемом коде иоценивает условие для прохождения или провала теста.

Private Assert As New Rubberduck.AssertClass     

FakesProvider - это служебный объект для установки перехватчиков во время выполнения VB для «игнорирования» или «подмены» вызовов из среды выполнения VB дляскажем, функция InputBox.

Поскольку объект Fakes объявлен As New, блок With создает экземпляр FakesProvider для теста.Метод InputBox для Fakes Устанавливает функцию rtcInputBox в vbe7.dll, которая перенаправляет весь трафик с VBA на эту функцию для реализации Rubberduck.Теперь выполняется подсчет вызовов, отслеживание переданных параметров, предоставление возвращаемых значений и т. Д.

    With Fakes.InputBox

При вызовах Returns и ReturnsWhen используется COM-объект VBA с удержанием, чтобы сообщить настройку теста ложных вызовов на InputBox,В этом примере он конфигурирует объект InputBox для возврата vbNullString для вызова номер один и "Пользовательская запись 2" при передаче параметра Prompt "Second" для вызова номер два.

        .Returns vbNullString, 1
        .ReturnsWhen "Prompt", "Second", "User entry 2", 2

Именно здесь и вступает AssertClass. Когда вы запускаете модульные тесты из интерфейса Rubberduck, он определяет интерфейс COM для кода пользователя.Затем он вызывает метод теста через этот интерфейс.Затем Rubberduck использует AssertClass для проверки условий работы.Метод IsTrue принимает Boolean в качестве параметра (с дополнительным выходным сообщением).Таким образом, в строке кода ниже VB вычисляет выражение userInput = vbNullString и передает результат в качестве параметра IsTrue.Затем реализация Rubberduck IsTrue устанавливает состояние модульного теста на основе того, соответствует ли параметр, переданный из VBA, условию вызываемого метода AssertClass.

        Assert.IsTrue userInput = vbNullString

Что это означаетв связи с вашим вопросом:

Обратите внимание, что при разборе того, как выполняется приведенный выше код, все выполняется в среде VBA .Rubberduck предоставляет VBA «окно» для отчета о результатах через объект AssertClass и просто (для некоторых значений «просто») предоставляет сервис перехвата через объект FakesProvider.VBA «владеет» обоими этими объектами - они просто предоставляются через COM-провайдер Rubberduck.

Когда вы используете оператор End в VBA, он принудительно завершает выполнение в этой точке.На COM-объекты Rubberduck больше нет активных ссылок со стороны клиента (ваша процедура тестирования), и неясно, уменьшает ли это число ссылок на COM-объект.Это как выдернуть вилку из стены.Единственное, что может определить Rubberduck на этом этапе, - это отключение COM-клиента.В вашем случае это проявляется как исключение COM, попавшее в Rubberduck.Поскольку Rubberduck не может узнать , почему объект, который он предоставляет, потерял связь, он сообщает о результате теста как "Неокончательный" - он не был выполнен до завершения.


* 1062Тем не менее, решение состоит в том, чтобы реорганизовать ваш код, чтобы не использовать End.Когда-либо.Цитирование документации, указанной выше End ...

Немедленно прекращает выполнение.Сам по себе никогда не требуется, но может быть помещен где-нибудь в процедуре для завершения выполнения кода, закрытия файлов, открытых с помощью оператора Open, и для очистки переменных.для других объектов COM (кроме Rubberduck) нет гарантии, что они будут надежно завершены.


Полное раскрытие. Я участвую в проекте Rubberduck и написал часть кода, описанного выше.Если вы хотите лучше понять, как работает модульное тестирование (и можете читать c #), реализации поставщиков COM можно найти по этой ссылке .

...