JUnit 4: Настройте вещи в наборе тестов перед запуском тестов (например, метод теста @BeforeClass, только для набора тестов) - PullRequest
23 голосов
/ 08 декабря 2008

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

Естественно, веб-сервис должен работать, иначе тесты не пройдут. : -)

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

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

Ответы [ 4 ]

23 голосов
/ 03 октября 2011

Ответ теперь заключается в создании @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 );
    }
}
1 голос
/ 08 декабря 2008

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

Ваш вопрос в значительной степени дублирует Хук выполнения до и после Suite в jUnit 4.x , поэтому я взгляну на предложения там.

0 голосов
/ 09 декабря 2008

Один из вариантов - использовать что-то вроде Apache Ant для запуска вашего модульного теста. Затем вы можете выполнить целевой вызов до и после своей целевой Junit, чтобы запустить и остановить ваш веб-сервис:

<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"/>

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

0 голосов
/ 09 декабря 2008

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

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

Мой совет:

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

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

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