Тестирование отдельных классов и кластеров класса Принцип инкапсуляции ограничивает видимость данных и методов, поэтому нет уверенности, что выполнив все методы класса на определённых наборах тестовых примеров, будет проведено исчерпывающее тестирование.Тестирование отдельных классов и кластеров класса на определённых наборах тестовых примеров, будет проведено исчерпывающее тестирование. Существует несколько способов, позволяющих драйверу обходить инкапсуляцию: 1) для каждого класса при его разработке создаётся свой набор тестовых примеров, который учитывает инкапсуляцию; 2) при разработке класса в него включают специальные методы для тестирования; 3) создаются дочерние классы, через которых осуществляется доступ к данным и методам для тестирования; 3) создаются "параллельные классы", через которые производится доступ к данным и методам, которые тестируются. Всякое изменение в классе или подмена его другим классом может быть источником дополнительных ошибок. На практике тестирование часто начинают с класса, который имеет наименьшее количество связей, при этом драйвер и заглушки моделируют все взаимодействия данного класса с другими классами. Затем постепенно подключаются к первому классу вторые, третьи и т. д., образуя интеграцию в рамках программного модуля. Тестирование классов в RTS-системе Надо рассмотреть диаграммы взаимодействия, диаграммы классов, и выбрать класс, который имеет наименьшее количество связей с другими классами. Тестирование класса Train struct tr { int numb; char s1[20]; char s2[20]; char clT[10]; char date[8]; } class Train { protected: char *ftr="d:\\RTS\\train.dat"; FILE *f;//файловая перем. tr *mTr;//массив поездов int nt;//к-во поездов public: ~Train(); Train(); void addTr(tr); int delTr(int,char*,char*,int,char); protected: void storeTr();//запись в файл void loadTr();//чтение из файла } Train::Train() { f=fopen(ftr,"a+"); nt=........ mtr=new tr[nt]; loadTr(); .... } Train::~Train() { storeTr(); delete[] mtr;} Построение драйвера Создадим схему тестирования |исходные данные |запросы vдля поездов v Результаты [Драйвер TestTrain ]----------> создание|добавление|уничтожение|удалить|получить^ объектаv поездовv объектаv поездv поезд| [Объект Train ] чтение ^запись| из файла|в файлv [Файл поезлов ] Группа тестов I Проверка конструктора, методов addTr, getTr ТВ1: создаём объект Train, добавляем поезда. ИД1: addTr(n1,s11,s21,date1,clTr1) ИД2: addTr(n2,s12,s22,date2,clTr2) ИД3: addTr(n3,s13,s23,date3,clTr3) .......... getTr(s11,s21,date1,clTr1) ОЖ.Р=n1 ........ getTr(s11,s22,date1,clTr1) ОЖ.Р=нет поезда getTr(s11,s21,date2,clTr1) ОЖ.Р=нет поезда Группа тестов II Проверка удаление объекта, чтения и записи данных в файл ТВ1: удаляем объект Train. Создание объекта Train. Перенести вызовы из группы I. Убедиться в совпадении ОЖ. Р. Группа тестов III Удаление поезда ТВ: delTr(n1,s11,s21,date1,clTr1); getTr(s11,s21,date1,clTr1) ОЖ.РЕЗ: "нет поезда" //Драйвер void main() { //описание переменных //указатель на поезд, переменная структура Tr... //массив поездов //цикл ввода поездов //.... запись в объект Train .......... Совместное тестирование кластера из объектов Train--Way b:=isItinerary(s1,s2) -> -> 1.3:[itda.k!=0]create(itDa,s1,s2) ------------------------[:Register]-----------[_o:Order_]---------------------------------[_w:Way_] b:=isTrain(...) -> 1.1:=getTrain(clT,date,it) -> ------------------[:Register]-------[_o:Order_]-----------------------------[_w:Way_] |1.1.1:getTrain(Sn,Sd,date,clT) |1.1.2:[itda.k=2]Tr2:=getTrain(Snv2,Sdv2,date,clT) [_t:Train_] s:=getPrice() -> -> -> ----------------[_:Register_]-----[_:Order_]------[:Payment] |1.1.1:getDist() [:Way] Схема тестирования +---------[Драйвер TestTr_Way ] |создание |создать|удалить^получить ^получить v v v |номера поездов|расстояние [_:Train_] [_:Way_ ] Предварительная операция -- создание объекта Train Группа тестов I Проверка конструктора Way и метода getTrain ТВ1 -- один маршрут ТВ2 -- два маршрута Стохастическое тестирование классов Стохастическое тестирование предусматривает генерирование входных данных для тестовых вариантов случайным образом. Например, предметная область -- банк. Пусть класс Счёт имеет следующие операции -- открыть, установить, положить, снять, остаток, итог, ограничить, кредит, закрыть. Каждая операция выполняется при определённых ограничениях, а именно: счёт должен быть открытым перед использованием других операций; счёт должен быть закрытым после всех других операций, однако и в рамках этих ограничений существует большое количество допустимых перестановок и сочетаний, например: открыть, установить, положить, снять и закрыть. Набор разных последовательностей может генерироваться случайным образом. Тестирование разбивок на уровне классов Тестирование разбивок на уровне классов подобно разбиению на эквивалентности для процедурно-ориентированного ПО. Оно позволяет уменьшить количество тестовых вариантов, необходимых для проверки классов. Области ввода и вывода разбивают на категории, а тестовые варианты разбивают для проверки каждой категории. Обычно используют одну из трёх категорий: 1) категории по состоянию, связанные с возможностью операций изменять состояние объекта. Например, в классе Счёт операции снять и положить изменяют состояние и относятся к этой категории.