Подтвердить что ты не робот

Какова цель метода setUp XCTestCase?

За комментарий в шаблоне по умолчанию для XCTestCase относительно setUp:

Put setup code here; it will be run once, before the first test case.

Однако в XCTestCase.h комментарий выше setUp указывает иначе:

Setup method called before the invocation of each test method in the class.

Чтобы подтвердить фактическое поведение, я помещаю NSLog внутри setUp, чтобы подсчитать, сколько раз он был вызван:

static int count = 0;

- (void)setUp
{
    [super setUp];
    count++;

    NSLog(@"Call Count = %d", count);
}

Это привело к тому, что метод setUp вызывается перед каждым тестовым методом (подтверждение комментария на XCTestCase.h).

Я хотел использовать метод setUp для создания объектов test/mock один раз (например, для установки тестового стека Core Data). Создание их снова и снова было бы интенсивным и потенциально очень медленным.

Итак,

1) Что на самом деле предназначено для setUp? Разумеется, разработчики не создают в нем объекты снова и снова?

2) Как создать эти объекты только один раз в XCTestCase?

4b9b3361

Ответ 1

Здесь есть несколько моментов для обсуждения: поведение методов setUp и общие лучшие методы тестирования.

На самом деле существуют два setUp:

+ (void)setUp;
- (void)setUp;

Метод класса (+ (void)setUp) запускается только один раз во время всего тестового прогона.

Метод экземпляра (- (void)setUp) - тот, который указан в шаблоне по умолчанию; он запускается перед каждым тестом. Надеюсь, в гипотетической будущей версии Xcode этот комментарий будет изменен на // Put setup code here. This method is called before the invocation of each test method in the class. WINK WINK

Таким образом, благодаря этим двум методам возможны оба описанных вами поведения.

Относительно вашего комментария:

"Несомненно, разработчики не создают в нем объекты снова и снова?"

Мой ответ будет "Да, они обычно есть". Популярным акронимом для "хороших" модульных тестов является FIRST:

  • Fast
  • Изолированный
  • Повторяющиеся
  • Self-контролирующая
  • Своевременное

Изолированный является ключевым в этом обсуждении: ваши тесты не должны полагаться на предыдущее состояние, оставленное другими тестами. В идеале вы должны снести и восстановить свой стек Core Data в памяти для каждого теста, чтобы вы знали, что начинаете с чистого листа. Хорошим примером является этот пост от Грэма Ли. Вы хотите использовать стек в памяти, потому что: a) вы можете легко выбросить его, и b) он должен быть очень быстрым, потому что он просто в памяти и не попадает на ваш диск.

Если вы обнаружите, что ваши тесты медленно запускаются в результате этого (не оптимизируйте преждевременно), то я думаю, что следующим следующим шагом будет создание стека в вашем методе + (void)setUp, но создайте новый контекст каждый раз в вашем методе - (void)setUp.

Ответ 2

Я пришел сюда с почти той же проблемой: как выполнить setUp только один раз и в Swift. Вот решение:

override class func setUp() {
    super.setUp()    
    // ...
}

override class func tearDown() {    
    // ...
    super.tearDown()
}

Сейчас я все еще ищу решение для асинхронного setUp!