Конечно, есть много таких подходов, как синхронный запрос, обещание, но из моего опыта я думаю, что вы должны использовать подход обратного вызова. Естественно, что асинхронное поведение Javascript. Итак, ваш фрагмент кода можно переписать немного иначе:
function foo() {
var result;
$.ajax({
url: '...',
success: function(response) {
myCallback(response);
}
});
return result;
}
function myCallback(response) {
// Does something.
}
Я думаю, что это очень важная функция для JUnit, если автор JUnit не хочет, чтобы функция заказа, почему?
blockquote>Я не уверен, что с JUnit существует чистый способ, насколько я знаю. JUnit предполагает, что все тесты могут выполняться в произвольном порядке. Из часто задаваемых вопросов:
Как использовать тестовое устройство?
(...) Порядок вызова тестовых методов не является гарантировано, поэтому testOneItemCollection () может быть выполнено до testEmptyCollection (). (...)
blockquote>Почему это так? Я считаю, что выполнение тестов зависит от порядка - это практика, которую авторы не хотят продвигать. Тесты должны быть независимыми, они не должны сочетаться и нарушать это, что усложнит работу, нарушит способность запускать тесты индивидуально (очевидно) и т. Д.
. Говоря, если вы действительно хотите чтобы пойти в этом направлении, рассмотрите возможность использования TestNG, поскольку он поддерживает запуск методов тестирования в любом произвольном порядке изначально (и такие вещи, как указание того, что методы зависят от групп методов). Седрик Боуст объясняет, как это сделать в порядке выполнения тестов в testng .
Изменение (пока еще неизданное) https://github.com/junit-team/junit/pull/386 вводит @SortMethodsWith
. https://github.com/junit-team/junit/pull/293 , по крайней мере, сделал предсказуемый прогноз без этого (в Java 7 он может быть довольно случайным).
вы можете использовать один из этих фрагментов кода:
@FixMethodOrder(MethodSorters.JVM)OR `@FixMethodOrder(MethodSorters.DEFAULT)` OR `@FixMethodOrder(MethodSorters.NAME_ASCENDING)` before your test class like this:
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class BookTest { ...}
То, что вы хотите, вполне разумно, когда тестовые примеры запускаются как набор.
К сожалению, нет времени, чтобы дать полное решение прямо сейчас, но посмотрите на класс:
org.junit.runners.Suite
Это позволяет вам вызывать тестовые примеры (из любого тестового класса) в определенном порядке.
Они могут использоваться для создания функциональных, интеграционных или системных тестов.
(как рекомендовано), независимо от того, запускаете ли вы их или нет, а затем повторно используйте тесты как часть более крупного изображения.
Мы повторно используем / наследуют один и тот же код для модульных, интеграционных и системных тестов, иногда управляются данными, иногда управляются, а иногда запускаются как набор.
Если вы избавитесь от существующего экземпляра Junit и загрузите JUnit 4.11 или больше в пути сборки, следующий код выполнит методы тестирования в порядке их имен, отсортированных по возрастанию порядок:
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SampleTest {
@Test
public void testAcreate() {
System.out.println("first");
}
@Test
public void testBupdate() {
System.out.println("second");
}
@Test
public void testCdelete() {
System.out.println("third");
}
}
Миграция в TestNG кажется лучшим способом, но я не вижу здесь ясного решения для jUnit. Вот наиболее читаемое решение / форматирование, которое я нашел для jUnit:
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SampleTest {
@Test
void stage1_prepareAndTest(){};
@Test
void stage2_checkSomething(){};
@Test
void stage2_checkSomethingElse(){};
@Test
void stage3_thisDependsOnStage2(){};
@Test
void callTimeDoesntMatter(){}
}
Это гарантирует, что методы stage2 вызывается после stage1 и до stage3.
См. мое решение здесь: «Junit and java 7.»
В этой статье описывается, как запускать junit-тесты по порядку - «так же, как в вашем исходном коде». Тесты будут выполняться, чтобы ваши тестовые методы отображались в файле класса.
http://intellijava.blogspot.com/2012/05/junit-and-java-7.html
Но, как сказал Паскаль Тивент, это не очень хорошая практика.
Пожалуйста, ознакомьтесь с этим: https://github.com/TransparentMarket/junit . Он запускает тест в том порядке, в котором они указаны (определяется в файле скомпилированного класса). Кроме того, в нем есть пакет AllTests для запуска тестов, определенных в первом пакете. Используя реализацию AllTests, вы можете расширить решение и фильтровать свойства (мы использовали аннотации @Fast, но они еще не были опубликованы).
Не уверен, что я согласен, если я хочу проверить «Загрузка файлов», а затем проверить «Данные, вставленные путем загрузки файлов», почему я не хочу, чтобы они были независимыми друг от друга? Совершенно разумно, я думаю, чтобы иметь возможность запускать их отдельно, а не как в случае с Goliath.
В итоге я подумал, что мои тесты не выполняются по порядку, но правда в том, что беспорядок был в моих асинхронных заданиях. При работе с параллелизмом вам также необходимо выполнять проверки параллельности между вашими тестами. В моем случае задания и тесты используют семафор, поэтому следующие тесты зависают до тех пор, пока запущенное задание не освободит блокировку.
Я знаю, что это не полностью связано с этим вопросом, но, возможно, может помочь настроить правильную проблему
Я прочитал несколько ответов и согласен с тем, что это не самая лучшая практика, но самый простой способ заказать ваши тесты - и то, как JUnit запускает тесты по умолчанию, - это по алфавиту по возрастанию.
Так что просто укажите свои тесты в алфавитном порядке, который вы хотите. Также обратите внимание, что имя теста должно начинаться с теста слова. Просто следите за числами
test12 будет работать до test2
, поэтому:
testA_MyFirstTest testC_ThirdTest testB_ATestThatRunsSecond
Его главная проблема, с которой я столкнулась, когда я работал над Junit и мной, придумал следующее решение, которое отлично подходит для меня:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
public class OrderedRunner extends BlockJUnit4ClassRunner {
public OrderedRunner(Class<?> clazz) throws InitializationError {
super(clazz);
}
@Override
protected List<FrameworkMethod> computeTestMethods() {
List<FrameworkMethod> list = super.computeTestMethods();
List<FrameworkMethod> copy = new ArrayList<FrameworkMethod>(list);
Collections.sort(copy, new Comparator<FrameworkMethod>() {
@Override
public int compare(FrameworkMethod f1, FrameworkMethod f2) {
Order o1 = f1.getAnnotation(Order.class);
Order o2 = f2.getAnnotation(Order.class);
if (o1 == null || o2 == null) {
return -1;
}
return o1.order() - o2.order();
}
});
return copy;
}
}
также создает интерфейс, как показано ниже:
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD})
public @interface Order {
public int order();
}
Теперь предположим, что у вас есть класс A, где вы написали несколько тестовых примеров, например, ниже:
(@runWith=OrderRunner.class)
Class A{
@Test
@Order(order = 1)
void method(){
//do something
}
}
Таким образом, запуск начнется с метода с именем «method ()». Спасибо!
Вот расширение JUnit, которое может вызвать желаемое поведение: https://github.com/aafuks/aaf-junit
Я знаю, что это противоречит авторы философии JUnit, но при использовании JUnit в средах, которые не являются строгим модульным тестированием (как это практикуется на Java), это может быть очень полезно.
Посмотрите отчет JUnit. JUnit уже организован пакетом. Каждый пакет имеет (или может иметь) классы TestSuite, каждый из которых, в свою очередь, запускает несколько TestCases. Каждая TestCase может иметь несколько тестовых методов формы public void test*()
, каждая из которых фактически станет экземпляром класса TestCase, к которому они принадлежат. Каждый тестовый метод (экземпляр TestCase) имеет имя и критерии прохождения / отказа.
Для моего управления требуется концепция отдельных элементов TestStep, каждая из которых сообщает свои собственные критерии прохождения / отказа. Неудача любого этапа тестирования не должна препятствовать выполнению последующих этапов тестирования.
В прошлом разработчики тестов в моем положении организовали классы TestCase в пакеты, соответствующие части (-ям) тестируемого продукта, создал класс TestCase для каждого теста и сделал каждый тестовый метод отдельным «шагом» в тесте с его собственными критериями прохождения / отказа в выводе JUnit. Каждый TestCase является автономным «тестом», но отдельные методы или «этапы» теста в TestCase должны выполняться в определенном порядке.
Методами TestCase были шаги TestCase, а разработчики тестов получил отдельный критерий прохождения / отказа за каждый шаг теста. Теперь шаги тестирования смешаны, и тесты (конечно) не работают.
Например:
Class testStateChanges extends TestCase
public void testCreateObjectPlacesTheObjectInStateA()
public void testTransitionToStateBAndValidateStateB()
public void testTransitionToStateCAndValidateStateC()
public void testTryToDeleteObjectinStateCAndValidateObjectStillExists()
public void testTransitionToStateAAndValidateStateA()
public void testDeleteObjectInStateAAndObjectDoesNotExist()
public void cleanupIfAnythingWentWrong()
Каждый метод тестирования утверждает и сообщает о своих собственных критериях прохождения / отказа. Свертывание этого в «один большой тестовый метод» для упорядочения теряет степень детализации критерия прохождения / отказа каждого «шага» в сводном отчете JUnit. ... и это расстраивает моих менеджеров. В настоящее время они требуют другой альтернативы.
Может ли кто-нибудь объяснить, как JUnit с упорядоченным методом тестирования скремблирования будет поддерживать отдельные критерии прохождения / отказа каждого последовательного тестового шага, как показано выше и требуется моим руководством?
Независимо от документации, я рассматриваю это как серьезный регресс в рамках JUnit, который усложняет жизнь многим разработчикам тестов.
Если порядок важен, вы должны сделать заказ самостоятельно.
@Test public void test1() { ... }
@Test public void test2() { test1(); ... }
В частности, вы должны перечислить некоторые или все возможные перестановки заказов для проверки, если это необходимо.
Например,
void test1();
void test2();
void test3();
@Test
public void testOrder1() { test1(); test3(); }
@Test(expected = Exception.class)
public void testOrder2() { test2(); test3(); test1(); }
@Test(expected = NullPointerException.class)
public void testOrder3() { test3(); test1(); test2(); }
Или полный тест всех перестановок:
@Test
public void testAllOrders() {
for (Object[] sample: permute(1, 2, 3)) {
for (Object index: sample) {
switch (((Integer) index).intValue()) {
case 1: test1(); break;
case 2: test2(); break;
case 3: test3(); break;
}
}
}
}
Здесь permute()
- простая функция, которая выполняет итерацию все возможные перестановки в массив массивов.
В настоящее время JUnit позволяет методам тестирования выполнять упорядочение с помощью аннотаций классов:
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@FixMethodOrder(MethodSorters.JVM)
@FixMethodOrder(MethodSorters.DEFAULT)
Чтобы задать порядок методов, вы можете их назвать:
a_testWorkUnit_WithCertainState_ShouldDoSomething b_testWorkUnit_WithCertainState_ShouldDoSomething c_testWorkUnit_WithCertainState_ShouldDoSomething
blockquote>