Вопрос о Тесте PHPUnit - Как к Модульному тесту мой класс

Я пытаюсь войти в Поблочное тестирование на очевидные положительные стороны, которые оно представляет, и я пытаюсь записать Модульный тест на класс, который я записал на днях. (Я знаю, что это напротив TDD, терпите меня),

Мой класс, Image, используется в сочетании с некоторыми другими для обработки изображения.

Image по существу обертывает ресурс изображения GD и хранит данные наряду с ним. Например, экземпляр Image будет всегда содержать это - текущее состояние, т.е. его новая ширина/высота, если изменено, данные исходного изображения, и т.д.

Image класс также содержит методы для,

  • При создании себя из файла представьте в виде строки данные или URL, например. $image->loadFromPath()
  • Создание нового GD отображает ресурс от свойств тока Image экземпляр, например, чтобы изменение размеров изображения поддержало прозрачность фона и т.д.
  • Клонирование GD отображает ресурс для использования в классах управления

То, с чем я борюсь, то, как к Модульному тесту этот класс правильно с PHPUnit. Я сделал некоторое чтение, и у меня есть несколько конфликтующих идей о том, как приблизиться к нему, и я не знаю то, что является правильным. Сделайте меня,

  1. Запишите тест для каждого метода класса. Я считал где-нибудь, что должен протестировать каждый метод. Однако некоторые методы работают, другие (справедливо так может я добавлять), таким образом, у Вас тогда есть цепочка зависимости. Но я также считал, что каждый Модульный тест должен быть независим от другого. Таким образом, что я делаю, если это верно?
  2. Запишите каждый тест как маршрут использования класса. Я также считал где-нибудь, что каждый тест должен вместо этого представить 1 маршрут пути/использования, которым можно следовать с классом. Поэтому при покрытии каждого использования Вы в конечном счете получите полное покрытие кода.

Так, какой из них корректен, если таковые имеются?

13
задан Stephen Melrose 20 January 2010 в 15:51
поделиться

2 ответа

Агрегаты должны быть записаны для оценки общедоступного интерфейса класса. Ваш тестовый случай должен использовать класс, поскольку вы собираетесь использовать его в вашей программе. Идея здесь состоит в том, чтобы проверить поведение (или ожидаемых, неожиданных, или краевых условий) класса.

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

Как было упомянуто, 100% тестовое покрытие является хорошей целью, но не всегда реалистично.

Кроме того, в случае GD будьте осторожны о записи модуля тестов, которые тестируют функциональность GD (уже тестировали, вам не нужно тратить время тестировать его снова). Я бы прошел , используя издевательства PhPunit и заглушки (и издеваться над файловой системой) в руководстве PhPunit.

Вот что может выглядеть пример теста:

public function testImageIsResized()
{
    $image = new Image();
    $image->loadFromPath('some/path');
    $image->resize(200, 300);
    $this->assertEquals(200, $image->getWidth());
    $this->assertEquals(300, $image->getHeight());
}

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

9
ответ дан 2 December 2019 в 00:31
поделиться

Ладно, ребята, у меня все работает. Таким образом, установите StartSVN. Bbelieve меня или нет я установил 2.0.8 и через несколько часов получил сообщение от RSS есть новая версия - 2.1, поэтому я сделал обновление (по крайней мере, смог проверить процесс обновления, все прошло просто прекрасно). Затем установить Ruby (я получил 1.8.6), затем Gems (1.3.1 это req, но я получил 1.3.5) При получении Ruby и драгоценных камней введите cmd и введите: gem install rails -v = 2.3.5 затем: gem install rack -v = 1,0,1

, затем я получил последний багажник Redmine. Установлен MySQL 5.0 (5.1 не поддерживается), создать новую БД (через оболочку или gui-инструменты), redmine пользователя и его привилегии.

Затем: gem install mysql + копировать http://instantrails.rubyforge.org/svn/trunk/InstantRails-win/InstantRails/mysql/bin/libmySQL.dll в ruby/bin

редактировать конфигурационный файл для redmine и запустить rack webserver... Эл должен работать. У меня была одна проблема, я не смог увидеть хранилище в недавно созданном проекте redmine.

Решение - redmine.org/boards/2/topics/show/723

Конфигурация шахты выглядит следующим образом: SVN_BIN = «svn --trust-server-cert --non-interactive --config-dir c :/Repositories»

Итак, теперь все работают. Мой следующий шаг, переместить svn repo из ald pc в этот новый. Выполнено:)

-121--3867672-

Поэтому я понял, почему у меня возникла проблема. Я предполагал, что wsdlLocation должен быть WSDL, который фактически публикует служба. Конечно, это не так. Решение состоит в том, чтобы упаковать в клиент локальный WSDL с правильным SOAP: адресом для фактической службы.

изменить Я обнаружил, что вы можете изменить адрес конечной точки программным путем без необходимости изменять фактический WSDL:

HelloService service = new HelloService (
  this.getClass().getResource("originalHello.wsdl"),
  new QName("http://example.org/hello", "HelloService "));
HelloPort proxy = service.getHelloPort();

Map<String, Object> ctxt = ((BindingProvider)proxy ).getRequestContext();
ctxt.put(JAXWSProperties.HTTP_CLIENT_STREAMING_CHUNK_SIZE, 8192);
ctxt.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://new/endpointaddress");

proxy.sayHello("Hello World!");

Кредит переходит к: Цзяньмин Ли

-121--3978084-

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

/**
 * @test
 * @covers MyClass::something()
 * @covers MyClass::_somethingElse()
 */
public function somethingWorksAsExpected()
{
    $this->assertSame($expected, $this->testObject->something());
}

Для личных проектов 100% покрытие кода нормально. Тем не менее, я видел разговоры на конференциях, где 100% сомневаются в необходимости. Несмотря на все преимущества, тесты требуют времени для написания, и в бюджетном проекте может быть достаточно просто протестировать 80/20 и исключить некритические низкоприоритетные функции вашего приложения.

Что касается тестирования вашего класса, ознакомьтесь с главой Разработка поведения в руководстве PHPUnit . В вашем случае, я бы проверил функциональность, которую вы описали в вашем вопросе.

5
ответ дан 2 December 2019 в 00:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: