Upload
igor-shkulipa
View
48
Download
2
Embed Size (px)
Citation preview
Темы лекции: Unit-тестирование.
Практическое задание: Unit-тестирование.
Тренер: Игорь Шкулипа, к.т.н.
Платформа .Net и язык программирования C#.
Занятие 17
http://www.slideshare.net/IgorShkulipa 2
Модульное тестирование
Unit testing (юнит тестирование или модульное тестирование) —заключается в изолированной проверке каждого отдельного элементапутем запуска тестов в искусственной среде.
Unit (Элемент) — наименьший компонент, который можноскомпилировать.
Драйверы — модули тестов, которые запускают тестируемый элемент.
Заглушки — заменяют недостающие компоненты, которые вызываютсяэлементом и выполняют следующие действия:
• возвращаются к элементу, не выполняя никаких других действий;• отображают трассировочное сообщение и иногда предлагают
тестировщику продолжить тестирование;• возвращают постоянное значение или предлагают тестеру самому
ввести возвращаемое значение;• осуществляют упрощенную реализацию недостающей
компоненты;• имитируют исключительные или аварийные условия.
http://www.slideshare.net/IgorShkulipa 3
Подходы к unit-тестированию
White-box testing. Для конструирования тестов используютсявнутренняя структура кода и управляющая логика. При этом существуетвероятность, что код будет проверяться так, как он был написан, а это негарантирует корректность логики.
Black-box testing. Для конструирования тестов используются требованияи спецификации ПО.
Недостатки:• таким способом невозможно найти взаимоуничтожающихся
ошибок,• некоторые ошибки возникают достаточно редко (ошибки работы с
памятью) и потому их трудно найти и воспроизвести
http://www.slideshare.net/IgorShkulipa 4
Стратегия модульного тестирования
Модульное тестирование является одной из ключевых практикметодологии экстремального программирования:
• Написание тестов помогает войти в рабочий ритм
• Придает уверенность в работоспособности кода.
• Дает запас прочности при дальнейшей интеграции или измененияхкода.
Модульное тестирование оправдано, если оно:
• Снижает время на отладку
• Дает возможность поиска ошибок с меньшими затратами, нежелипри других подходах
• Дает возможность дешевого поиска ошибок при изменениях кода вдальнейшем
http://www.slideshare.net/IgorShkulipa 5
Цель модульного тестирования
Получение работоспособного кода с наименьшими затратами. И его применениеоправдано тогда и только тогда, когда оно дает больший эффект, нежели другиеметоды.
Отсюда следует несколько выводов:
• Нет смысла писать тесты на весь код. Некоторые ошибки проще найтина более поздних стадиях. Так, например, для ООП данное правило можетзвучать так: нет смысла писать тесты на класс, который используетсятолько одним классом. Эффективней написать тесты на вызывающий класси создать тесты тестирующие все участки кода.
• Писать тесты для кода потенциально подверженного изменениямболее выгодно, чем для кода, изменение которого не предполагается.Сложная логика меняется чаще, чем простая. Следовательно, в первуюочередь имеет смысл писать модульные тесты на сложную логику. А напростую логику писать позднее или вообще тестировать другими методами.
• Для того чтобы как можно реже изменять тесты следует хорошопланировать интерфейсы. То же самое можно сказать и применительно кнаписанию исходного кода. Действительно, создание хорошей архитектурычасто определяет дальнейший ход проекта. И есть оптимум, на каком этапеархитектура «достаточно хороша».
http://www.slideshare.net/IgorShkulipa 6
Планирование тестов
• Код с не оттестированными участками не может быть опубликован
• Тесты должны базироваться на спецификации
• На каждое требование должен быть, как минимум, один тест. Неважно,ручной или автоматический
• Простой тест нужен т.к. несмотря на малую вероятность нахожденияошибки, цена пропущенной ошибки чрезмерно высока
• Наиболее эффективный способ создания тестового набора —совместное использование методов черного и белого ящиков.
http://www.slideshare.net/IgorShkulipa 7
TDD
TDD (Test-Driven Development) - это методика разработки, позволяющаяоптимизировать использование модульных тестов. Стоит подчеркнуть,что речь идет именно об оптимальном, а не максимальномприменении. Задача, которую преследует TDD, - достижение балансамежду усилиями и результатом.
С практической точки зрения, основой TDD является цикл«red/green/refactor»:
• в первой фазе программист пишет тест,• во второй - код, необходимый для того, чтобы тест работал,• в третьей, при необходимости, производится рефакторинг.
В соответствии с принципом "Test First", следует писать только такойкод, который абсолютно необходим, чтобы тесты выполнялисьуспешно.
http://www.slideshare.net/IgorShkulipa 8
Пример. Создание теста
http://www.slideshare.net/IgorShkulipa 9
Пример. Создание теста
http://www.slideshare.net/IgorShkulipa 10
Пример. Создание теста
http://www.slideshare.net/IgorShkulipa 11
Класс-тест
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTestProject1
{
[TestClass]
public class UnitTest1
{
[TestMethod, ExpectedException(typeof(ArgumentException))]
public void TestMethod1()
{
TDDExample.FactorialClass.Factorial(-1);
}
}
}
http://www.slideshare.net/IgorShkulipa 12
Тестируемый класс
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Numerics;
namespace TDDExample
{
public class FactorialClass
{
public static BigInteger Factorial(int number)
{
if (number < 0) throw new
ArgumentException("Argument is Less than Zero.");
if (number == 0) return 1;
else return Factorial(number - 1) * number;
}
}
}
http://www.slideshare.net/IgorShkulipa 14
Тест с другими данными
14
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace UnitTestProject1
{
[TestClass]
public class UnitTest1 {
[TestMethod, ExpectedException(typeof(ArgumentException))]
public void TestMethod1()
{
TDDExample.FactorialClass.Factorial(10);
}
}
}
http://www.slideshare.net/IgorShkulipa 15
Класс Assert
Проверяет условия, использующие утверждения "истина/ложь", в процессемодульных тестов.
Пространство имен: Microsoft.VisualStudio.TestTools.UnitTesting
Методы:
• AreEqual, AreEqual<T> / AreNotEqual, AreNotEqual<T> + 17 перегрузок -проверяет два указанных объекта на равенство/неравенство. Утверждение невыполняется, если объекты не равны.
• AreSame / AreNotSame + 2 перегрузки - проверяет, ссылаются ли двеуказанные объектные переменные на один и тот же объект / на разные объекты.
• Equals - определяет равенство двух объектов.
• Fail - отменяет выполнение утверждения без проверки каких-либо условий.
• Inconclusive - указывает, что утверждение не может быть проверено.
• IsFalse / IsTrue - проверяет, имеет ли указанное условие значение false/true.
• IsInstanceOfType / IsNotInstanceOfType - проверяет, является / не являетсяли указанный объект экземпляром заданного типа.
• IsNull / IsNotNull - проверяет, имеет / не имеет ли указанный объект значениеnull
• ReplaceNullChars - заменяет в строке символы null ('\0') на "\\0".
http://www.slideshare.net/IgorShkulipa 16
Пример. Тестируемый класс
public class FactorialClass
{
public static BigInteger Factorial(int number)
{
if (number < 0) throw new
ArgumentException("Argument is Less than Zero.");
if (number == 0) return 1;
else return Factorial(number - 1) * number;
}
public static double CircleSquare(double radius)
{
return 3.14 * radius * radius;
}
public static double CircleLength(double radius)
{
return 2.0 * 3.14 * radius;
}
}
http://www.slideshare.net/IgorShkulipa 17
Пример. Класс-тест[TestClass]
public class UnitTest1 {
[TestMethod, ExpectedException(typeof(ArgumentException))]
public void TestFactorial() {
TDDExample.FactorialClass.Factorial(-100);
}
[TestMethod]
public void TestCircleSquare() {
double testRadius = 10;
double expectedResult = Math.PI * Math.Pow(testRadius, 2);
double actualResult = TDDExample.FactorialClass.CircleSquare(testRadius);
double tolerance=0.01;
Assert.AreEqual(expectedResult, actualResult, tolerance);
}
[TestMethod]
public void TestCircleLength() {
double testRadius = 10;
double expectedResult = 2.0 * Math.PI * testRadius;
double actualResult = TDDExample.FactorialClass.CircleLength(testRadius);
double tolerance = 0.01;
Assert.AreEqual(expectedResult, actualResult, tolerance);
}
}
http://www.slideshare.net/IgorShkulipa 19
Лабораторная работа №17. Unit-тестирование
В индивидуальных курсовых проектах при необходимости использоватьсоздание unit-тестов и TDD.