В настоящее время я добавляю новую функцию в LibFX , для которой я создаю некоторые пользовательские коллекции, схожие с таковыми из Java Collections Framework . Я отправился на поиски тестов, которые мог бы выполнить против них, и был рад узнать, что Google Guava содержит именно то, что мне нужно: массивный набор тестов, который проверяет каждый уголок моей реализации для всех интерфейсов сбора из JDK и Guava.
Давайте кратко рассмотрим это.
обзор
В этом посте сначала будет показано, как настроить проект, а затем посмотреть, как начать работу с реальными тестами.
Я не создал специальных примеров, но вы можете видеть, как я использовал это в LibFX .
Настроить
Чтобы это работало, нам нужен JUnit, Guava-Testlib и небольшой шаблонный код.
Получить JUnit
Если вы еще не используете JUnit в своем проекте, загрузите его здесь . Если вы используете Maven или Gradle:
Информация о зависимостях для Maven
1
2
3
4
5
6
|
< dependency > < groupId >junit</ groupId > < artifactId >junit</ artifactId > < version >4.12</ version > < scope >test</ scope > </ dependency > |
Информация о зависимостях для Gradle
1
|
testCompile 'junit:junit:4.12' |
Получить гуаву
Что нам действительно нужно, так это не сама Гуава, а Гуава-Тестлиб . Вы можете скачать его из центрального репозитория , который также содержит информацию о зависимостях для разных менеджеров.
Для вашего удобства:
Информация о зависимостях для Maven
1
2
3
4
5
6
|
< dependency > < groupId >com.google.guava</ groupId > < artifactId >guava-testlib</ artifactId > < version >18.0</ version > < scope >test</ scope > </ dependency > |
Информация о зависимостях для Gradle
1
|
testCompile 'com.google.guava:guava-testlib:18.0' |
Напишите немного
Предположим, вы хотите написать MySet
и соответствующий MySetTest
.
Делая это JUnit-3.8.x-way, создайте метод public static Test suite();.
JUnit ищет этот метод и использует его для определения всех тестов, которые он будет выполнять для этого класса. Внутри этого метода создайте TestSuite и добавьте тесты, которые мы собираемся записать ниже:
Котел в «MySetTest»
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
public class MySetTest { public static Test suite() { return new MySetTest().allTests(); } public Test allTests() { TestSuite suite = new TestSuite( "package.name.of.MySetTest" ); suite.addTest(testForOneToWayUseMySet()); suite.addTest(testForAnotherWayToUseMySet()); return suite; } } |
(Я не пытался сделать это с помощью аннотаций JUnit 4. Если вы это сделали, пингуйте меня, и я включу это здесь.)
Имея этот шаблон, вы можете запускать этот класс с JUnit, например, изнутри вашей IDE или с вашего CI-сервера.
Проверьте свои реализации
Теперь, когда это сделано, мы можем начать создавать тесты для наших реализаций. Или, точнее, скажите Гуаве, как это сделать для нас. Это процесс, состоящий из двух частей: один создает генератор для элементов в коллекции и тестируемый модуль, другой использует один из сборщиков тестовых наборов Guava для создания полного набора тестов, адаптированных к реализации.
Мы продолжим тестировать реализацию Set
. Ниже мы увидим, для каких других интерфейсов доступны тестовые наборы.
Генератор для элементов и тестируемого устройства
Разработчик набора тестов требует, чтобы вы дали ему возможность создавать образцы элементов в коллекции и создавать экземпляры вашей коллекции. Для этого вам нужно реализовать TestSetGenerator<E>
(где E
— тип элементов).
Это прямо с order(List<E>)
который является единственным методом, который может потребовать некоторого размышления. Обратите внимание, что в отличие от документации, текущая версия testlib (18.0) вызывает этот метод, даже если CollectionFeature.KNOWN_ORDER
не сообщается (подробности о функциях см. Ниже). В моем случае достаточно вернуть порядок вставки.
Test Suite Builder
Теперь, когда происходит настоящее волшебство. Вы берете свой генератор сверху, передаете его правильному сборщику тестов, указываете, какие функции имеет ваша коллекция, и он создаст индивидуальный и всеобъемлющий набор тестов:
Использование SetTestSuiteBuilder для создания тестов
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
public Test testForOneToWayUseMySet() { return SetTestSuiteBuilder .using( new MySetGenerator()) .named( "one way to use MySet" ) .withFeatures( CollectionSize.ANY, CollectionFeature.ALLOWS_NULL_VALUES, CollectionFeature.FAILS_FAST_ON_CONCURRENT_MODIFICATION, CollectionFeature.SUPPORTS_ADD, CollectionFeature.SUPPORTS_ITERATOR_REMOVE, CollectionFeature.SUPPORTS_REMOVE, ) .createTestSuite(); } |
Особенности
Важно указать правильные функции. Взгляните на два перечисления CollectionSize
и CollectionFeatures
чтобы увидеть, какие существуют возможности для описания поведения вашей коллекции.
Обратите внимание, что созданные тесты проверяют возможности в обоих направлениях! Например, если не ALLOWS_NULL_VALUES
сгенерирует тесты, которые проверят, что добавление null в коллекцию приводит к NullPointerException
.
Подавляющие тесты
Вызывая suppressing
на компоновщике, вы можете указать методы тестирования, которые не будут выполняться. Похоже, что существует последнее средство, когда функции не позволяют точно определить поведение. Я не использовал это.
Установка и удаление
Если вам нужно выполнить код до или после каждого теста, вы можете передать его как Runnable
для withSetUp
или withTearDown
, соответственно (оба могут быть вызваны в компоновщике).
Доступные тесты
Конечно, вы можете создавать тестовые наборы и для других интерфейсов. Первый взгляд дает следующие возможности:
Коллекции Java:
- Коллекция
- Итератор
- Список
- карта
- NavigableMap
- NavigableSet
- Очередь
- Поставил
- SortedMap
- SortedSet
Коллекции Гуавы:
- BiMap
- ListMultimap
- Multimap
- Multiset
- SetMultimap
- SortedMultiset
- SortedSetMultimap
Поиск типа для * TestSuiteBuilder (обратите внимание на подстановочный знак) приводит к появлению некоторых других сборщиков. Я не исследовал их, но возможно, что они могут быть использованы для создания тестов для других случаев.
Чтобы использовать их, просто внедрите соответствующий Test...Generator
и передайте его соответствующему ...TestSuiteBuilder
.
отражение
Мы увидели, как тестировать реализации коллекций с помощью Testlib из Guava: как включить его и JUnit в наш проект, какой шаблон нам нужен для его запуска, и обзор генератора и генератора тестовых наборов. В последнем случае происходит вся магия, поскольку она создает всесторонние тесты с учетом нашего описания нашей реализации и ее возможностей.
Ссылка: | Реализация тестовой коллекции с Guava от нашего партнера JCG Николая Парлога в блоге CodeFx . |