Читайте также:
|
|
Отладочные средства Visual Basic помогают найти и искоренить ошибки, случайно внесенные в ваше приложение. Тем не менее в процессе разработки больших приложений (особенно тех, которые содержат многократно используемый код) желательно написать специальную тестовую утилиту, предназначенную для «прогона» вашей программы. Если приложение успешно пройдет тестирование, его можно запускать в нормальном режиме. В этом разделе вы научитесь создавать собственные тестовые утилиты.
Для начала мы напишем несложное интерфейсное приложение (рис. 12.13), которое позволяет тестировать функции модуля одним нажатием кнопки. Хорошо спроектированные, самостоятельные функции должны хорошо работать с таким интерфейсом. Вы можете добавить в него другие кнопки для тестирования ваших собственных процедур. Имена процедур, входные данные и результаты выводятся в верхнем списке.
Рис. 12.13. Приложение Debug Toolbox
Интерфейсное приложение создается следующим образом:
1. Создайте новый проект командой File > New Project или клавишами Ctrl+N.
2. В диалоговом окне New Project выберите значок Standard EXE, затем закройте диалоговое окно кнопкой ОК.
3. В окне проекта щелкните на строке Project1.
4. Введите в окне свойств новое значение свойства Name проекта — Debug Toolbox.
5. Щелкните на форме Form1 в конструкторе форм, чтобы сделать ее активной.
6. Задайте свойству Name значение frmMain, а свойству Caption — значение Debug Toolbox.
7. Создайте на форме стандартный список. Переместите его в верхнюю часть формы и растяните так, чтобы он занимал примерно половину высоты формы и почти всю ширину.
8. Задайте свойству Name списка значение lstResults.
9. Создайте на форме рамку. Задайте ее свойству Name значение fraFunctions, а свойству Caption — значение Функции.
10. Расположите рамку fraFunctions под списком lstResults и растяните ее так, чтобы она занимала всю оставшуюся часть формы.
Общий макет формы готов, теперь мы создадим в рамке Функции несколько кнопок. Они будут использоваться при тестировании функций.
1. С помощью мыши «нарисуйте» кнопку внутри рамки.
ПРИМЕЧАНИЕ Рамки, как и формы, представляют собой контейнеры для других элементов. Чтобы добавить в рамку новый элемент, необходимо «нарисовать» его мышью внутри самой рамки. Двойной щелчок на кнопке в панели элементов разместит элемент на форме, а не в рамке.
2. Задайте свойству Name кнопки значение cmdSpellMonth, а свойству Caption -значение Spell&Month.
Чтобы не рисовать внутри рамки вторую кнопку, мы продублируем созданную ранее. Это гарантирует одинаковый размер всех кнопок, а также упрощает создание дополнительных кнопок в контейнере.
3. Щелкните на кнопке cmdSpellMonth, чтобы сделать ее активным элементом.
4. Нажмите Ctrl+C, чтобы скопировать элемент в буфер обмена Windows.
5. Щелкните на рамке fraFunctions, чтобы сделать ее активным элементом. Тем самым вы назначаете рамку приемником для следующей операции вставки.
6. Нажмите Ctrl+V; в рамке создается дубликат кнопки. На экране появляется сообщение о том, что элемент с именем cdmSpellMonth уже существует (рис. 12.14).
Рис. 12.14. Хотите ли вы создать массив элементов?
7. В диалоговом окне нажмите кнопку No — мы сами зададим имена всех кнопок. Кнопка включается в элемент-рамку.
8. Переместите новую кнопку в верхнюю часть рамки на одну линию с кнопкой cmdSpellMonth.
9. Задайте свойству Name новой кнопки значение cmdUTrim, а свойству Caption -значение UTrim$.
10. Сделайте кнопку cmdUTrim активной и нажмите Ctrl+C, чтобы скопировать ее в буфер обмена.
11. Щелкните на рамке fraFunctions и нажмите Ctrl+V, чтобы вставить копию кнопки в рамку. На вопрос о том, желаете ли вы создать массив элементов, ответьте отрицательно (No).
12. Расположите новую кнопку в правом верхнем углу рамки и выровняйте ее по одной линии с кнопками cmdUTrim и cmdSpellMonth.
13. Задайте свойству Name новой кнопки значение cmdCubeRoot, а свойству Caption -значение C&ube Root$. Готовая форма должна выглядеть так, как показано на рис. 12.15.
Рис. 12.15. Форма Debug Toolbox в конструкторе форм
Визуальный интерфейс готов. Сохраните свой проект, чтобы не потерять внесенные изменения. Перейдем к написанию программы:
1. Вставьте следующий фрагмент в процедуру события Form_Resize формы frmMain:
Private Sub Form_Resize()
' Расположить список в верхней половине формы.
' Растянуть его на ширину формы и 1/2 высоты.
lstResults.Move 0, 0, ScaleWidth, ScaleHeight / 2
' Расположить рамку в нижней половине формы.
' Растянуть ее на ширину формы и 1/2 высоты.
fraFunctions.Move 0, ScaleHeight /2, ScaleWidth,ScaleHeight / 2
End Sub
2. Первое, что мы делаем после нажатия кнопки, — заносим в список имя тестируемой процедуры. Для этой цели используется процедура ShowProcedure(). Добавьте эту процедуру в секцию (General)(Declarations) формы frmMain:
Private Sub ShowProcedure(Proc As String)
' Включить имя процедуры в список
lstResults.AddItem " Процедура: " & vbTab & Ргос
End Sub
3. Нам также понадобится функция для получения исходных данных от пользователя. Добавьте следующую функцию в секцию(Generа1)(Dес1агаtions) формы frmMain:
Private Function GetInput(Msg As String) As Variant
Dim rc As Variant
'Запросить исходные данные у пользователя
rc = InputBox(Msg, "Исходные данные")
lstResults.AddItem "Исходные данные: " & rc
Вернуть строку с исходными данными
GetInput = rc
End Function
4. Добавьте в frmMain следующую функцию:
Private Sub ShowResults(result As Variant)
'Включить результат в список
lstResults.AddItem "Результат: " & vbTab & result
End Sub
5. Сохраните проект.
После создания интерфейсной формы мы переходим к добавлению процедур в проект:
1. Вставьте в проект новый программный модуль — щелкните правой кнопкой мыши в окне проекта и выполните команду Add Module из контекстного меню.
2. Задайте свойству Name нового программного модуля значение TestProcedures.
Начнем с функции SpellMonth(). Как нетрудно догадаться по названию, эта функция возвращает название месяца по его номеру. Например, если вызвать ее с аргументом 5, функция возвращает строку Май.
3. Добавьте следующую функцию в секцию (General)(Declarations) модуля TestProcedures:
Public Function SpellMonth(MonthNumber As Integer) As String
Dim rc As String
'Получить название месяца
rc = Format$(MonthNumber & "/1/1998", "mmmm")
'Возвратить номер месяца
SpellMonth = rc
End Function
Наша следующая функция будет называться UTrim$(). В ней стандартная функция Visual Basic UCase$(), преобразующая строки в верхний регистр, объединяет-
ся с функцией Trim$(), которая удаляет ведущие и завершающие пробелы из строки. Строго говоря, функция UTrim$(txt) эквивалентна UCase$(Trim$(txt)). При совместном использовании эти функции образуют мощное и в высшей степени полезное средство для проверки данных. С их помощью можно сравнить две строки и убедиться в идентичности их содержимого без учета регистра. Например:
If UTrim$(MyInput) = UTrim$(DatabaseValue) Then...
' Данные идентичны
Else
' Данные отличаются
End If
4. Добавьте функцию UTrim$() в программный модуль:
Public Function UTrim$(Txt As String) As String
' Преобразовать в верхний регистр
' и удалить все ведущие и завершающие пробелы.
Txt = UCase$(Trim$(Txt))
End Function
5. Если вы создали программную библиотеку в уроке 4, включите в проект модуль MyLibrary и перейдите к шагу 7; в противном случае продолжайте выполнять шаг 6.
6. Добавьте следующую функцию в программный модуль:
Public Function CubeRoot(x As.Double) As Double
If x = 0 Then
CubeRoot = 0
Exit Function
End If
CubeRoot = 10 " ((Log(Abs(x)) / Log(10)) / 3)
If x < 0 Then
CubeRoot = -CubeRoot
End If
End Function
7. Сохраните проект.
Мы написали процедуры, которые можно тестировать. Теперь необходимо включить в интерфейсную форму код для их тестирования. Во время ввода программы вы наверняка обратите внимание на сходство приведенных фрагментов. Все они выполняют общие задачи:
О вывод имени процедуры в списке;
О получение исходных данных от пользователя;
О вывод исходных данных в списке;
О передачу исходных данных процедуре;
О вывод результатов.
Начнем с процедуры, вызывающей функцию SpellMonth():
1. Добавьте следующий фрагмент в процедуру события cmdSpellMonth_Click:
Private Sub cmdSpellMonth_Click()
Dim гс As Integer
Dim result As String
'Вывести имя процедуры в списке
ShowProcedure "SpellMonth"
'Получить исходные данные от пользователя
rc = GetInput("Bведитe номер месяца:")
'Получить результаты
rc = SpellMonth(rc)
'Вывести результаты в списке
ShowResults result
End Sub
2. Следующий фрагмент предназначен для тестирования функции UTrim$():
Private Sub cmdUTrim_Click()
Dim rc As String
Dim result As String
'Вывести имя процедуры в списке
ShowProcedure "UTrim$"
'Получить исходные данные от пользователя
rc = GetInput("Bведитe строку:")
'Получить результаты
rc = UTrim$(rc)
'Вывести результаты в списке
ShowResults result
End Sub
3. Наконец, последняя процедура тестирует функцию CubeRoot():
Private Sub cmdCubeRoot_Click()
Dim rc As Double
Dim result As String
'Вывести имя процедуры в списке
ShowProcedure "CubeRoot"
'Получить исходные данные от пользователя
rc = GetInput("Введите число:")
'Получить результаты
rc = CubeRoot(rc)
'Вывести результаты в списке
ShowResults result
End Sub
4. Сохраните и запустите проект.
ПОДСКАЗКА Старайтесь почаще сохранять свою работу. Это особенно важно при написании критически важных частей приложения, а также при вводе фрагментов, которые будет трудно ввести заново. Словом, сохраняйтесь как можно чаще!
Итак, у нас есть как интерфейсная форма, так и функции, которые можно вызвать и проверить полученные результаты. Лучший способ тестирования — ввести некоторые эталонные данные, рассчитать результат вручную, а затем повторить вычисления на компьютере. Если процедуры работают правильно, результаты, полученные от компьютера, совпадут с результатами исходных вычислений. Следующий пример поможет вам лучше понять, о чем идет речь.
Для тестирования функции SpellMonth() нам потребуются исходные данные, по которым мы будем проверять правильность результата. Воспользуемся следующей таблицей.
Номер месяца | Название месяца |
Январь | |
Февраль | |
Март | |
Апрель | |
Май | |
Июнь | |
Июль | |
Август | |
Сентябрь | |
Октябрь | |
Ноябрь | |
Декабрь |
1. Нажмите кнопку SpellMonth. В списке выводится строка Процедура: SpellMonth, а на экране появляется окно ввода.
2. Введите в диалоговом окне значение 10 и нажмите кнопку ОК. В результате (см. рис. 12.16) функция SpellMonth возвращает строку Октябрь. Из приведенной ранее таблицы видно, что десятым месяцем действительно является октябрь. Из этого можно заключить, что функция работает правильно.
Рис. 12.16. Тестирование функции SpellMonth()
3. Снова нажмите кнопку SpellMonth.
4. Введите в диалоговом окне значение 7 и нажмите кнопку ОК. В списке должна быть выведена строка Июль.
5. Снова нажмите кнопку SpellMonth.
6. Введите в диалоговом окне значение 1 и нажмите кнопку ОК. В списке должна быть выведена строка Январь.
Пока функция SpellMonth() работает нормально. Прежде чем переходить к другой функции, давайте протестируем ее еще один раз.
7. Снова нажмите кнопку SpellMonth.
8. Введите в диалоговом окне значение 15 и нажмите кнопку ОК.
Хотя год состоит всего из 12 месяцев, функция все равно возвращает значение Январь. Что делать? Считать, что пятнадцатым месяцем на самом деле должен быть 15-12, то есть третий месяц — март? Или ограничить пользователя значениями от 1 до 12, как это было сделано в таблице с тестовыми данными? Давайте включим в функцию SpellMonth() оператор If...Then...Else, чтобы ограничиться только указанным интервалом.
9. Остановите приложение Debug Toolbox, чтобы внести необходимые исправления в функцию SpellMonth().
10. Измените функцию SpellMonth() и приведите ее к следующему виду:
Public Function SpellMonth(MonthNumber As Integer) As String
Dim rc As String
' Убедиться в том, что значение MonthNumber
'находится в интервале 1 - 12
If MonthNumber > 0 And MonthNumber < 13 Then
'Получить название месяца
rc = Format$(MonthNumber & "/1/1998", "mmmm")
'Возвратить номер месяца
SpellMonth = rc
Else
' Возвратить сообщение об ошибке
SpellMonth = "Ошибка: недопустимый номер месяца!"
End If
End Function
11. Сохраните и запустите проект.
12. Нажмите кнопку SpellMonth.
13. Введите в диалоговом окне значение 15 и нажмите кнопку ОК. На этот раз будет выведено сообщение об ошибке.
ПОДСКАЗКА Как показывает предыдущий пример, функцию следует тестировать многократно. Если бы мы ограничились одним или двумя месяцами, то так и не обнаружили бы логической ошибки в SpellMonth(). Функцию можно считать надежной лишь после многочисленных проверок. Обязательно проверьте, как она будет реагировать на неожиданные значения. Всегда находится пользователь, который совершает какую-нибудь особенную глупость, -если ваше приложение не будет готово к этому, возникнет аварийная ситуация!
Мы успешно протестировали и исправили функцию SpellMonth(). Перейдем к тестированию функции UTrim$(). Давайте создадим таблицу с несколькими тестовыми строками и сравним результаты. На этот раз тест будет состоять всего из трех значений.
Неформатированная строка | Отформатированная строка |
Предложение с символами обоих регистров | ПРЕДЛОЖЕНИЕ С СИМВОЛАМИ ОБОИХ РЕГИСТРОВ |
Несколько ведущих пробелов | НЕСКОЛЬКО ВЕДУЩИХ ПРОБЕЛОВ |
ОТЛАДКА - увлекательное занятие! | ОТЛАДКА - УВЛЕКАТЕЛЬНОЕ ЗАНЯТИЕ! |
1. Нажмите кнопку UTrim$, чтобы приступить к тестированию функции UTrim$().
2. Введите первую строку из таблицы, Предложение с символами обоих регистров. В результате должна быть получена строка ПРЕДЛОЖЕНИЕ С СИМВОЛАМИ ОБОИХ РЕГИСТРОВ.
3. Нажмите кнопку ОК.
4. Как видно из рис. 12.17, результата нет вообще. Очевидно, функция работает не так, как мы рассчитывали. Остановите программу и откройте окно программы для функции UTrim$().
Рис. 12.17. Функция UТriт$ возвращает неожиданные резулътаты
На первый взгляд функция работает нормально — переменная Txt преобразуется в UCase$(Trim$(Txt)).
Public Function UTrim$(Txt As String) As String
'Преобразовать в верхний регистр
'и удалить все ведущие и завершающие пробелы.
Txt = UCase$(Trim$(Txt))
End Function
Однако после более внимательного анализа выясняется, что мы забываем возвратить значение Txt из функции UTrim$.
5. Замените последнюю строку функции (находящуюся перед End Function) следующей:
UTrim = UCase$(Trim$(Txt))
6. Сохраните проект и запустите его.
7. Снова нажмите кнопку UTrim$, чтобы продолжить тестирование функции UTrim$().
8. Введите первую строку из таблицы, Предложение с символами обоих регистров. В результате должна быть получена строка ПРЕДЛОЖЕНИЕ С СИМВОЛАМИ ОБОИХ РЕГИСТРОВ.
9. Нажмите кнопку ОК. Функция работает как положено — полный успех!
10. Снова нажмите кнопку UTrim$ и введите в диалоговом окне строку «Несколько ведущих пробелов». Не набирайте кавычки — в данном случае они лишь показывают, что перед первым словом должны находиться четыре-пять пробелов (рис. 12.18).
11. Нажмите кнопку OK, чтобы просмотреть результат.
12. Снова нажмите кнопку UTrim$, чтобы в последний раз проверить функцию
UTrim$().
13. Введите в диалоговом окне строку ОТЛАДКА - увлекательное занятие!
14. Нажмите кнопку ОК.
15. Как видно из рис. 12.19, после исправления ошибки функция UTrim$() работает правильно. В каждом из трех тестов были получены именно те результаты, на которые мы рассчитывали.
Рис. 12.18. Строка с ведущими пробелами
Вероятно, вы уже поняли, что перед тем, как включать функции в приложение, их необходимо тщательно протестировать. Описанная методика помогает систематически проверить работу процедур и сравнить результаты.
Мы приближаемся к последней стадии тестирования программы Debug Toolbox. Пора заняться функцией CubeRoot. Мы встречались с ней в уроке 4 во время изучения программных модулей и модулей классов. Давайте проверим, правильно ли работает эта функция. Ниже приведена таблица с тестовыми данными. Я выбрал произвольные числа, вычислил их кубические корни на калькуляторе и записал результаты.
Рис. 12.19. Результаты всех трех тестов функции UTrim$()
Число | Ожидаемое значение кубического корня |
2.080083823 | |
6.694329501 |
1. Нажмите кнопку CubeRoot.
2. Введите значение 1 и нажмите кнопку ОК. Результат должен быть равен 1.
3. Снова нажмите кнопку CubeRoot.
4. Введите значение 8 и нажмите кнопку ОК. Результат должен быть равен 2.
5. Снова нажмите кнопку CubeRoot, чтобы проверить третье число из таблицы.
6. Введите значение 9 и нажмите кнопку ОК. Результат должен быть равен 2.0800838230519.
7. Нажмите кнопку CubeRoot.
8. Введите значение 27 и нажмите кнопку ОК. Результат должен быть равен 3.
9. В последний раз нажмите кнопку CubeRoot.
10. Введите значение 300 и нажмите кнопку ОК. Результат должен быть равен 6.69432950082169.
Как видите, результаты совпали с теми, которые были получены на калькуляторе. Следовательно, можно быть уверенным, что функция CubeRoot() работает нормально и ее стоит сохранить в программной библиотеке. Две другие функции, ShowMonth() и UTrim$(), тоже были отлажены и работают надежно. При желании их тоже можно включить в библиотеку, они пригодятся при сравнении строковых данных и работе с датами.
Урок подошел к концу. Теперь ваших знаний хватит для успешной отладки любого приложения, которым вы будете заниматься. Помните о том, что при разработке собственных приложений необходимо документировать программу структурированными комментариями и заметками на полях (ведь вы сначала создаете набросок программы на бумаге, не правда ли?). Структурированный код существенно упрощает чтение программы, сокращает время разработки и повышает надежность программы. Комментарии и соглашения об именах также заметно уменьшают время отладки. Привыкайте документировать свои программы сейчас, и вы избавитесь от многих неприятностей в будущем!
ПРИМЕЧАНИЕ Отладка начинается с профилактических мер. Единый стиль использования комментариев, структурное программирование кода и соблюдение соглашений об именах — ключ к ускорению разработки приложений. Помните старую поговорку: «Семь раз отмерь, один раз отрежь!»
Дата добавления: 2015-07-20; просмотров: 74 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Работа в окне непосредственных вычислений | | | Справочных файлов |