Модульное тестирование больших наборов данных?
-
04-07-2019 - |
Вопрос
Каков наилучший способ модульного тестирования больших наборов данных? Некоторый унаследованный код, который я поддерживаю, имеет структуры из ста или более членов; другие части кода, над которым мы работаем, создают или анализируют наборы данных из сотен образцов.
Наилучший подход, который я нашел до сих пор, - это сериализовать структуры или наборы данных с диска, выполнить тестируемые операции, сериализовать результаты на диск, а затем преобразовать файлы, содержащие сериализованные результаты, в файлы, содержащие ожидаемые результаты. Это не очень быстро, и это нарушает "не трогай диск" Принцип юнит-тестирования. Однако единственная альтернатива, которую я могу придумать (написание кода для инициализации и тестирования сотен членов и точек данных), кажется невыносимо утомительной.
Есть ли лучшие решения? Р>
Нет правильного решения
Другие советы
Если то, что вы пытаетесь достичь, на самом деле является модульным тестом, вы должны смоделировать базовые структуры данных и смоделировать данные. Этот метод дает вам полный контроль над входами. Например, каждый тест, который вы пишете, может обрабатывать одну точку данных, и у вас будет очень краткий набор тестов для каждого условия. Существует несколько фреймворков с открытым исходным кодом, я лично рекомендую Rhino Mocks ( http: // ayende.com/projects/rhino-mocks/downloads.aspx ) или NMock ( http: //www.nmock .org ). р>
Если вы не можете смоделировать структуры данных, я рекомендую рефакторинг, чтобы вы могли :-) Оно того стоит! Или вы также можете попробовать TypeMock ( http://www.typemock.com/ ), который позволяет издеваться конкретных классов.
Если, однако, если вы выполняете тесты с большими наборами данных, вы действительно выполняете функциональные тесты, а не модульные тесты. В этом случае загрузка данных в базу данных или с диска является типичной операцией. Вместо того, чтобы избегать этого, вы должны работать над тем, чтобы он работал параллельно с остальной частью вашего автоматизированного процесса сборки, чтобы влияние на производительность не сдерживало ваших разработчиков.
Это все еще жизнеспособный подход. Хотя я бы классифицировал это как функциональный тест или просто как не единичный тест. Хорошим модульным тестом было бы взять выборку из этих записей, которая дает хорошее распределение крайних случаев, с которыми вы можете столкнуться, и записать их. Затем у вас есть ваше последнее «принятие» или "функциональный" проверить с помощью массового теста на всех данных.
Я использую этот подход при тестировании больших объемов данных, и я считаю, что он работает достаточно хорошо, потому что небольшие блоки обслуживаемы, а затем я знаю, что массовый тест работает, и все это происходит автоматически.
Наилучший подход, который я нашел до сих пор, - это сериализовать структуры или наборы данных с диска, выполнить тестируемые операции, сериализовать результаты на диск, а затем преобразовать файлы, содержащие сериализованные результаты, в файлы, содержащие ожидаемые результаты. Р>
Я написал код, который использует описанную выше технику, за исключением того, что в тесте вместо сериализации с диска я преобразовал сериализованные данные в байтовый массив, который компилятор может поместить в исполняемый файл для вас. Р>
Например, ваши сериализованные данные могут быть преобразованы в:
unsigned char mySerialisedData[] = { 0xFF, 0xFF, 0xFF, 0xFF, ... };
test()
{
MyStruct* s = (MyStruct*) mySerialisedData;
}
Для более подробного примера (в C #) см. этот модульный тест . В нем показан пример использования некоторых жестко закодированных сериализованных данных в качестве входных данных для тестов и проверки подписи сборки.