Как я могу проверить читатель файла?

19

Я работаю над проектом с несколькими форматами файлов. Некоторые форматы определяются .xsds, другие - документацией на соответствующих веб-сайтах, а некоторые являются собственными внутренними форматами, которые не имеют документации. Mwahahahaha.

В чем проблема?

Я хотел бы проверить свои программы для чтения файлов, но я не совсем уверен, как это сделать. Поток приложения таков:

file.___  ===> read by FileReader.java ===> which creates a Model object

где FileReaderинтерфейс

public interface FileReader {
    public Model read(String filename);
}

ModelИмеет ряд атрибутов , которые заполняются при чтении файла. Это выглядит примерно так

public class Model {
    List<String> as;
    List<String> bs;
    boolean isAPain = true;
    // ...
}

Что я пробовал?

Моя единственная идея состояла в том, чтобы создать файловые «генераторы» для каждого формата файла. Эти генераторы в основном являются компоновщиками, которые принимают несколько переменных (например, количество комментариев для генерации в файле) и выводят образец файла, который я затем читаю, и сравнивают полученный результат Modelс переменными, которые я использовал для первоначальной генерации файла.

Это имеет несколько проблем:

  • Файлы, которые он генерирует, не похожи на реальные файлы. Генератор не знает контекста.
  • Трудно распознать, сгенерирован ли генератор для граничных случаев, так как я задаю переменные вручную. Этот метод едва ли лучше, чем я, создающий дюжину примеров файлов.

Есть ли лучшие способы сделать это?

РЕДАКТИРОВАТЬ: изменение единицы для интеграции, поскольку это то, что я на самом деле имею в виду.

РЕДАКТИРОВАТЬ 2: Вот пример крайних случаев, которые я упомянул.

Каждый файл представляет собой граф, состоящий из вершин и ребер. Эти вершины и ребра могут быть присоединены по-разному, поэтому:

v1 -- e1 --> v2 <-- e2 -- v3

отличается от

v1 -- e1 --> v2 -- e2 --> v3

в этом направлении края имеют значение. Я не уверен, входит ли это в суть вопроса, но сложно придумать все подходящие случаи ребер, когда я вручную устанавливаю количество вершин, количество ребер и просто генерирую соединения случайным образом.

sdasdadas
источник
1
На ум приходит тестирование на основе данных. Можете ли вы привести конкретные примеры граничных случаев (на основе граничных случаев, которые могут быть инициированы в реальной FileReaderреализации)? Пример: учитывая граничные случаи, найденные в форматах файлов изображений , для каждой записи таблицы, если поддерживается комбинация свойств строки / столбца, должен быть хотя бы один тестовый пример (файл данных), охватывающий эту комбинацию.
Руонг
@ rwong Я добавил пример, но я не уверен, дает ли он вам идею. Я думаю, что моя проблема обычная проблема с крайними случаями, т.е. Я что-нибудь пропустил? Хотя тестирование на основе данных выглядит интересно. Благодарность!
sdasdadas
7
Кроме того, я только что заметил это, но мои крайние случаи буквально являются крайними случаями.
sdasdadas
1
Почему бы не сделать тестовые файлы ручной работы, а затем всегда работать с одними и теми же?
Бобсон
@ Бобсон Это немного хуже, чем использование генератора. В этом случае я мог бы пропустить крайние случаи (поскольку я, вероятно, пропускаю сейчас), но я также мог бы ввести ошибки в мою печать. И с огромными файлами, создание их самостоятельно заняло бы довольно много времени.
sdasdadas

Ответы:

19

Во-первых, давайте поговорим о ваших целях:

  • вы явно не хотите тестировать «форматы файлов» - вы хотите протестировать различные FileReaderреализации

  • вы хотите найти как можно больше различных типов ошибок с помощью автоматических тестов

Чтобы полностью достичь этой цели, ИМХО нужно сочетать разные стратегии:

  • во-первых, реальное модульное тестирование: ваши FileReaderреализации будут состоять из множества различных частей и функций. Напишите небольшие тесты, которые тестируют каждый из них в отдельности; Разработайте свои функции таким образом, чтобы им не нужно было считывать данные из файла. Такие тесты помогут вам протестировать большинство ваших крайних случаев.
  • во-вторых, сгенерированные файлы: это то, что я бы назвал интеграционными тестами. Такие файлы помогут вам отследить сбои, отличные от пункта 1, например, комбинации определенных параметров, ошибки в доступе к файлам и т. Д. Для создания хороших тестовых примеров будет также полезно узнать о некоторых классических методах, таких как группировка тестовых примеров в классы эквивалентности или граничное тестирование. Получить копию этой книги Гленфорд Майерс, чтобы узнать больше об этом. Статья Википедии о тестировании программного обеспечения является хорошим ресурсом, тоже.
  • в-третьих, попытайтесь получить реальные данные: может быть трудно проверить, правильно ли эти файлы оцениваются вашими пользователями FileReader, но, возможно, стоит сделать это, поскольку часто обнаруживаются ошибки, не обнаруженные в первых двух стратегиях. Некоторые люди называют эти добрые вещи также «интеграционными тестами», другие предпочитают «приемочные тесты», но на самом деле этот термин не имеет большого значения.

ИМХО, не существует «быстрого» подхода, который принес бы вам пользу от всех трех стратегий «по цене одной». Если вы хотите выявлять крайние случаи, а также сбои в стандартных случаях, а также в реальных случаях, вы должны инвестировать, по крайней мере, некоторые - более вероятно, много - усилия. К счастью, все эти подходы могут быть использованы для создания автоматических повторяемых тестов.

Кроме того, вы должны убедиться, что ваши FileReaderфайлы не маскируют ошибки при чтении этих данных - создавайте встроенные проверки / утверждения, создавайте исключения, когда что-то идет не так, внутренне и т. Д. Это дает вашему тестовому коду гораздо больше шансов обнаружить ошибки даже если у вас нет явного тестового файла или тестового примера для непредвиденной ситуации.

Док Браун
источник
Потрясающий ответ, и я отредактирую заголовок моего вопроса, чтобы лучше отразить. Благодарность!
sdasdadas