TDD: Какие методы вы выставляете для модульного тестирования?

Прежде всего: вы не должны использовать .*, если можете быть более конкретным, как в этом случае [^/]+. Потому что несколько .* могут вызвать огромный откат. Итак:

RewriteRule ^viewshoplatest/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/$ /viewshoplatest.php?$1=$2&$3=$4&$5=$6&$7=$8&$9=$10&$11=$12&$13=$14&$15=$16

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

Но поскольку mod_rewrite делает только позволяют ссылаться на первые девять групп (см. ответ Тима ), вы можете использовать итеративный подход и обрабатывать по одному параметру за раз:

RewriteRule ^viewshoplatest/([^/]+)/([^/]+)/([^/]+/[^/]+/.*)$ /viewshoplatest/$3?$1=$2 [QSA,N]
RewriteRule ^viewshoplatest/([^/]+)/([^/]+)/([^/]*)/?$ /viewshoplatest.php?$1=$2&$3 [QSA,L]

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

Но поскольку использование флага N может быть опасным, поскольку это может привести к бесконечному recursion, вы также можете использовать PHP для анализа запрошенного пути:

$_SERVER['REQUEST_URI_PATH'] = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$segments = implode('/', trim($_SERVER['REQUEST_URI_PATH'], '/'));
array_shift($segments); // remove path prefix "/viewshoplatest"
for ($i=0, $n=count($segments); $i<$n; ) {
    $_GET[rawurldecode($segments[$i++])] = ($i < $n) ? rawurldecode($segments[$i++]) : null;
}

Теперь вам просто нужно это правило, чтобы передать запрос через:

RewriteRule ^viewshoplatest(/|$) /viewshoplatest.php [L]

16
задан Yuval Adam 22 December 2008 в 15:20
поделиться

9 ответов

  1. тестируют функции; это обычно означает тестировать открытый интерфейс - на, не должен все функции быть доступным через открытый интерфейс? если они не, то они не функции! Могут быть исключения к этому, но я не могу думать ни о ком.

  2. тестируют открытый интерфейс; любые методы, которые не называют прямо или косвенно от открытого интерфейса, не необходимы . Мало того, что они не должны быть протестированы, они не должны существовать вообще.

14
ответ дан Steven A. Lowe 22 December 2008 в 15:20
поделиться

Необходимо смотреть на тот вопрос: Вы тестируете закрытый метод? .

Для не повреждения инкапсуляции я нахожу, что закрытый метод огромен или сложен или достаточно важен для требования его собственных тестов, я просто поместил его в другой класс и обнародовал его там (Объект Метода). Тогда я могу легко протестировать previously-private-but-now-public метод, который теперь живет на своем собственном классе.

6
ответ дан Community 22 December 2008 в 15:20
поделиться

Используя Ваш пример Стека, Вы действительно не должны должны быть представлять любые внутренние работы модульному тесту это. Повторяя, что сказали другие, необходимо не стесняться иметь как много закрытых методов по мере необходимости, но только тестировать через общедоступный API.

[Test]
public void new_instance_should_be_empty()
{
  var stack = new Stack();

  Assert.That(stack.IsEmpty(), Is.True);
}

[Test]
public void single_push_makes_IsEmpty_false()
{
  var stack = new Stack();

  stack.Push("first");

  Assert.That(stack.IsEmpty(), Is.False);
}

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

[Test]
public void three_pushes_and_three_pops_results_in_empty_stack()
{
  var stack = new Stack();

  stack.Push("one");
  stack.Push("two");
  stack.Push("three");
  stack.Pop();
  stack.Pop();
  stack.Pop();

  Assert.That(stack.IsEmpty(), Is.True);
}
4
ответ дан James Gregory 22 December 2008 в 15:20
поделиться

Иногда я делаю методы, которые иначе были бы частными на уровень пакета (Java) или внутренними (.NET) методы, обычно с комментарием или аннотацией/атрибутом для объяснения почему.

Большую часть времени, однако, я стараюсь не делать это. Что общедоступный API не позволил бы Вам протестировать в Вашем случае стека? Если пользователь видит ошибку, и они только используют общедоступный API, что мешает Вам выполнить те же вызовы?

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

2
ответ дан Jon Skeet 22 December 2008 в 15:20
поделиться

правильный TDD - все о тестировании поведения, которое могло быть протестировано открытым интерфейсом..., если существует, любые закрытые методы тогда, те методы должны быть косвенно протестированы любым открытым интерфейсом...

2
ответ дан StackUnderflow 22 December 2008 в 15:20
поделиться

Если бы Ваш закрытый метод весьма непосредственно тестируется общедоступными методами тестирования API, и он должен быть протестирован тогда, я делегировал бы Ваш основной класс к другому вторичному классу.

public Stack {
    public ... push(...) {...}
    public ... pop(...) {...}
    public ... isEmpty(...) {...}

    // secondary class
    private StackSupport stackSupport;
    public StackSupport getStackSupport() {...}
    public void setStackSupport(StackSupport stackSupport) {...}
}

public StackSupport {
    public ...yourOldPrivateMethodToTest(...) {...}
}

Тогда Ваш закрытый метод является открытым методом в другом классе. И можно протестировать тот открытый метод в другом классе тесты.:-)

0
ответ дан Daniel Fanjul 22 December 2008 в 15:20
поделиться

С TDD весь Ваш код должен быть достижимым от Вашего открытого интерфейса:

  • Первый Вы пишете тесты для своих функций.
  • Тогда Вы пишете минимальное количество кода для Ваших тестов для передачи. Это - признак, что Ваши опции реализованы.

, Если некоторый код не покрыт, это означает, что любой этот код бесполезен (удалите его и запустите свои тесты снова), или Ваши тесты являются неполными (некоторые опции были реализованы, но не explicitely определенный тестом).

2
ответ дан mouviciel 22 December 2008 в 15:20
поделиться

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

0
ответ дан Rogez Sanchez 22 December 2008 в 15:20
поделиться

При кодировании использования TDD я создаю API открытого интерфейса для объекта. Это означало бы в Вашем примере, что мой интерфейс, который реализации класса будут только иметь push(), pop() и isEmpty().

Однако тестирование этих методов путем вызова их не является модульными тестами в себе (больше на этом в конце этого сообщения) , так как они, скорее всего, тестируют сотрудничество нескольких внутренних методов, которые вместе приводят к желаемому результату, и это - то, о чем вопрос: те методы должны быть частными?

Мой ответ не, используйте protected (или эквивалент его на языке по Вашему выбору) для тех вместо private, что означает, что, если Ваш проект и тестовые АНГЛИЧАНЕ структурированы точно так же, класс набора тестов видит в фактическом классе, так как они находятся фактически в той же папке. Их можно считать модульными тестами: Вы тестируете функциональные блоки самого класса, не их сотрудничество.

Что касается тестирования отдельных методов интерфейса/API, конечно, важно сделать это также, и я не подвергаю сомнению тот факт, что, те однако падают где-нибудь между туманной строкой поблочное тестирование и приемочные испытания .

, По-моему, самая важная вещь помнить вот состоит в том, что модульные тесты говорят Вам, если метод неправильно себя ведет, приемочные испытания говорят, неправильно себя ведет ли сотрудничество нескольких методов/классов, и интеграционное тестирование говорит, неправильно себя ведет ли сотрудничество нескольких систем.

-1
ответ дан Esko 22 December 2008 в 15:20
поделиться
Другие вопросы по тегам:

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