Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Общие вопросы по программированию, компьютерный форум
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 30.05.2011, 18:09   #1
alexinspir
Новичок
Джуниор
 
Аватар для alexinspir
 
Регистрация: 26.08.2008
Сообщений: 1,010
По умолчанию Test-Driven Development на практике

Test-Driven Development (TDD, разработка через тестирование) является одной из основополагающих техник экстремального программирования, но к сожалению, в россии очень немногие разработчики умеют ею пользоваться.

В настоящей теме, я постараюсь показать на практике что это за фрукт и как его едят

Разработка через тестирование подразумевает следующие этапы, которые в 90% случаев идут строго по порядку(об оставшихся 10% скажу позднее):

1. пишется пустой класс А (релизный)
2. пишется класс ATest (тестовый) и в нем создаются заглушки всех тестовых методов(определяем весь функционал который нам нужен от класса А)
3. создаем заглушки методов в классе А, которые должны реализовывать весь необходимый функционал, который выявился на этапе 2
4. Если выявились недостающие тесты, то они декларируются, и реализуются все тестовые методы в классе ATest до конечной стадии. и прогоняем тесты. все тесты должны завершиться с ошибкой (именно ошибкой из-за UnsupportedOperationException, которые выкидываются из класса А), за некоторым специфичным исключением(например, проверка наследования).
5. реализуем все методы в классе A, прогоняем тесты - все тесты должны завершиться успешно.


Примером будут служить 2 класса (релизный и тестовый) из проекта Kelvina, в разработке которого участвую я и мой коллега.
Язык - Java.
Модульные тесты написаны при помощи JUnit.

В роли класса А будет: RollbackReaderWrapper
В роли класса ATest будет: RollbackReaderWrapperTest
ромик0: Cколько получают здешние модераторы?
pu4koff: У модераторов сдельная оплата труда. Выдал предупреждение - плюс к премии. Выдал бан - лучший модератор месяца со всеми вытекающими.

Последний раз редактировалось alexinspir; 06.06.2011 в 05:02.
alexinspir вне форума Ответить с цитированием
Старый 30.05.2011, 18:13   #2
alexinspir
Новичок
Джуниор
 
Аватар для alexinspir
 
Регистрация: 26.08.2008
Сообщений: 1,010
По умолчанию Этап первый.

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

Код:
/*
 * Copyright 2011 Aleksandr Akhtyamov.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ru.wsdev.kelvina.system.io;

/**
 * Служит в качестве обертки вокруг java.io.Reader.
 * Расширяет функционал Reader'а, позволяя откатывать 
 * позицию курсора на любую позицию в заранее определенном интервале.
 * @author Aleksandr Akhtyamov
 */
public class RollbackReaderWrapper {
   
}
ромик0: Cколько получают здешние модераторы?
pu4koff: У модераторов сдельная оплата труда. Выдал предупреждение - плюс к премии. Выдал бан - лучший модератор месяца со всеми вытекающими.
alexinspir вне форума Ответить с цитированием
Старый 30.05.2011, 18:24   #3
alexinspir
Новичок
Джуниор
 
Аватар для alexinspir
 
Регистрация: 26.08.2008
Сообщений: 1,010
По умолчанию Этап второй.

Для того чтобы определиться какой функционал требуется от класса, мы создадим тестовый класс RollbackReaderWrapperTest.
Методами тестового класса(далее - тестовые методы [Test Method]), мы будем определять весь функционал, который нам потребуется от релизного класса.
Каждый тестовый метод будет реализован в соответствии с принципом "проверяйте одно условие за тест" (Verify One Condition per Test).
Комментарии на русском языке даны чисто для объяснения моих рассуждений, в тестах практически не пишут документационные комментарии.
В последующих примерах комментарии будут удалены.
Код:
/*
 * Copyright 2011 Aleksandr Akhtyamov.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ru.wsdev.kelvina.system.io;


import static org.junit.Assert.fail;

import org.junit.Test;

/**
 * @author Aleksandr Akhtyamov
 *
 */
public class RollbackReaderWrapperTest {
   /*
    * В релизном классе должен быть только один конструктор, 
    * который принимает оборачиваемый ридер и размер буфера.
    * Он НЕ ДОЛЖЕН конструировать объект, если обрачиваемый ридер есть null.
    */
   @Test
   public void testNullPointerWrappedReader(){
      fail("not implemented yet");
   }
   
   /*
    * В релизном классе должен быть метод, 
    * который активизирует буферизацию, чтобы возможен был откат.
    */
   @Test
   public void testEnableBuffer(){
      fail("not implemented yet");
   }
   
   /*
    * В релизном классе должен быть метод, 
    * который деактивирует буферизацию.
    */
   @Test
   public void testDisableBuffer(){
      fail("not implemented yet");
   }
   
   /*
    * В релизном классе должен быть метод,
    * который возвращает текущее заполнение буфера (размер содержимого).
    */
   @Test
   public void testBufferFilling(){
      fail("not implemented yet");
   }
   
   /*
    * В релизном классе должен быть метод, 
    * который реализует откат
    */
   @Test
   public void testRollback(){
      fail("not implemented yet");
   }
   
   /*
    * У буфера должен быть размер, при откате большем чем размер буфера, 
    * должно кидаться исключение
    */
   @Test
   public void testBufferOverflow(){
      fail("not implemented yet");
   }
   
   /*
    * В релизном классе должен быть метод, 
    * который говорит, активирована буферизация или нет.
    * мы должны проверить, то что он адекватно говорит об активной буферизации.
    */
   @Test
   public void testBufferMustBeEnabled(){
      fail("not implemented yet");
   }
   
   /*
    * и адекватно говорит об отключенной буферизации
    */
   @Test
   public void testBufferMustBeDisabled(){
      fail("not implemented yet");
   }
   
   /*
    * По скольку мы реализуем обертку вокруг ридера, то обертка вполне может быть
    * сабклассом java.io.Reader, и переопределять все его методы.
    * Проверим что RollbackReaderWrapper наследует ридер. 
    */
   @Test
   public void testKindOfRollbackReaderWrapperTestIsReader(){
      fail("not implemented yet");
   }
}
ромик0: Cколько получают здешние модераторы?
pu4koff: У модераторов сдельная оплата труда. Выдал предупреждение - плюс к премии. Выдал бан - лучший модератор месяца со всеми вытекающими.

Последний раз редактировалось alexinspir; 30.05.2011 в 18:31.
alexinspir вне форума Ответить с цитированием
Старый 31.05.2011, 11:25   #4
alexinspir
Новичок
Джуниор
 
Аватар для alexinspir
 
Регистрация: 26.08.2008
Сообщений: 1,010
По умолчанию Этап второй. продолжение.

Мы определили какие нам методы нужны от класса, вот они:

-один конструктор с двумя параметрами
-метод aктивации буфера
-метод деактивации буфера
-метод возвращающий текущее наполнение буфера
-метод отката
-метод возвращающий текущее состояние буферизации (активна/неактивна)
и методы унаследованные от java.io.Reader

чтож, давайте подвергнем критике.

Конструктор
Критика:
Почему только 1 конструктор? почему не может быть 2 конструктора, первый из которых мы определили, а второй принимает лишь оборачиваемый ридер и ставит размер буфера по умолчанию?
Решение:
добавляем второй конструктор. добавляем публичную, статическую константу, которая будет хранить размер по умолчанию для буфера.


Буфер
Критика:
Активация и деактивация буфера - как будет вести себя класс при повторной активации буфера, без промежуточной деактивации?
у нас есть методы read/skip/reset, унаследованные от java.io.Reader - как ведет себя буфер при их вызовах?
Как ведет себя буфер при переполнении?
Рассуждение:
В нашем случае ридер будет перебрасываться между множеством экземпляров парсеров туда-обратно. из чего следует, что работа с RollbackReaderWrapper'ом, при мануальной (по требованию) работе буфера будет достаточно сложной - надо будет контролировать его текущее состояние.
Также будет очень тяжелая работа по кодированию функционала мануальной работы буфера, с учетом появившихся вопросов.
Решение:
Буфер сделаем неявным, и постоянно активным.
Так как буфер будет неявным, и буферизация будет идти постоянно, то нам будут нужны методы:
-очистка буфера
-закрытие обертки с возвращением обернутого ридера, при этом текущая позиция курсора враппера должна совпадать с курсором обернутого ридера - ридер не должен быть в состоянии отката (это может привести к потере данных и ошибкам у невнимательных и неопытных программистов, использующих RollbackReaderWrapper)

