четверг, 29 мая 2014 г.

Тестирование ADF приложений. Часть 1(Тестирование модулей при помощи JUnit)

Очень важным этапом при разработке приложений является их тестирование. Ручное тестирование занимает много времени и усилий. И что бы облегчить эту работу  мы автоматизируем этот этап.

      Над ADF приложениями проводятся тестирования 3 видов:

  • Тестирование модулей (будем использовать  JUnit)
  • Тестирование форм (будем использовать Selenium)
  • Тестирование нагрузки (будем использовать JMeter)

В этой статье рассмотрим тестирование модулей приложения. Приступим
В статье я буду использовать проект, который был создан в одной из предыдущих статей
https://drive.google.com/file/d/0ByLMFtz8FbBvZGE1S2tXaGN1QUU/edit?usp=sharing



JUnit является  фреймворком модульного тестирования для Java, что означает: 
  •  Он используется для тестирования Java кода
  •  Тестовые сценарии пишутся в Java
         При помощи  JUnit, мы создадим тестовые классы, содержащие методы проверки. Внутри этих методов , мы разместим тесты "утверждения" . Если они будут верны, то тест считается пройденным, в противном случае он считается  не пройденным.
Для облегчения написания и выполнения модульных тестов. в JDeveloper существует расширение JUnit. Его можно найти в   Help | Check for Updates->JUnit extension under Official
Oracle Extensions and Updates —>BC4J JUnit Integration , JUnit Integration 








Хороший  тест  должен иметь следующие характеристики: 
  •  Он должен проверять одну вещь 
  •  Он может работать в изоляции 
  •  Легко запускаться 
  •  Быстро выполняться

Рассмотрим подробнее эти характеристики:
  • Тест должен проверять одну вещь.Наши тесты должны проверять  маленькие кусочки кода Небольшие тесты указывают , где именно ошибка .
  • Тест должен в состоянии работать в изоляции.  Тесты   не должны зависеть от внешних ресурсов, таких как базы данных .Так как в  ADF приложениях всегда участвует БД, то тесты должны создавать свои собственные тестовые данные , чтобы они могли быть запущены и повторно запускать в любое время .
  • Тесты должны легко запускаться. Это достигается с помощью инфраструктуры JUnit в JDeveloper , где вы можете просто запустить свой тестовый класс и получить обратную связь непосредственно в JDeveloper на JUnit Test Runner
  • Быстро выполняться. Тесты должны быстро работать , чтобы вы на самом деле запускали их и не поддавались искушению пропустить тестирование 
Подготовка к тестированию
В качестве примера, как настроить модульное тестирования, мы будем осуществлять модульное тестирование Application (AppModule). Модули тестирования вынесем  в отдельный проект, чтобы избежать загромождения рабочего проекта   тестовыми артефактами.

Настройка тестового проекта 
Откройте рабочую область и выберите File | New, а затем Generic проекта . Дайте проекту имя ModelTests и нажмите кнопку Готово, чтобы создать проект. 



Добавление тестов

Теперь выберите проект ModelTests и выберите File->New->General->Unit Tests->Business Components Test Suite

Мастер JUnit ADF Business Components Test Suite позволяет выбрать бизнес-компоненты, который вы хотите проверить, а также Application Module. Убедитесь, что в параметрах указан Application Module, который требуется для тестирования:







Мастер создал три вида объектов для вас: 
  • Test Fixture (AppModuleAMFixture)
  • Test Suite (AllAppModuleTests)
  • Тестовые классы 

Test Fixture заботится о создании экземпляра Application Module, который требуется для тестирования.  Вы можете открыть файл AppModuleAMFixture.java чтобы увидеть, что он делает-это стандартный код для доступа к Application Module. 

Test Suite собирает все отдельные тесты, которые составляют свой ​​набор тестов. Этот класс активно использует Java аннотации-ключевых слов с префиксом @.
Аннотация @Suite.SuiteClasses перечисляет  все тестовые классы, чтобы выполнился весь пакет

@Suite.SuiteClasses( { PhotoView2VOTest.class, EmpView2VOTest.class, PhotoView1VOTest.class, EmpView1VOTest.class })

Так же формируется  ряд тестовых классов-по умолчанию один для каждого ViewObject включенного в Application Module . Эти классы используют аннотации: 
@Test - указывает что выполнять при выполнении теста.
@Before - указывает что выполнять перед выполнением теста.
@After - указывает что выполнять после  выполнения теста.
Класс, созданный для просмотра объекта EmpView1VO выглядит следующим образом:



public class EmpView1VOTest {
    private AppModuleAMFixture fixture1 = AppModuleAMFixture.getInstance();

    public EmpView1VOTest() {
    }

    @Test
    public void testAccess() {
        ViewObject view = fixture1.getApplicationModule().findViewObject("EmpView1");
        assertNotNull(view);
    }

    @Before
    public void setUp() {
    }

    @After
    public void tearDown() {
    }
}




Метод testAccess получает Application Module (от объекта fixture1, который извлекается из  класса AppModuleAMFixture), а затем находит объект EmpView1. Затем он утверждает, что ссылка на объект не является нулевой, то есть, Application Module действительно содержит экземпляр объекта вида EmpView1. Если это так, то проверка прошла успешно. Если это не так, то тест не не пройден. Проверкой занимается метод assertNotNull. Так же существуют следующие методы: assertEquals, assertFalse, assertNull, assertTrue, assertSame.

Чтобы увидеть тестирование в действии, щелкните правой кнопкой мыши на классе наборов тестов (AllAppModuleTests.java) и выберите пункт Run
В окне журнала, появится  новая вкладка JUnit Test Runner,в ней отображаются результаты тестирования. 


Создадим тест который добавляет запись, потом ищет ее.  И если не находит выводит ошибку:
"Тестовая  строка  (-111) не найдена". Потом после выполнения теста удаляем эту запись.Код должен выглядеть так



 @Test
    public void testInsert() {
    Transaction tr = fixture1.getApplicationModule().getTransaction();
   //Добавление записи в БД 
   tr.executeCommand("INSERT INTO EMP (EMPNO, \n" + 
    "       ENAME, \n" + 
    "       JOB, \n" + 
    "       MGR, \n" + 
    "       HIREDATE, \n" + 
    "       SAL, \n" + 
    "       DEPTNO) VALUES (-111, 'TestName','TestJOB',10,sysdate,100,10)");
    tr.commit(); 
    ViewObject v = fixture1.getApplicationModule().findViewObject("EmpView1");
    //Поиск записи
    Key k = new Key(new Object[] { -111 });
    Row r1 = v.getRow(k);
// Вывод утверждения  если запись пуста
    assertNotNull("Тестовая  строка  (-111) не найдена", r1);
    }
    
    @AfterClass
    public static  void deleteTestData() {
    Transaction tr = AppModuleAMFixture.getInstance().getApplicationModule().getTransaction();
   //Удаление записи после выполнения теста 
   tr.executeCommand("DELETE FROM EMP WHERE EMPNO = -111");
    tr.commit();
    }

   


Такие тесты можно и нужно делать для всех модулей приложения.