Должен ли я проверять случаи, когда ничего не ожидается

A Sample может быть удален, если статус S или P. У меня эти тесты:

@Test
public void canBeDeletedWhenStatusIsP() {
    Sample sample = new Sample();
    sample.setState("P");
    assertTrue(sample.canBeDeleted());
}

@Test
public void canBeDeletedWhenStatusIsS() {
    Sample sample = new Sample();
    sample.setState("S");
    assertTrue(sample.canBeDeleted());
}

Должен ли я идти дальше? Как проверить, удаляется ли образец ? Например:

@Test
public void cantBeDeletedWhenStatusINeitherPNorS() {
    Sample sample = new Sample();
    sample.setState("Z");
    assertFalse(sample.canBeDeleted());
}

Этот тест полезен? Как насчет названия тестов? Будет ли эта логика достаточно проверена?

Ответ 1

SaintThread дает вам хороший "прямой" ответ.

Но давайте отступим. Потому что вы делаете что-то не так в своем производственном коде. Скорее всего, ваш производственный код делает что-то вроде переключения на эту строку, которая обозначает состояние образца. И не только один раз, но и во всех его методах. И... это не хороший дизайн OO!

Вместо этого вы должны использовать полиморфизм, например:

abstract class Sample {
  boolean canBeDeleted();
// ... probably other methods as well

с и различными конкретными подклассами, такими как

class ZSample extends Sample {
  @Override canBeDeleted() { return false; }
// ...

И, наконец, у вас есть

class SampleFactory {
  Sample createSampleFrom(String stateIdentifier) {
  // here you might switch over that string and return a corresponding object, for example of class ZSample

И тогда ваши тесты сводятся к следующему:

  • Тестирование factory; пример для ввода "Z", он возвращает экземпляр ZSample
  • Тестирование всех ваших подклассов Sample; например, canBeDeleted() возвращает false для экземпляра ZSample

Дело в том, что ваш код выполняет работу FSM (конечный автомат). Тогда не используйте, если /elses повсюду; вместо этого выполните OO: создайте явный конечный автомат. И бесплатный бонус: этот подход также позволил бы превратить ваши образцы в объекты неизменяемые; который чаще всего лучше, чем иметь дело с объектами, которые могут изменять свое состояние с течением времени (поскольку неизменность помогает много с многопоточными проблемами, например).

Отказ от ответственности: если ваш класс "Образец" относится только к одному методу, возможно, вышеперечисленное является излишним. Но в любом другом случае... возможно, отступите назад и посмотрите, добавят ли мои предложения ценность для вашего дизайна!

Ответ 2

По-моему, вы должны проверить:

cantBeDeletedWithoutStatus

assertFalse(sample.canBeDeleted());

cantBeDeletedWhenStatusIsInvalid

sample.setState("Z");
assertFalse(sample.canBeDeleted());

cantBeDeletedWhenStatusIsToggledToInvalid

sample.setState("P");
sample.setState("Z");
assertFalse(sample.canBeDeleted());

canBeDeletedWhenStatusIsToggledToS

sample.setState("Z");
sample.setState("S");
assertFalse(sample.canBeDeleted());

canBeDeletedWhenStatusIsToggledToP

sample.setState("Z");
sample.setState("P");
assertFalse(sample.canBeDeleted());

Сообщите мне свои мысли в комментариях

Ответ 3

Нам нужно, чтобы наши тесты были тщательными, поэтому они могут обнаружить множество классов ошибок. Итак, простой ответ - да, протестируйте случай no-op.

Вы не указываете, какие возможные значения для состояния. Предположим, что они должны быть заглавными английскими буквами, дающими 26 состояний. Тогда ваш вопрос по существу совпадает с "должен ли я иметь 26 тестовых случаев". Это много, но не слишком много. Теперь представьте себе более сложный случай, для которого состояние является int и все значения int возможны. Тестирование их всех было бы непрактичным. Что делать?

Средством для тестирования при наличии очень большого количества входов или начальных состояний является использование эквивалентности partitiong. Разделите входы или состояния на множества входов и наборы состояний, так что все элементы в наборе должны приводить к одному и тому же поведению и смежны друг с другом. Таким образом, в вашем случае разделы эквивалентности могут быть A-O, P, Q-R, S, T-Z. Тогда для каждого раздела есть один тестовый пример.