Наследование от java.io.Reader
Критика:
Т.к. в качестве оборачиваемого ридера используется java.io.Reader, то вполне возможно оборачивание RollbackReaderWrapper'а в другой RollbackReaderWrapper, что будет явно не самым хорошим решением - может иметь место у неопытных программистов, и существенно замедлять работу объекта.
Решение:
Если оборачиваемый ридер является экземпляром RollbackReaderWrapper'а, то объект не должен конструироваться.

Перепишем декларации тестов, с учетом всех рассуждений и выводов.

Так как размер декларации получился очень большой, то разрежу ее на ТРИ поста
ромик0: Cколько получают здешние модераторы?
pu4koff: У модераторов сдельная оплата труда. Выдал предупреждение - плюс к премии. Выдал бан - лучший модератор месяца со всеми вытекающими.

Последний раз редактировалось alexinspir; 31.05.2011 в 17:21.
alexinspir вне форума Ответить с цитированием
Старый 31.05.2011, 16:13   #5
alexinspir
Новичок
Джуниор
 
Аватар для alexinspir
 
Регистрация: 26.08.2008
Сообщений: 1,010
По умолчанию Этап второй. продолжение.

Код:
/*
 * Copyright 2011 Aleksandr Akhtyamov.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ru.wsdev.kelvina.system.io;


import static org.junit.Assert.fail;

import org.junit.Test;

/**
 * @author Aleksandr Akhtyamov
 *
 */
public class RollbackReaderWrapperTest {

   // ............................................................
   
   /*
    * По скольку мы реализуем обертку вокруг ридера, то обертка вполне может быть
    * сабклассом java.io.Reader, и переопределять все его методы.
    * Проверим что RollbackReaderWrapper наследует ридер. 
    */
   @Test
   public void testKindOfRollbackReaderWrapperTestMustBeReader(){
      fail("not implemented yet");
   }
   
   /*
    * Проверяем первый конструктор с двумя параметрами на недопустимость null-ридера
    */
   @Test
   public void testReaderIntConstructor_NullPointerReader(){
      fail("not implemented yet");
   }
   
   /*
    * и что он матерится, если оборачиваемый ридер является экземпляром RollbackReaderWrapper'а
    */
   @Test
   public void testReaderIntConstructor_UnsupportedReaderInstance(){
      fail("not implemented yet");
   }
   
   /*
    * и спокойной принимает в качестве оборачиваемого ридера экземпляр не RollbackReaderWrapper'а 
    */
   @Test
   public void testReaderIntConstructor_SupportedReaderInstance(){
      fail("not implemented yet");
   }
   
   /*
    * проверим что конструктор адекватно принимает допустимый размер
    */
   @Test
   public void testReaderIntConstructor_ValidBufferSize(){
      fail("not implemented yet");
   }
   
   /*
    * и что матерится на слишком большой размер
    */
   @Test
   public void testReaderIntConstructor_InvalidBufferSize(){
      fail("not implemented yet");
   }
   
   /*
    * Проверяем второй конструктор с одним параметрами на недопустимость null-ридера
    */
   @Test
   public void testReaderConstructor_NullPointerReader(){
      fail("not implemented yet");
   }
   
   /*
    * и что он матерится, если оборачиваемый ридер является экземпляром RollbackReaderWrapper'а
    */
   @Test
   public void testReaderConstructor_UnsupportedReaderInstance(){
      fail("not implemented yet");
   }
   
   /*
    * и спокойной принимает в качестве оборачиваемого ридера экземпляр не RollbackReaderWrapper'а 
    */
   @Test
   public void testReaderConstructor_SupportedReaderInstance(){
      fail("not implemented yet");
   }
   
   /*
    * Также надо надо протестировать что размер в конструкторе с одним параметром 
    * правильно ставится размер буфера
    */
   @Test
   public void testReaderConstructor_verifyDefaultBufferSize(){
      fail("not implemented yet");
   }
   
