Методика автоматизации поиска некорректных модульных тестов Алексей Лянгузов. Sun Microsystems, Inc.
План Введение Чужой среди своих или «Who Watches the Watchers?» Знай своего врага в лицо Как отыскать затаившегося врага
Введение Признать проблему Изучить проблему Решить проблему
Далее... Введение Чужой среди своих или «Who Watches the Watchers?» Знай своего врага в лицо Как отыскать затаившегося врага
Признаем проблему Верны ли измерения сделанные неисправным инструментом? Тесты содержат ошибки!
Плохие и хорошие тесты а 4б Тест Исправен Тест Неисправен Программа Исправна Программа Неисправна
А вы уверены что тест найдет ошибку в коде?... что тест не маскирует ошибку в коде?
Далее... Введение Чужой среди своих или «Who Watches the Watchers?» Знай своего врага в лицо Как отыскать затаившегося врага
Анти-паттерн Лодырь Пустозвон Активный Случайный //тестируем метод String. lastIndexOf () int expected = 12; String target = "I watch the watchers"; String lookFor = "watcher"; int actual = target. indexOf (lookFor); assertTrue(expected == actual); Тест не вызывает тестируемый метод, вообще ничего не делая, делая что-то или вызывая другой метод
Анти-паттерн Правдолюб Всегда «да» Никогда «нет» int expected = 5; int actual = 2 + 2; if(expected == actual){ assertTrue("Passed", true); } else{ assertFalse ("Failed!", false ); } Тест или всегда говорит, что прошел или не может сказать что упал
Анти-паттерн Невыполнимый Недостижимое условие Неверный Setup // must be " os.name " String os = System.getProperty(" os_name "); if("Windows XP".equals(os)){ //do something assertTrue(false); } else { System.out.println(Not applicable); } Тест не может начаться из-за неверного условия или невыполнимой стадии setup.
Анти-паттерн Оборотень (vice versa) //код теста boolean expected = true ; //must be false boolean actual = Target.isNotNull(null); assertEquals(expected, actual); //код программы boolean isNotNull(Object obj){ //must be != return (obj == null); } Тест проходит, когда должен упасть и падает, когда должен пройти. Возможен только при наличии дефекта в коде программы!
Далее... Введение Чужой среди своих или «Who Watches the Watchers?» Знай своего врага в лицо Как отыскать затаившегося врага
Существующие методы Инспекция кода тестов Автоматические методы –Статическая проверка покрытия –Динамическая проверка покрытия –Аудит кода тестов –Запуск тестов
Идея Запуская тест против программы, заведомо работающей неправильно, мы в праве ожидать, что тест должен упасть
Реализация Давайте сделаем так, чтобы тестируемая программа работала неправильно!
Возможные вопросы Если каждый метод работает неправильно, как это вообще работает? Как провести подготовительную стадию (setup) теста, если все работает неправильно? Это очень дорого иметь две версии программы – хорошую и плохую Как определить некорректное поведение конкретного метода?
А вот так! Stringstaticfinal Object publicintthrows 1.Два режима работы Оригинальный Неправильный 5.Базируется на сигнатуре 3.Ломается по сигналу 2.Тест знает 'свой' метод Метод кода Метод кода 4.Сигнал посылается перед запуском теста ?
Компоненты Code Infecter Tests Broken Code Emulator Patched Test Framework Test-to-Code Map Software Product Infected Software Product
Процесс Создать map Заразить код Прохачить Test Framework Запустить тесты
Пример кода Patched Test Framework public void runTest(Test test){ String testName = test.getName(); Resulter.setTestName(testName); Status status = test.run(); BCE.infect(test, status); while(BCE.hasNextEmulation()){ status = test.run(); BCE.remember(status); } status=BCE.disinfect(); Resulter.setStatus(status); }
Пример кода Зараженный метод package pack1; public class Class1{ public method int meth1(){ if(BCE.isInfected("pack1.Class1.meth1()")){ return BCE.emulateIntMethod(); } int result = 0; //method body return result; }
Недостатки и ограничения Необходимость «подправить» Test Framework Применим в основном только к unit тестам Время прогона тестов увеличивается Подразумевается возможность определить какой метод будет тестироваться
Достоинства Языко- независим Не зависит ни от логики теста ни от логики метода Не требует и не вносит изменения в тесты Универсален Реализация зависит от Test Framework Не требует наличия какого-то API Автоматизированный подход Применим к исходному и бинарному коду
Вопросы Q&A Alexey Lyanguzov Sun Microsystems, Inc. Patent pending