Статьи

Прогресс в тестировании с Xcode 7 и Swift 2

В первые дни существования iOS инструменты для облегчения тестирования не были основной задачей команды разработчиков инструментов Apple. С течением времени это постепенно изменилось с появлением платформы XCTest и, в последнее время, поддержки асинхронного тестирования и тестирования производительности.

С Xcode 7 и Swift 2 Apple делает еще один большой шаг для улучшения тестирования в Xcode. В этом уроке я расскажу вам о трех важных дополнениях, которые сделают тестирование более простым и приятным.

В Swift 1 разработчики должны перепрыгнуть через несколько обручей, чтобы проверить свой код. Например, объект модульного тестирования имеет доступ только к открытым объектам другого модуля. Это не удивительно, если вы знакомы с контролем доступа Swift. Однако проверка внутренних процедур становится болью.

Команда Apple Swift знала об этой проблеме, и в результате Swift 2 вводит атрибут @testable чтобы сделать тестирование менее болезненным. С атрибутом @testable цель модульного теста имеет доступ ко всем внутренним объектам другого модуля. В следующем фрагменте кода показано, как использовать атрибут @testable .

1
@testable import AnotherModule

Давайте создадим простой проект, чтобы увидеть, как он работает. Откройте Xcode 7, создайте проект на основе шаблона приложения Single View и отметьте флажок « Включить модульные тесты» .

Настройка проекта с включенными юнит-тестами

Чтобы показать, как @testable атрибут @testable , я реализовал структуру с именем User . Он имеет два сохраненных свойства: firstName и lastName , а также личное вычисляемое свойство fullName .

01
02
03
04
05
06
07
08
09
10
11
12
import Foundation
 
struct User {
    var lastName: String = «»
    var firstName: String = «»
     
    var fullName: String {
        get {
            return firstName + » » + lastName
        }
    }
}

Поскольку мы не указали уровень доступа для вычисляемого свойства fullName , он является внутренним . Если мы хотим выполнить модульный тест fullName , мы можем пометить его как открытый . Это не здорово, и это побеждает цель контроля доступа Swift.

К счастью, Swift 2 решает эту проблему с @testable атрибута @testable . Следующий фрагмент кода показывает, как @testable атрибут @testable . @testable оператор import к @testable , мы можем получить доступ к свойству fullName структуры User в методе testFullName .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
import XCTest
@testable import Testing
 
class TestingTests: XCTestCase {
     
    override func setUp() {
        super.setUp()
    }
     
    override func tearDown() {
        super.tearDown()
    }
     
    func testFullName() {
        var me = User()
        me.firstName = «Bart»
        me.lastName = «Jacobs»
         
        XCTAssertEqual(me.fullName, «Bart Jacobs», «The full name should be equal to \»Bart Jacobs\».»)
    }
     
}

Обратите внимание, что в документации четко указано, что атрибут @testable может выполнять свою работу, только если продукт скомпилирован с включенным тестированием. Другими словами, вы не можете и не должны использовать атрибут @testable для других целей, кроме тестирования.

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

Вместо того, чтобы показывать вам скриншоты, я бы хотел показать вам шаги, необходимые для включения покрытия кода в проекте Xcode. Давайте возьмем в качестве примера проект, который мы создали несколько минут назад.

Чтобы включить покрытие кода, нам нужно только отредактировать активную схему. Нажмите на схему в левом верхнем углу и выберите Редактировать схему ….

Отредактируйте текущую схему, чтобы включить покрытие кода

Чтобы включить покрытие кода, выберите « Тестировать» слева и установите флажок « Сбор покрытия кода» . Вот и все. Если вы пытались включить покрытие кода в более ранних версиях Xcode, то я уверен, что вы будете рады видеть, как просто включить покрытие кода в Xcode 7.

Скажите Xcode, чтобы собрать покрытие Дадта

Запустите модульные тесты, нажав Command-U или выбрав Test из меню Product в Xcode. Когда тестирование закончится, откройте Навигатор отчетов справа и выберите вкладку Покрытие вверху. Это показывает, насколько хорошо ваши модульные тесты охватывают код, который вы написали.

Покрытие кода в Xcode 7

Похоже, мы проделали довольно хорошую работу по тестированию User структуры. Это становится лучше, хотя. Вы видите крошечную стрелку, следующую за именем метода? Если вы щелкнете по нему, Xcode перенесет вас к исходному коду, который тестировал модульный тест. Поскольку XCode собрал данные покрытия, он также может показать эти данные покрытия в редакторе исходного кода.

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

Покрытие кода в редакторе исходного кода

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

Одной из наиболее ожидаемых особенностей Xcode 7 является интеграция тестирования пользовательского интерфейса. В прошлом я работал с KIF и UI Automation , но никогда не был доволен ни одним из этих решений. Тестирование пользовательского интерфейса Xcode выглядит как решение, которого многие из нас ждали.

Тестирование пользовательского интерфейса в Xcode 7 расширяется на мощной платформе Apple XCTest за счет добавления трех классов: XCUIApplication , XCUIElement и XCUIElementQuery . Чтобы упростить создание тестов пользовательского интерфейса, Xcode 7 предоставляет возможность записи тестов. Это очень мощная функция, с которой некоторые из вас, возможно, уже знакомы, если вы когда-либо работали с Apple UI Automation .

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

Создание тестов пользовательского интерфейса очень просто

Обратите внимание, что тестирование пользовательского интерфейса доступно только на iOS 9 и OS X 10.11. Apple подчеркивает, что юнит-тесты и тесты взаимодействия с пользователем дополняют друг друга. Другими словами, это не вопрос выбора того или другого.

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

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

Если вы хотите больше узнать о тестировании с использованием Swift и платформы XCTest, то я рекомендую вам ознакомиться с курсом Дерека Дженсена о модульном тестировании с использованием Swift и XCTest .

Apple приложила много усилий для улучшения тестирования и отладки с выпуском Xcode 7. Хотя интегрированное покрытие кода является фантастическим, добавление тестирования пользовательского интерфейса будет иметь еще большее влияние.

Я надеюсь, что этот краткий обзор подстегнул ваш аппетит к тестированию в Xcode 7. Мы расскажем об этих новых функциях более подробно в будущих уроках.