   /*
    * Нам все еще нужен метод, сообщающий о состоянии буфера.
    */
   @Test
   public void testBufferFilling(){
      fail("not implemented yet");
   }
   
   /*
    * В релизном классе должен быть метод, 
    * который реализует откат
    */
   @Test
   public void testRollback(){
      fail("not implemented yet");
   }
   
   /*
    * и при откате на дистанцию большую чем есть в буфере, 
    * должно кидаться исключение
    */
   @Test
   public void testInvalidRollbackDistance(){
      fail("not implemented yet");
   }
   
   /*
    * должен быть метод сброса буфера, проверим что он правильно производит сброс
    */
   @Test
   public void testFlushBuffer(){
      fail("not implemented yet");
   }
   
   /*
    * но он должен матерится, если RollbackReaderWrapper находится в состоянии отката при вызове
    */
   @Test
   public void testFlushBuffer_inRollbackState(){
      fail("not implemented yet");
   }
   
   /*
    * должен быть метод закрывающий обертку и возвращающий обернутый ридер,
    * проверим что возвращаемый ридер вернулся "открытым"
    */
   @Test
   public void testExtractWrappedReader_wrappedReaderMustBeOpened(){
      fail("not implemented yet");
   }
   
   /*
    * и что курсор находится на ожидаемой позиции.
    */
   @Test
   public void testExtractWrappedReader_wrappedReaderPositionIsExpected(){
      fail("not implemented yet");
   }
   
   /*
    * и что обертка закрылась
    */
   @Test
   public void testExtractWrappedReader_wrapperIsClosed(){
      fail("not implemented yet");
   }

   // ............................................................

}
ромик0: Cколько получают здешние модераторы?
pu4koff: У модераторов сдельная оплата труда. Выдал предупреждение - плюс к премии. Выдал бан - лучший модератор месяца со всеми вытекающими.
alexinspir вне форума Ответить с цитированием
Старый 31.05.2011, 16:17   #6
alexinspir
Новичок
Джуниор
 
Аватар для alexinspir
 
Регистрация: 26.08.2008
Сообщений: 1,010
По умолчанию Этап второй. продолжение.

Код:
/*
 * Copyright 2011 Aleksandr Akhtyamov.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ru.wsdev.kelvina.system.io;


import static org.junit.Assert.fail;

import org.junit.Test;

/**
 * @author Aleksandr Akhtyamov
 *
 */
public class RollbackReaderWrapperTest {
   // ............................................................
   /*
    * ======== методы переопределенные от Reader =========
    */
   
   /*
    * проверим что метод close() закрывает как обертку так и обернутый ридер
    */
   @Test
   public void testClose_WrapperAndWrappedReaderAreClosed(){
      fail("not implemented yet");
   }
   
   /*
    * По скольку у нас реализован механизм отката, то поддержка меток нам не нужна
    * метод markSupported должен вернуть false
    */
   @Test
   public void testMarkSupported_mustReturnFalse(){
      fail("not implemented yet");
   }
   
   /*
    * и естественно при вызове метода mark(int) должно кидаться исключение
    */
   @Test
   public void testMark_mustThrowAnException(){
      fail("not implemented yet");
   }
   
   /*
    * ну и reset тоже должен кидать исключение
    */
   @Test
   public void testReset_mustThrowAnException(){
      fail("not implemented yet");
   }
   
   /*
    * При вызове всех методов read буфер должен заполнятся последними прочитанными символами
    * Протестируем то что буфер заполняется...
    */
   @Test
   public void testRead_bufferTest(){
      fail("not implemented yet");
   }
   
   @Test
   public void testRead_CharArray_bufferTest(){
      fail("not implemented yet");
   }
   
   @Test
   public void testRead_CharArrayIntInt_bufferTest(){
      fail("not implemented yet");
   }
   
   @Test
   public void testRead_CharBuffer_bufferTest(){
      fail("not implemented yet");
   }
   
   /*
    * ...и что при чтении в массивы и CharBuffer размером большим чем размер 
    * буфера враппера в последнем окажутся только последние прочитанные символы...
    */
   @Test
   public void testRead_CharArray_bufferTestOnExceedRead(){
      fail("not implemented yet");
   }
   
   @Test
   public void testRead_CharArrayIntInt_bufferTestOnExceedRead(){
      fail("not implemented yet");
   }
   
   @Test
   public void testRead_CharBuffer_bufferTestOnExceedRead(){
      fail("not implemented yet");
   }
   
   /*
    * ... а также что они адекватно работают после отката
    */
   @Test
   public void testRead_rollbackTest(){
      fail("not implemented yet");
   }
   
   @Test
   public void testRead_CharArray_rollbackTest(){
      fail("not implemented yet");
   }
   
   @Test
   public void testRead_CharArrayIntInt_rollbackTest(){
      fail("not implemented yet");
   }
   
   @Test
   public void testRead_CharBuffer_rollbackTest(){
      fail("not implemented yet");
   }
   // ............................................................
}
ромик0: Cколько получают здешние модераторы?
pu4koff: У модераторов сдельная оплата труда. Выдал предупреждение - плюс к премии. Выдал бан - лучший модератор месяца со всеми вытекающими.
alexinspir вне форума Ответить с цитированием
Старый 31.05.2011, 16:19   #7
alexinspir
Новичок
Джуниор
 
Аватар для alexinspir
 
Регистрация: 26.08.2008
Сообщений: 1,010
По умолчанию Этап второй. продолжение.

Код:
/*
 * Copyright 2011 Aleksandr Akhtyamov.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ru.wsdev.kelvina.system.io;


import static org.junit.Assert.fail;

import org.junit.Test;

/**
 * @author Aleksandr Akhtyamov
 *
 */
public class RollbackReaderWrapperTest {

   // ............................................................
   /*
    * Проверим метод Ready.
    * Согласно контракту этого метода из java.io.Reader, 
    * метод должен возвращать true, только тогда, 
    * когда следующий вызов read, не будет заблокирован.
    * В нашем случае блокировку проверить мы не сможем, 
    * поэтому мы проверим лишь то что в режиме отката, когда в буфере есть символы,
    * всегда возвращает true.
    * напишем два теста
    */
   @Test
   public void testReady_inRollbackStateWithUnreadyFakeReader(){
      fail("not implemented yet");
   }
   
   @Test
   public void testReady_inRollbackStateWithReadyFakeReader(){
      fail("not implemented yet");
   }
   
   /*
    * и что если обертка не находится в режиме отката, то делегирует этот
    * вызов обертному ридеру.
    * напишем 2 теста
    */
   
   @Test
   public void testReady_inNormalStateWithUnreadyFakeReader(){
      fail("not implemented yet");
   }
   
   @Test
   public void testReady_inNormalStateWithReadyFakeReader(){
      fail("not implemented yet");
   }
   
   /*
    * И остался метод skip, проверим что при его вызове заполняется буфер...
    */
   @Test
   public void testSkip_bufferMustFilling(){
      fail("not implemented yet");
   }
   
   /*
    * ... а также что он корректно работает в режиме отката внутри области отката...
    */
   @Test
   public void testSkip_bufferTestWithinRollbackZone(){
      fail("not implemented yet");
   }
   
   /*
    * ... и в обоих областях 
    * (когда находится в области отката, но пропускается больше символов, 
    * чем дистанция между позицией враппера и позиции оборачиваемого ридера)
    */
   @Test
   public void testSkip_bufferTestInBothZone(){
      fail("not implemented yet");
   }
   // ............................................................
}
ромик0: Cколько получают здешние модераторы?
pu4koff: У модераторов сдельная оплата труда. Выдал предупреждение - плюс к премии. Выдал бан - лучший модератор месяца со всеми вытекающими.
alexinspir вне форума Ответить с цитированием
Старый 31.05.2011, 17:20   #8
alexinspir
Новичок
Джуниор
 
Аватар для alexinspir
 
Регистрация: 26.08.2008
Сообщений: 1,010
По умолчанию Этап третий.

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

Теперь наш тестовый класс будет служить нам документацией для релизного класса.

На основе этой документации, мы видим какие нам нужны методы и что они должны делать - т.е. мы можем сразу написать к методам документационные комментарии.

класс разбит на ДВА поста
Код:
/*
 * Copyright 2011 Aleksandr Akhtyamov.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ru.wsdev.kelvina.system.io;

import java.io.IOException;
import java.io.Reader;
import java.nio.CharBuffer;

/**
 * Служит в качестве обертки вокруг java.io.Reader.
 * Расширяет функционал Reader'а, позволяя откатывать 
 * позицию курсора на любую позицию в заранее определенном интервале.
 * Класс НЕ является потокобезопасным
 * @author Aleksandr Akhtyamov
 */
public class RollbackReaderWrapper extends Reader{

   //..............................................................

   /**
    * Максимальный размер буфера
    */
   public static final int MAX_BUFFER_SIZE = 4096;
   
   /**
    * Размер буфера по умолчанию
    */
   public static final int DEFAULT_BUFFER_SIZE = 1024;
   
   /**
    * Конструирует обертку с указанным размером буфера.
    * @param wrappedReader оборачиваемый ридер
    * @param bufferSize размер буфера
    * @throws IOException если оборачиваемый ридер закрыт или указан недопустимый размер буфера
    */
   public RollbackReaderWrapper(Reader wrappedReader, int bufferSize)throws IOException{
      throw new UnsupportedOperationException("not implemented yet");
   }
   
   /**
    * Конструирует обертку с размером буфера по умолчанию.
    * @param wrappedReader оборачиваемый ридер
    * @throws IOException если оборачиваемый ридер закрыт
    */
   public RollbackReaderWrapper(Reader wrappedReader)throws IOException{
      throw new UnsupportedOperationException("not implemented yet");
   }

   /**
    * Возвращает размер буфера.
    * @return размер буфера.
    * @throws IOException если враппер закрыт
    */
   public int getBufferSize() throws IOException{
      throw new UnsupportedOperationException("not implemented yet");
   }
   
   /**
    * Возвращает размер текущего содержимого буфера
    * @return размер текущего содержимого буфера
    * @throws IOException если враппер закрыт
    */
   public int getBufferFillSize() throws IOException{
      throw new UnsupportedOperationException("not implemented yet");
   }
   
   /**
    * Откатывает позицию ридера на указанную дистанцию.
    * @param distance дистанция отката
    * @throws IOException если дистанция превышает размер содержимого буфера или буфер закрыт.
    */
   public void rollback(int distance)throws IOException{
      throw new UnsupportedOperationException("not implemented yet");
   }
   
   /**
    * Сбрасывает буфер.
    * @throws IOException если враппер находится в состоянии отката или он закрыт.
    */
   public void flushBuffer()throws IOException{
      throw new UnsupportedOperationException("not implemented yet");
   }
   
   /**
    * Разворачивает ридер.
    * @return обернутый ридер.
    * @throws IOException если враппер находится в состоянии отката или он закрыт
    */
   public Reader unwrapReader() throws IOException{
      throw new UnsupportedOperationException("not implemented yet");
   }

   //..............................................................

}
ромик0: Cколько получают здешние модераторы?
pu4koff: У модераторов сдельная оплата труда. Выдал предупреждение - плюс к премии. Выдал бан - лучший модератор месяца со всеми вытекающими.

Последний раз редактировалось alexinspir; 31.05.2011 в 18:38.
alexinspir вне форума Ответить с цитированием
Старый 31.05.2011, 17:25   #9
alexinspir
Новичок
Джуниор
 
Аватар для alexinspir
 
Регистрация: 26.08.2008
Сообщений: 1,010
По умолчанию Этап третий. продолжение.

Код:
/*
 * Copyright 2011 Aleksandr Akhtyamov.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ru.wsdev.kelvina.system.io;

import java.io.IOException;
import java.io.Reader;
import java.nio.CharBuffer;

/**
 * Служит в качестве обертки вокруг java.io.Reader.
 * Расширяет функционал Reader'а, позволяя откатывать 
 * позицию курсора на любую позицию в заранее определенном интервале.
 * Класс НЕ является потокобезопасным
 * @author Aleksandr Akhtyamov
 */
public class RollbackReaderWrapper extends Reader{

   //..............................................................


   /**
    * @see java.io.Reader#close()
    */
   @Override
   public void close() throws IOException {
      throw new UnsupportedOperationException("not implemented yet");
   }

