Тестирование плагинов

Тестирование плагинов #

Этот раздел описывает возможности написания интеграционных тестов.

JUnit #

Для тестирования механизмов плагинов к 1C:EDT используется библиотека JUnit 4, которая интегрирована в среду разработки Eclipse. JUnit используется как для unit, так и для интеграционного тестирования.

JUnit — библиотека для модульного тестирования программного обеспечения на языке Java.

Принципы и подробные примеры использования можно найти в официальной Wiki JUnit.

Mockito #

Для создания mock-объектов в тестах мы используем библиотеку Mockito. Принципы и подробные примеры использования можно найти в официальной Wiki Mockito.

Инструменты для написания интеграционных тестов #

Мы реализовали удобную инфраструктуру использования тестовых проектов 1С:EDT с тестовыми данными для интеграционного тестирования плагинов.

Тестовая рабочая область #

Для использования тестовой рабочей области в тестах реализован Rule-класс TestingWorkspace. Этот класс предоставляет ряд методов для управления проектами с тестовыми данными:

  • развернуть проект в тестовой рабочей области,
  • очистить тестовую рабочую область и др.

Тестовая рабочая область очищается автоматически до и после выполнения тестов (если не настроено иное).

Типичный тестовый сценарий выглядит следующим образом:

  1. TestingWorkspace автоматически очищает тестовую рабочую область до начала теста.
  2. Тест производит необходимую инициализацию состояния тестовой рабочей области, например разворачивает проект с тестовыми данными.
  3. Тест проверяет какие-то механизмы на данном проекте.
  4. TestingWorkspace автоматически очищает тестовую рабочую область после окончания теста.

Так как TestingWorkspace реализован как тестовый Rule (в терминах JUnit 4), то его можно использовать:

  • для предоставления новой тестовой рабочей области для каждого отдельного теста с помощью аннотации @Rule,
  • для предоставления единой тестовой рабочей области для всех тестов класса с помощью аннотации @ClassRule.
Нужно аккуратно использовать TestingWorkspace с аннотацией @ClassRule. Выполняемые тесты могут создавать побочные эффекты, т. к. они будут разделять одну и ту же тестовую рабочую область. Однако такой подход может быть полезен в тех случаях, когда необходимо написать большое количество тестов, которые не изменяют данные. Такой подход позволит избежать больших затрат времени на развертывание каждого отдельного теста.

Пример с тестовой рабочей областью на каждый тест класса

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
public class TestingWorkspaceRuleExampleTest
{
    @Rule
    public TestingWorkspace testingWorkspace = new TestingWorkspace();
 
    @Test
    public void testSomeProjectBehavior()
    {
        IProject project = testingWorkspace.setUpProject("Main", getClass());
 
        // Тут мы можем использовать проект для тестирования...
    }
 
    @Test
    public void testSomeOtherProjectBehavior()
    {
        IProject project = testingWorkspace.setUpProject("Other", getClass());
 
        // Тут мы можем использовать проект для тестирования...
    }
}

Пример с единой тестовой рабочей областью на все тесты класса

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class TestingWorkspaceRuleClassExampleTest
{
    @ClassRule
    public static TestingWorkspace testingWorkspace = new TestingWorkspace();
 
    private static IProject mainProject;
    private static IProject otherProject;
 
    @BeforeClass
    public static void setUp() throws Exception
    {
       mainProject = testingWorkspace.setUpProject("Main", TestingWorkspaceRuleClassExampleTest.class);
       otherProject = testingWorkspace.setUpProject("Other", TestingWorkspaceRuleClassExampleTest.class);
    }
 
    @Test
    public void testSomeProjectBehavior()
    {
        // Тут мы можем использовать оба проекта для тестирования...
    }
 
    @Test
    public void testSomeOtherProjectBehavior()
    {
        // ... и тут
    }
}

Методы setUpProject(String, Class) в Rule-классе TestingWorkspace производят поиск тестируемого проекта, который определяется через передаваемое название, в ресурсной папке с названием workspace внутри плагина, который определяется через передаваемый класс. Например, если передать сам класс теста, как в примерах выше, то ожидается ресурсная папка с таким именем в этом же тестовом плагине. Более подробно об этом можно прочитать в описании класса TestingWorkspace.

Внедрение зависимостей в тесты #

Для внедрения зависимостей в тесты реализованы JUnitGuiceRunner и ParameterizedJUnitGuiceRunner, унаследованные от org.junit.runner.Runner, а также правило (Rule) InjectWithGuice. Они могут быть использованы для внедрения зависимостей из описанных Guice-модулей.

Пример использования JUnitGuiceRunner

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
@RunWith(JUnitGuiceRunner.class)
@GuiceModules(
    modules = { ModuleA.class, ModuleB.class, ModuleC.class },
    overrides = { TestModuleA.class })
public class Test
{
    @Inject
    private IServiceFromModuleA serviceFromModuleA;
 
    @Inject
    private IServiceFromModuleB serviceFromModuleB;
 
    @Test
    public void shouldTestSomething()
    {
        // Используем наши зависимости
        serviceFromModuleA.use();
        serviceFromModuleB.use();
    }
}

Правило InjectWithGuice может быть полезно, когда в тесте требуется использовать свой org.junit.runner.Runner (т. к. JUnit 4 имеет ограничение на использование только одного org.junit.runner.Runner на тест).

Пример использования InjectWithGuice

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
public class Test
{
    @Rule
    public InjectWithGuice injectWithGuice = new InjectWithGuice(new ModuleA(), new ModuleB());
 
    @Inject
    private IServiceFromModuleA serviceFromModuleA;
 
    @Inject
    private IServiceFromModuleB serviceFromModuleB;
 
    @Test
    public void shouldTestSomething()
    {
        // Используем наши зависимости
        serviceFromModuleA.use();
        serviceFromModuleB.use();
    }
}

В качестве внедряемых зависимостей вполне могут использоваться публичные сервисы. Более подробно о них и об их использовании можно прочитать здесь.