2008-12-08 3 views
23

Я хочу провести некоторое функциональное тестирование на (спокойном) веб-сервисе. Testuite содержит кучу тестовых примеров, каждый из которых выполняет пару HTTP-запросов в веб-сервисе.JUnit 4: Настройте вещи в наборе тестов до запуска тестов (например, метод @BeforeClass для теста, только для тестового набора)

Естественно, веб-сервис должен запускаться или тесты не сработают. :-)

Запуск web-сервиса занимает пару минут (он делает некоторые тяжелые подъемы данных), поэтому я хочу начать его как можно реже (по крайней мере, все тестовые примеры, которые могут использовать только ресурсы GET из службы).

Итак, есть ли способ установить бомбу в тестовом наборе, прежде чем тесты будут запущены, как в методе @BeforeClass тестового примера?

ответ

1

jUnit не может делать такого рода вещи - хотя TestNG имеет @BeforeSuite и @AfterSuite аннотации. Как правило, вы получаете свою систему сборки для этого. В maven существуют фазы «pre-integration-test» и «post-integration-test». В ANT, вы просто добавляете шаги к задаче.

Ваш вопрос в значительной степени является овалом Before and After Suite execution hook in jUnit 4.x, поэтому я хотел бы взглянуть на предложения там.

+0

Почему BeforeSuite и AfterSuite не работает? – guerda 2008-12-09 06:59:06

-3

Как и в сторону, это плохая идея иметь модульных тестов на самом деле вызывая внешние ресурсы, такие как веб-сервисы, базы данных и т.д.

Юнит-тесты должны быть супер-быстро бежать и задержку «пару минут» для каждого запуска пакета будет означать, что он не будет работать так сильно, как должен.

Мой совет:

Посмотрите на насмешливый внешних зависимостей в модульных тестов с чем-то вроде EasyMock (http://www.easymock.org/).

Создайте отдельный набор интеграционных тестов с чем-то вроде Fitnesse (http://fitnesse.org/) или доморощенным решением, которое работает против тестовой среды и постоянно растет.

+0

hi nick, мои юнит-тесты не делают этого типа вещей и являются суперклик. я говорил о функциональных тестах :-) – 2008-12-10 11:58:52

0

Один из вариантов - использовать что-то вроде Apache Ant, чтобы запустить набор модулей. Вы можете поставить цель вызова до и после вашей цели JUnit, чтобы начать и остановить WebService:

<target name="start.webservice"><!-- starts the webservice... --></target> 
<target name="stop.webservice"><!-- stops the webservice... --></target> 
<target name="unit.test"><!-- just runs the tests... --></target> 

<target name="run.test.suite" 
     depends="start.webservice, unit.test, stop.webservice"/> 

Затем запустить пакет с помощью муравей (или ваш инструмент интеграции выбора). Большинство IDE поддерживают Ant, и это значительно облегчает перенос ваших тестов в непрерывную среду интеграции (многие из которых используют цели Ant для определения своих собственных тестов).

21

Ответ теперь заключается в создании @ClassRule в вашем номере. Правило будет вызываться до или после (в зависимости от того, как вы его реализуете) запускается каждый тестовый класс. Существует несколько различных базовых классов, которые вы можете расширить/реализовать. Что приятно в правилах классов, так это то, что если вы не реализуете их как анонимные классы, вы можете повторно использовать код!

Вот статья о них: http://java.dzone.com/articles/junit-49-class-and-suite-level-rules

Вот некоторые примеры кода, чтобы проиллюстрировать их использование. Да, это тривиально, но это должно хорошо иллюстрировать жизненный цикл, чтобы вы начали.

Первое определение свита:

import org.junit.*; 
import org.junit.rules.ExternalResource; 
import org.junit.runners.Suite; 
import org.junit.runner.RunWith; 


@RunWith(Suite.class) 
@Suite.SuiteClasses({ 
    RuleTest.class, 
}) 
public class RuleSuite{ 

    private static int bCount = 0; 
    private static int aCount = 0; 

    @ClassRule 
    public static ExternalResource testRule = new ExternalResource(){ 
      @Override 
      protected void before() throws Throwable{ 
       System.err.println("before test class: " + ++bCount); 
       sss = "asdf"; 
      }; 

      @Override 
      protected void after(){ 
       System.err.println("after test class: " + ++aCount); 
      }; 
     }; 


    public static String sss; 
} 

А теперь определение тестового класса:

import static org.junit.Assert.*; 

import org.junit.ClassRule; 
import org.junit.Rule; 
import org.junit.Test; 
import org.junit.rules.ExternalResource; 

public class RuleTest { 

    @Test 
    public void asdf1(){ 
     assertNotNull("A value should've been set by a rule.", RuleSuite.sss); 
    } 

    @Test 
    public void asdf2(){ 
     assertEquals("This value should be set by the rule.", "asdf", RuleSuite.sss); 
    } 
} 
+0

«Правило будет вызываться до или после (в зависимости от того, как вы его реализуете) каждый тестовый класс запускается» - я не могу это подтвердить. Метод compare() моего класса ClassRule вызван только один раз, хотя я добавил два набора тестов в набор. – 2015-11-25 11:33:40

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