   /**
    * @see java.io.Reader#mark(int)
    */
   @Override
   public void mark(int readAheadLimit) throws IOException {
      throw new UnsupportedOperationException("not implemented yet");
   }
   
   /**
    * @see java.io.Reader#markSupported()
    */
   @Override
   public boolean markSupported(){
      throw new UnsupportedOperationException("not implemented yet");
   }
   
   /**
    * @see java.io.Reader#read()
    */
   @Override
   public int read() throws IOException {
      throw new UnsupportedOperationException("not implemented yet");
   }
   
   /**
    * @see java.io.Reader#read(char[])
    */
   @Override
   public int read(char[] cbuf) throws IOException{
      throw new UnsupportedOperationException("not implemented yet");
   }
   
   /**
    * @see java.io.Reader#read(char[], int, int)
    */
   @Override
   public int read(char[] cbuf, int off, int len) throws IOException {
      throw new UnsupportedOperationException("not implemented yet");
   }
   
   /**
    * @see java.io.Reader#read(CharBuffer)
    */
   @Override
   public int read(CharBuffer target) throws IOException{
      throw new UnsupportedOperationException("not implemented yet");
   }
   
   /**
    * @see java.io.Reader#ready()
    */
   @Override
   public boolean ready() throws IOException{
      throw new UnsupportedOperationException("not implemented yet");
   }
   
   /**
    * @see java.io.Reader#reset()
    */
   @Override
   public void reset() throws IOException{
      throw new UnsupportedOperationException("not implemented yet");
   }
   
   /**
    * @see java.io.Reader#skip(long)
    */
   @Override
   public long skip(long n) throws IOException{
      throw new UnsupportedOperationException("not implemented yet");
   }

   //..............................................................

}
ромик0: Cколько получают здешние модераторы?
pu4koff: У модераторов сдельная оплата труда. Выдал предупреждение - плюс к премии. Выдал бан - лучший модератор месяца со всеми вытекающими.
alexinspir вне форума Ответить с цитированием
Старый 04.06.2011, 01:03   #10
alexinspir
Новичок
Джуниор
 
Аватар для alexinspir
 
Регистрация: 26.08.2008
Сообщений: 1,010
По умолчанию Этап четвертый.

На этом этапе мы реализуем все декларированные тесты.

В ходе реализации всех тестовых методов, стало ясно что потенциально будут полезны еще два метода в релизном классе:
-isClosed()
-inRollbackMode()

Что касается самой реализации:
Так как подготовка объектов релизного класса невозможна извне, а только лишь с помощью его собственных методов, то очень многие тесты являются пересекающимися (Test Overlap).
Пересечения тестов - это ситуация, когда тесты используют некую общую функциональность, при изменении которой, все тесты которые ее используют (note: не обязательно тестируют) отказывают или вообще завершаются с ошибкой.
Пересечения тестов являются крайне нежелательными, и при любой возможности от них стараются избавиться. В моем же случае у меня нет достаточно времени и опыта чтобы найти способ избавиться от них.

Выше опубликованная декларация методов тестового класса была изменена (в соответствии с именами методов в релизном классе) а также были добавлены новые тесты.

Для удобства понимания использовалась только новая тестовая конфигурация (Fresh Fixture) для каждого теста.
Для гарантии корректности некоторых тестов использовались подставные объекты (Fake Object).

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


Следующий, и последний, этап - реализация методов релизного класса.
Вложения
Тип файла: txt RollbackReaderWrapperTest.java.txt (20.6 Кб, 129 просмотров)
ромик0: Cколько получают здешние модераторы?
pu4koff: У модераторов сдельная оплата труда. Выдал предупреждение - плюс к премии. Выдал бан - лучший модератор месяца со всеми вытекающими.

Последний раз редактировалось alexinspir; 06.06.2011 в 04:09. Причина: замена файла, был недописан последний тест.
alexinspir вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Test-driven development [Smarik] Свободное общение 2 30.03.2011 10:46
Ответ по практике StudentMarat Свободное общение 1 14.09.2010 23:57
Задание по практике IPI Помощь студентам 4 15.06.2010 12:31
Отчот по практике sby Фриланс 3 12.05.2009 17:16
Программа по практике Antowka БД в Delphi 0 15.10.2007 10:40