В каждом тестовом задании может быть несколько вариантов ответа. После проведения теста студенты могут попробовать обосновать свои неверные ответы.
В основные обязанности тестировщика входят:
Ответ: 1, 3, 5
Одному тест-требованию может соответствовать:
Ответ: 2
Два тестовых примера проверяют один и тот же класс эквивалентности:
Ответ: 2, 4
Сколько классов эквивалентности в общем случае выделяют для функции с двумя целочисленными входными параметрами и одним целочисленном выходным значением?
Ответ: 3
Ответ: 1, 3, 4
Студенты приносят заполненные отчеты об ошибках для тех модулей, которые они тестировали. Преподаватель оценивает их тест-планы и смотрит, удалось ли студентам найти все допущенные в методах ошибки.
Основной объем тестирования практически любой сложной системы обычно выполняется в автоматическом режиме. Кроме того, тестируемая система обычно разбивается на отдельные модули, каждый из которых тестируется вначале отдельно от других, затем в комплексе.
Это означает, что для выполнения тестирования необходимо создать некоторую среду, которая обеспечит запуск и выполнение тестируемого модуля, передаст ему входные данные, соберет реальные выходные данные, полученные в результате работы системы на заданных входных данных (рис. 7.1). После этого среда должна сравнить реальные выходные данные с ожидаемыми и на основании данного сравнения сделать вывод о соответствии поведения модуля заданному.
Тестовое окружение также может использоваться для отчуждения отдельных модулей системы от всей системы. Разделение модулей системы на ранних этапах тестирования позволяет более точно локализовать проблемы, возникающие в их программном коде. Для поддержки работы модуля в отрыве от системы тестовое окружение должно моделировать поведение всех модулей, к функциям или данным которых обращается тестируемый модуль.
Поскольку тестовое окружение само является программой (причем, часто реализованной не на том языке программирования, на котором написана система), оно тоже должно быть протестировано. Целью тестирования тестового окружения является доказательство того, что тестовое окружение никаким образом не искажает выполнение тестируемого модуля и адекватно моделирует поведение системы.
(рис 7.1) Обобщенная схема среды тестированияТестовое окружение для программного кода на структурных языках программирования состоит из двух компонентов – драйвера, который обеспечивает запуск и выполнение тестируемого модуля, и заглушек, которые моделируют функции, вызываемые из данного модуля. Разработка тестового драйвера представляет собой отдельную задачу тестирования, сам драйвер должен быть протестирован, дабы исключить неверное тестирование. Драйвер и заглушки могут иметь различные уровни сложности, требуемый уровень сложности выбирается в зависимости от сложности тестируемого модуля и уровня тестирования. Так, драйвер может выполнять следующие функции:
Заглушки могут выполнять следующие функции:
Тестовое окружение для объектно-ориентированного ПО выполняет те же самые функции, что и для структурных программ (на процедурных языках). Однако, оно имеет некоторые особенности, связанные с применением наследования и инкапсуляции.
Если при тестировании структурных программ минимальным тестируемым объектом является функция, то в объектно-ориентированным ПО минимальным объектом является класс. При применении принципа инкапсуляции все внутренние данные класса и некоторая часть его методов недоступна извне. В этом случае тестировщик лишен возможности обращаться в своих тестах к данным класса и произвольным образом вызывать методы; единственное, что ему доступно – вызывать методы внешнего интерфейса класса.
Существует несколько подходов к тестированию классов, каждый из них накладывает свои ограничения на структуру драйвера и заглушек.
Основное достоинство первых двух методов – при их использовании класс работает точно таким же образом, как в реальной системе. Однако в этом случае нельзя гарантировать того, что в процессе тестирования будет выполнен весь программный код класса и не останется непротестированных методов.
Основной недостаток 3-го метода – после изменения исходных текстов тестируемого модуля нельзя дать гарантии того, что класс будет вести себя таким же образом, как и исходный. В частности, это связано с тем, что изменение защиты данных класса влияет на наследование данных и методов другими классами.
Тестирование наследования – отдельная сложная задача в объектно-ориентированных системах. После того, как протестирован базовый класс, необходимо тестировать классы-потомки. Однако, для базового класса нельзя создавать заглушки, т.к. в этом случае можно пропустить возможные проблемы полиморфизма. Если класс-потомок использует методы базового класса для обработки собственных данных, необходимо убедиться в том, что эти методы работают.
Таким образом, иерархия классов может тестироваться сверху вниз, начиная от базового класса. Тестовое окружение при этом может меняться для каждой тестируемой конфигурации классов.
Тесты, проделанные нами на прошлом семинаре, как правило, проводятся не вручную. Для целей тестирования пишут специальную программу — тестовый драйвер, который и проводит тестирование. Более того, такие программы часто пишутся на другом языке, нежели тестируемая программа, или создаются автоматически, с помощью специальных утилит.
На этом семинаре мы сами напишем простой тестовый драйвер на C# для тестирования функций "Калькулятора", используя спецификацию второго семинара.
Замечание. Код программы слегка изменен для упрощения компиляции отдельных модулей. Так, исключена работа с переменной Program.res, а класс CalcClass объявлен как public.
Для начала рассмотрим функцию деления. Тест-требования к ней мы уже составили. Для простоты будем пользоваться лишь четырьмя общими тест- требованиями.
Составим программу:
private void buttonStartDel_Click(object sender, EventArgs e)
{
try
{
richTextBox1.Text = "";
richTextBox1.Text += "Test Case 1\n";
richTextBox1.Text += "Входные данные: a= 78508, b = -304\n";
richTextBox1.Text += "Ожидаемый результат: res = 78204
error = \"\""+"\n";
int res = CalcClass.Add(78508, -304);
string error = CalcClass.lastError;
richTextBox1.Text += "Код ошибки: " + error + "\n";
richTextBox1.Text += "Получившийся результат: " +"res = "+
res.ToString() +" error = "+error.ToString() +"\n";
if (res == 78204 error == "")
{
richTextBox1.Text += "Тест пройден\n\n";
}
else
{
richTextBox1.Text += "Тест не пройден\n\n";
}
}
catch (Exception ex)
{
richTextBox1.Text += "Перехвачено исключение: " +
ex.ToString() + "\nТест не пройден.\n";
}
try
{
richTextBox1.Text += "Test Case 2\n";
richTextBox1.Text += "Входные данные: a= -2850800078, b =
3000000000\n";
richTextBox1.Text += "Ожидаемый результат: res = 0 error =
\"Error 06\"\n";
int res = CalcClass.Add(-2850800078, 3000000000);
string error = CalcClass.lastError;
richTextBox1.Text += "Код ошибки: " + error + "\n";
richTextBox1.Text += "Получившийся результат: " + "res = " +
res.ToString() + " error = " + error.ToString() + "\n";
if (res == 0 error == "Error 06")
{
richTextBox1.Text += "Тест пройден\n\n";
}
else
{
richTextBox1.Text += "Тест не пройден\n\n";
}
}
catch (Exception ex)
{
richTextBox1.Text += "Перехвачено исключение: " +
ex.ToString() + "\nТест не пройден.\n";
}
try
{
richTextBox1.Text += "Test Case 3\n";
richTextBox1.Text += "Входные данные: a= 3000000000, b = -
2850800078\n";
richTextBox1.Text += "Ожидаемый результат: res = 0 error =
\"Error 06\"\n";
int res = CalcClass.Add(3000000000, -2850800078);
string error = CalcClass.lastError;
richTextBox1.Text += "Код ошибки: " + error+"\n";
richTextBox1.Text += "Получившийся результат: " + "res = " +
res.ToString() + " error = " + error.ToString() + "\n";
if (res == 0 error == "Error 06")
{
richTextBox1.Text += "Тест пройден\n\n";
}
else
{
richTextBox1.Text += "Тест не пройден\n\n";
}
}
catch (Exception ex)
{
richTextBox1.Text += "Перехвачено исключение: " +
ex.ToString() + "\nТест не пройден.\n";
}
try
{
richTextBox1.Text += "Test Case 4\n";
richTextBox1.Text += "Входные данные: a= 2000000000, b =
2000000000\n";
richTextBox1.Text += "Ожидаемый результат: res = 0 error =
\"Error 06\"\n";
int res = CalcClass.Add(2000000000, 2000000000);
string error = CalcClass.lastError;
richTextBox1.Text += "Код ошибки: " + error +"\n";
richTextBox1.Text += "Получившийся результат: " + "res = " +
res.ToString() + " error = " + error.ToString() + "\n";
if (res == 0 error == "Error 06")
{
richTextBox1.Text += "Тест пройден\n\n";
}
else
{
richTextBox1.Text += "Тест не пройден\n\n";
}
}
catch (Exception ex)
{
richTextBox1.Text += "Перехвачено исключение: " +
ex.ToString() + "\nТест не пройден.\n";
}
}
Каждый тестовый пример находится внутри блока try-catch для того, чтобы перехватить любое сгенерированное исключение внутри методов Add().
При этом файл CalcClass.dll, в котором и реализованы все математические методы, необходимо добавить в References проекта.
Проведем тестирование и получим следующий результат:
Test Case 1 Входные данные: a= 78508, b = -304 Ожидаемый результат: res = 78204 error = "" Код ошибки: Получившийся результат: res = 78204 error = Тест пройден Test Case 2 Входные данные: a= -2850800078, b = 3000000000 Ожидаемый результат: res = 0 error = "Error 06" Код ошибки: Error 06 Получившийся результат: res = 0 error = Error 06 Тест пройден Test Case 3 Входные данные: a= 3000000000, b = -2850800078 Ожидаемый результат: res = 0 error = "Error 06" Код ошибки: Error 06 Получившийся результат: res = 0 error = Error 06 Тест пройден Test Case 4 Входные данные: a= 2000000000, b = 2000000000 Ожидаемый результат: res = 0 error = "Error 06" Код ошибки: Error 06 Получившийся результат: res = 0 error = Error 06 Тест пройден
Точно такой же результат мы бы получили и при
Замечание. Мы считаем, что тестовый драйвер сам не содержит ошибок. Тестирование тестового драйвера выходит за пределы изучаемой темы.
Будут выданы .dll файлы, которые нужно протестировать методом "черного ящика", и пример тестового драйвера.
Составить тест-план и провести модульное тестирование следующих методов:
Нахождение остатка.
/// <summary>
/// Деление по модулю
/// </summary>
/// <param name="a">делимое</param>
/// <param name="b">делитель</param>
/// <returns>остаток</returns>
public static int Mod(long a, long b)
Унарный плюс.
/// <summary>
/// унарный плюс
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
public static int ABS(long a)
Унарный минус.
/// <summary>
/// унарный минус
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
public static int IABS(long a)
Вычитание.
/// <summary>
/// вычитание
/// </summary>
/// <param name="a">уменьшаемое</param>
/// <param name="b">вычитаемое</param>
/// <returns>разность</returns>
public static int Sub(long a, long b)
Умножение.
/// <summary>
/// умножение
/// </summary>
/// <param name="a">множитель</param>
/// <param name="b">множитель</param>
/// <returns>произведение</returns>
public static int Mult(long a, long b)
Деление.
/// <summary>
/// частное
/// </summary>
/// <param name="a">делимое</param>
/// <param name="b">делитель</param>
/// <returns>частное</returns>
public static int Div(long a, long b)
В каждом тестовом задании может быть несколько вариантов ответа. После проведения теста студенты могут попробовать обосновать свои неверные ответы.
В основные обязанности тестировщика входят:
Ответ: 1, 3, 5
Одному тест-требованию может соответствовать:
Ответ: 2
Два тестовых примера проверяют один и тот же класс эквивалентности:
Ответ: 2, 4
Сколько классов эквивалентности в общем случае выделяют для функции с двумя целочисленными входными параметрами и одним целочисленном выходным значением?
Ответ: 3
Ответ: 1, 3, 4
Студенты приносят заполненные отчеты об ошибках для тех модулей, которые они тестировали. Преподаватель оценивает их тест-планы и смотрит, удалось ли студентам найти все допущенные в методах ошибки.
Основной объем тестирования практически любой сложной системы обычно выполняется в автоматическом режиме. Кроме того, тестируемая система обычно разбивается на отдельные модули, каждый из которых тестируется вначале отдельно от других, затем в комплексе.
Это означает, что для выполнения тестирования необходимо создать некоторую среду, которая обеспечит запуск и выполнение тестируемого модуля, передаст ему входные данные, соберет реальные выходные данные, полученные в результате работы системы на заданных входных данных (рис. 7.1). После этого среда должна сравнить реальные выходные данные с ожидаемыми и на основании данного сравнения сделать вывод о соответствии поведения модуля заданному.
Тестовое окружение также может использоваться для отчуждения отдельных модулей системы от всей системы. Разделение модулей системы на ранних этапах тестирования позволяет более точно локализовать проблемы, возникающие в их программном коде. Для поддержки работы модуля в отрыве от системы тестовое окружение должно моделировать поведение всех модулей, к функциям или данным которых обращается тестируемый модуль.
Поскольку тестовое окружение само является программой (причем, часто реализованной не на том языке программирования, на котором написана система), оно тоже должно быть протестировано. Целью тестирования тестового окружения является доказательство того, что тестовое окружение никаким образом не искажает выполнение тестируемого модуля и адекватно моделирует поведение системы.
(рис 7.1) Обобщенная схема среды тестированияТестовое окружение для программного кода на структурных языках программирования состоит из двух компонентов – драйвера, который обеспечивает запуск и выполнение тестируемого модуля, и заглушек, которые моделируют функции, вызываемые из данного модуля. Разработка тестового драйвера представляет собой отдельную задачу тестирования, сам драйвер должен быть протестирован, дабы исключить неверное тестирование. Драйвер и заглушки могут иметь различные уровни сложности, требуемый уровень сложности выбирается в зависимости от сложности тестируемого модуля и уровня тестирования. Так, драйвер может выполнять следующие функции:
Заглушки могут выполнять следующие функции:
Тестовое окружение для объектно-ориентированного ПО выполняет те же самые функции, что и для структурных программ (на процедурных языках). Однако, оно имеет некоторые особенности, связанные с применением наследования и инкапсуляции.
Если при тестировании структурных программ минимальным тестируемым объектом является функция, то в объектно-ориентированным ПО минимальным объектом является класс. При применении принципа инкапсуляции все внутренние данные класса и некоторая часть его методов недоступна извне. В этом случае тестировщик лишен возможности обращаться в своих тестах к данным класса и произвольным образом вызывать методы; единственное, что ему доступно – вызывать методы внешнего интерфейса класса.
Существует несколько подходов к тестированию классов, каждый из них накладывает свои ограничения на структуру драйвера и заглушек.
Основное достоинство первых двух методов – при их использовании класс работает точно таким же образом, как в реальной системе. Однако в этом случае нельзя гарантировать того, что в процессе тестирования будет выполнен весь программный код класса и не останется непротестированных методов.
Основной недостаток 3-го метода – после изменения исходных текстов тестируемого модуля нельзя дать гарантии того, что класс будет вести себя таким же образом, как и исходный. В частности, это связано с тем, что изменение защиты данных класса влияет на наследование данных и методов другими классами.
Тестирование наследования – отдельная сложная задача в объектно-ориентированных системах. После того, как протестирован базовый класс, необходимо тестировать классы-потомки. Однако, для базового класса нельзя создавать заглушки, т.к. в этом случае можно пропустить возможные проблемы полиморфизма. Если класс-потомок использует методы базового класса для обработки собственных данных, необходимо убедиться в том, что эти методы работают.
Таким образом, иерархия классов может тестироваться сверху вниз, начиная от базового класса. Тестовое окружение при этом может меняться для каждой тестируемой конфигурации классов.
Тесты, проделанные нами на прошлом семинаре, как правило, проводятся не вручную. Для целей тестирования пишут специальную программу — тестовый драйвер, который и проводит тестирование. Более того, такие программы часто пишутся на другом языке, нежели тестируемая программа, или создаются автоматически, с помощью специальных утилит.
На этом семинаре мы сами напишем простой тестовый драйвер на C# для тестирования функций "Калькулятора", используя спецификацию второго семинара.
Замечание. Код программы слегка изменен для упрощения компиляции отдельных модулей. Так, исключена работа с переменной Program.res, а класс CalcClass объявлен как public.
Для начала рассмотрим функцию деления. Тест-требования к ней мы уже составили. Для простоты будем пользоваться лишь четырьмя общими тест- требованиями.
Составим программу:
private void buttonStartDel_Click(object sender, EventArgs e)
{
try
{
richTextBox1.Text = "";
richTextBox1.Text += "Test Case 1\n";
richTextBox1.Text += "Входные данные: a= 78508, b = -304\n";
richTextBox1.Text += "Ожидаемый результат: res = 78204
error = \"\""+"\n";
int res = CalcClass.Add(78508, -304);
string error = CalcClass.lastError;
richTextBox1.Text += "Код ошибки: " + error + "\n";
richTextBox1.Text += "Получившийся результат: " +"res = "+
res.ToString() +" error = "+error.ToString() +"\n";
if (res == 78204 error == "")
{
richTextBox1.Text += "Тест пройден\n\n";
}
else
{
richTextBox1.Text += "Тест не пройден\n\n";
}
}
catch (Exception ex)
{
richTextBox1.Text += "Перехвачено исключение: " +
ex.ToString() + "\nТест не пройден.\n";
}
try
{
richTextBox1.Text += "Test Case 2\n";
richTextBox1.Text += "Входные данные: a= -2850800078, b =
3000000000\n";
richTextBox1.Text += "Ожидаемый результат: res = 0 error =
\"Error 06\"\n";
int res = CalcClass.Add(-2850800078, 3000000000);
string error = CalcClass.lastError;
richTextBox1.Text += "Код ошибки: " + error + "\n";
richTextBox1.Text += "Получившийся результат: " + "res = " +
res.ToString() + " error = " + error.ToString() + "\n";
if (res == 0 error == "Error 06")
{
richTextBox1.Text += "Тест пройден\n\n";
}
else
{
richTextBox1.Text += "Тест не пройден\n\n";
}
}
catch (Exception ex)
{
richTextBox1.Text += "Перехвачено исключение: " +
ex.ToString() + "\nТест не пройден.\n";
}
try
{
richTextBox1.Text += "Test Case 3\n";
richTextBox1.Text += "Входные данные: a= 3000000000, b = -
2850800078\n";
richTextBox1.Text += "Ожидаемый результат: res = 0 error =
\"Error 06\"\n";
int res = CalcClass.Add(3000000000, -2850800078);
string error = CalcClass.lastError;
richTextBox1.Text += "Код ошибки: " + error+"\n";
richTextBox1.Text += "Получившийся результат: " + "res = " +
res.ToString() + " error = " + error.ToString() + "\n";
if (res == 0 error == "Error 06")
{
richTextBox1.Text += "Тест пройден\n\n";
}
else
{
richTextBox1.Text += "Тест не пройден\n\n";
}
}
catch (Exception ex)
{
richTextBox1.Text += "Перехвачено исключение: " +
ex.ToString() + "\nТест не пройден.\n";
}
try
{
richTextBox1.Text += "Test Case 4\n";
richTextBox1.Text += "Входные данные: a= 2000000000, b =
2000000000\n";
richTextBox1.Text += "Ожидаемый результат: res = 0 error =
\"Error 06\"\n";
int res = CalcClass.Add(2000000000, 2000000000);
string error = CalcClass.lastError;
richTextBox1.Text += "Код ошибки: " + error +"\n";
richTextBox1.Text += "Получившийся результат: " + "res = " +
res.ToString() + " error = " + error.ToString() + "\n";
if (res == 0 error == "Error 06")
{
richTextBox1.Text += "Тест пройден\n\n";
}
else
{
richTextBox1.Text += "Тест не пройден\n\n";
}
}
catch (Exception ex)
{
richTextBox1.Text += "Перехвачено исключение: " +
ex.ToString() + "\nТест не пройден.\n";
}
}
Каждый тестовый пример находится внутри блока try-catch для того, чтобы перехватить любое сгенерированное исключение внутри методов Add().
При этом файл CalcClass.dll, в котором и реализованы все математические методы, необходимо добавить в References проекта.
Проведем тестирование и получим следующий результат:
Test Case 1 Входные данные: a= 78508, b = -304 Ожидаемый результат: res = 78204 error = "" Код ошибки: Получившийся результат: res = 78204 error = Тест пройден Test Case 2 Входные данные: a= -2850800078, b = 3000000000 Ожидаемый результат: res = 0 error = "Error 06" Код ошибки: Error 06 Получившийся результат: res = 0 error = Error 06 Тест пройден Test Case 3 Входные данные: a= 3000000000, b = -2850800078 Ожидаемый результат: res = 0 error = "Error 06" Код ошибки: Error 06 Получившийся результат: res = 0 error = Error 06 Тест пройден Test Case 4 Входные данные: a= 2000000000, b = 2000000000 Ожидаемый результат: res = 0 error = "Error 06" Код ошибки: Error 06 Получившийся результат: res = 0 error = Error 06 Тест пройден
Точно такой же результат мы бы получили и при
Замечание. Мы считаем, что тестовый драйвер сам не содержит ошибок. Тестирование тестового драйвера выходит за пределы изучаемой темы.
Будут выданы .dll файлы, которые нужно протестировать методом "черного ящика", и пример тестового драйвера.
Составить тест-план и провести модульное тестирование следующих методов:
Нахождение остатка.
/// <summary>
/// Деление по модулю
/// </summary>
/// <param name="a">делимое</param>
/// <param name="b">делитель</param>
/// <returns>остаток</returns>
public static int Mod(long a, long b)
Унарный плюс.
/// <summary>
/// унарный плюс
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
public static int ABS(long a)
Унарный минус.
/// <summary>
/// унарный минус
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
public static int IABS(long a)
Вычитание.
/// <summary>
/// вычитание
/// </summary>
/// <param name="a">уменьшаемое</param>
/// <param name="b">вычитаемое</param>
/// <returns>разность</returns>
public static int Sub(long a, long b)
Умножение.
/// <summary>
/// умножение
/// </summary>
/// <param name="a">множитель</param>
/// <param name="b">множитель</param>
/// <returns>произведение</returns>
public static int Mult(long a, long b)
Деление.
/// <summary>
/// частное
/// </summary>
/// <param name="a">делимое</param>
/// <param name="b">делитель</param>
/// <returns>частное</returns>
public static int Div(long a, long b)
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.