2016-08-19 2 views
10

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()); 
} 

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

ответ

13

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 

И потом, ваши испытания сводятся к:

  1. Испытание завода; пример для ввода «Z», он возвращает экземпляр ZSample
  2. Тестирование всех ваших подклассов Образца; например, canBeDeleted() возвращает false для экземпляра ZSample

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

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

+0

Спасибо. Отличное объяснение. –

+1

Добро пожаловать. Забавная вещь; в первый раз я получаю +10 баллов по двум ответам ... в тот же день. Жаль, что большая часть этой репутации ... для меня потеряна. Но все же - рад, что я мог бы помочь! – GhostCat

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()); 

Позвольте мне знать ваши мысли в комментариях

+0

Спасибо. Это было полезно :) –

1

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

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

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

Смежные вопросы