Проверка составного объекта, когда компоненты уже проверены -> избыточны? - PullRequest
4 голосов
/ 04 марта 2012

У меня есть общий вопрос, проиллюстрированный конкретным примером. Сколько бы вы порекомендовали тестировать составные объекты, когда все компоненты компонентов уже протестированы?

В качестве конкретного примера рассмотрим NullTeridityStringReader ниже. Он читает из байтового буфера строку с нулевым символом в конце. Для этого используется декодер Javas Charset.

Я, конечно, хочу протестировать мой NullTeridityStringReader. Он должен уметь читать все виды строк, такие как UTF8, UTF16, ASCII и т. Д.

Представьте, что я написал CharsetDecoder и проверил, что он будет декодировать символы из всех возможных кодировок. Это действительно хорошо проверено и испытано, и я не сомневаюсь, что это работает. Теперь я пишу NullTeridityStringReader, который использует CharsetDecoder. Теоретически я хочу, чтобы NullTeridityStringReader мог обрабатывать все строки кодировок, которые может декодировать CharsetDecoder. Если бы я использовал TDD, я бы хотел управлять своим дизайном, поэтому я бы написал множество тестов, тестирующих декодирование каждой кодировки для NullTerminationStringReader:

...
void testNullTerminatedStringReaderCanDecodeUTF8String()
void testNullTerminatedStringReaderCanDecodeASCIIString()
...

Но это кажется избыточным, потому что в тесте для CharsetDecoder у меня есть все эти тесты:

...
void testCharsetDecoderCanDecodeUTF8Char()
void testCharsetDecoderCanDecodeASCIIChar()
...

Я не уверен, что здесь делать, потому что без тестов для NullTeridityStringReader, как я могу управлять его дизайном для поддержки всех этих декодирований? Я тестирую на неправильном уровне для NullTerminationStringReader? Если я не выполняю тесты, это также кажется, что чего-то не хватает, потому что в теории я знаю, что NullTeridityStringReader использует CharsetDecoder, и я знаю, что все, что он делает, это добавляет символы для формирования строки, так что здесь мало что может пойти не так. Если CharsetDecoder работает, то должен работать NullTeridityStringReader. Но что, если он не использовал CharsetDecoder - я думаю, что более понятно не предполагать, что он не знает о реализации NullTerminationStringReader, а затем писать тесты, однако это приводит к тому, что кажется избыточными ... dillema? Вы ставите.

class NullTerminatedStringReader
{
    private Charset charset;

    public String read(ByteBuffer buffer)
    {
        StringBuilder sb = new StringBuilder();
        while (true)
        {
            char charVal = readChar(buffer, charset.newDecoder()); // unicode char, possibly span several bytes
            if (charVal == '\0')
                break;
            sb.append(charVal);
        }

        return sb.toString();
    }

    private char readChar(ByteBuffer buffer, CharsetDecoder decoder) {...}
}

Ответы [ 2 ]

1 голос
/ 04 марта 2012

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

  • необходимо знать контракт компонента, который вы используете повторно (до и после условия CharsetDecoder, который вы используете вreadChar), чтобы ваш NullTerminationStringReader мог использовать какой-то другой компонент, который выполняет контракт.Но вам не нужно знать, что вы используете реализацию CharsetDecoder.
  • не нужно повторно тестировать функциональность компонента, который вы повторно используете: вы можете просто принять постусловия, если вы соответствуете предусловиям.
  • используйте эти предварительные условия для TDD для управления вашим дизайном NullTerminationStringReader, но вы можете предположить, что постусловия выполнены.И используйте постусловия для TDD, чтобы управлять вашим дизайном некоторой реализации, например CharsetDecoder, если вам все еще нужно его создать.Но для этого можно предположить, что предварительные условия будут выполнены.
1 голос
/ 04 марта 2012

При тестировании составного объекта я обычно проверяю две вещи:

  • Поддерживает ли он составные сквозные сценарии использования, для которых он предназначен?
  • Работает ли добавочная возможность, добавленная составным объектом?

В общем, я бы не стал всесторонне тестировать подобъекты, поскольку для этого у них должны быть свои собственные тестовые случаи. то есть вы должны предполагать, что ваши собственные подобъекты работают так же, как вы полагаете, что java.util.ArrayList работает.

Итак, в вашем примере с NullTeridityStringReader я бы, вероятно, только протестировал, что он работает с одной или двумя альтернативными кодировками (т. Е. Докажу, что он вызывает правильный CharsetDecoder), и верю, что CharsetDecoder был достаточно хорошо протестирован для работы. другие кодировки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...