Должен ли каждый метод иметь отдельный тестовый класс JUnit?


13

Я пишу юнит-тесты JUnit для своих классов.

Лучше ли иметь отдельный класс для каждого метода, или иметь только один тестовый класс для каждого фактического класса?

Ответы:


19

То, как организованы ваши тесты, довольно неважно по сравнению с важностью их проведения.

Самым важным для хорошего набора тестов является то, что он охватывает всю функциональность; это гарантирует, что всякий раз, когда будет обнаружен дефект регрессии, вы сразу заметите. Писать ли один тест для каждого метода, один тест для каждой комбинации входных значений метода или даже один тест для каждого возможного пути кода в этом методе не так важно. Распределение этих тестов по нескольким или нескольким классам тестов еще менее важно: набор тестов всегда должен быть успешным в полном объеме, поэтому не имеет значения, провалился ли он в одном из трех или двух из семнадцати тестов - оба являются ошибочными и должны фиксированный.

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


9

К вашему конкретному вопросу, соглашение JUnit, должно иметь соответствие 1: 1 между вашими классами приложений ( Foo1.java, Foo2.java) и тестовыми классами JUnit ( Foo1Test.java, Foo2Test.java).

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


4

Лучше ли иметь отдельный класс для каждого метода, или иметь только один тестовый класс для каждого фактического класса?

Если вам нужно написать отдельные тестовые классы для методов одного класса, значит, у вас неправильный дизайн. Методы должны быть небольшими, легко читаемыми, легко тестируемыми и легко изменяемыми. Тесты могут быть немного длиннее исходного кода из-за создания тестовых данных, насмешек и т. Д., Но не должны быть значительно дольше. Если это так, то ваш тестируемый класс слишком сложный и наверняка выполняет несколько задач ( принцип единой ответственности ): работайте над своим проектом.


2

Я думаю, что оба «один тестовый класс на метод» и «один тестовый класс на класс» обычно слишком экстремальны.

В общем, вы хотите иметь одну проверку для каждого метода тестирования / модульного теста. Например, это может быть несколько утверждений, чтобы проверить, что, list.isEmpty = trueи list.Length = 0, таким образом, один метод тестирования / модульный тест на поведение.

Это позволяет легко придумать имя метода теста, описывающего поведение. Вы хотите сгруппировать тестовые методы в тестовом классе, поэтому, когда вы читаете test classname.test method, это имеет смысл. Обычно они имеют некоторый общий код установки, который затем легко вставить в тестовую настройку / прибор. В зависимости от тестируемого класса это может быть один тестовый класс для всего класса, а также один тестовый класс для одного метода. Но обычно это будет где-то посередине.

Как и в обычном коде, вы хотите, чтобы тесты были максимально читабельными. Что мне помогает, так это следование стилю BDD, заданному «когда тогда» или «упорядочить-действовать-утверждать», при организации тестового кода. Тестовый класс мог бы это дать, это настройка. Затем, каждый тестовый метод в этом классе использует данное (или его часть) и имеет один, когда и один тогда.

Подумайте также о модульных тестах как о документации по использованию функциональности тестируемого класса. С хорошими модульными тестами вы можете прочитать тесты, чтобы узнать, как использовать функциональные возможности класса, который вы хотите использовать, и каковы будут результаты.

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

Конечно, я согласен с Килианом Фотом: на практике вам может повезти иметь несколько модульных тестов для кода, над которым вы работаете. И любой небольшой локализованный тест лучше, чем вообще никакой тест, или только большие интеграционные тесты, которые выполняются на сервере сборки, занимают много времени и обычно не очень локализованы (они не сообщают вам быстро, где ошибка - вы Надо будет немного поработать над этим).


Хорошая мысль: «Вы хотите сгруппировать методы испытаний в классе испытаний, поэтому, когда вы читаете метод testclassname.testmethod, это имеет смысл».
MAChitgarha

1

Я думаю, это правильно, что у каждого класса есть свой тестовый класс. Идея состоит в том, чтобы централизовать все модульные тесты, связанные с целевым классом, в одном тестовом классе. Тогда, например, MyClass.javaбудет назван его тестовый класс MyClassTest.java.


0

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.