Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Тесты: Повторение. Виктор Суриков

CocoaHeads
December 13, 2019

Тесты: Повторение. Виктор Суриков

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

CocoaHeads

December 13, 2019
Tweet

More Decks by CocoaHeads

Other Decks in Programming

Transcript

  1. Сбербанк Онлайн • Около 110 команд • 165 активных iOS-разработчиков

    • Более 130 модулей • Более 2 000 000 строк кода • 50-100 одновременно открытых pull-request 2
  2. Тестирование • Unit-тесты • Автоматические UI-тесты • Снапшот-тесты • Регрессионное

    тестирование 3 • Бета-тестирование • Частичная плавная раскатка функциональности
  3. Unit-тесты • Бизнес-логика • Баг == Тест • PR должен

    пройти все тесты • Но случается… 4
  4. Математика Начисление процентов осуществляется по следующей формуле: N– количество интервалов

    Расчетного периода j– индекс суммирования Ij- установленная по Вкладу/Счету Процентная ставка (в процентах годовых), действующая в j-ом интервале Расчетного периода Cj– остаток вклада в j-ом интервале Расчетного периода Tj– количество дней в периоде Kj– календарное количество дней в году (365/366) 6
  5. Поиск проблемы • Анализ кода Используется «календарь» • Что может

    аффектить даты? Временная зона • Проверка 8
  6. class CalculationTests: XCTestCase { private let defaultTimeZone = TimeZone.current override

    func setUp() { super.setUp() if let timezone = TimeZone(abbreviation: "UTC+7") { NSTimeZone.default = timezone } } override func tearDown() { super.tearDown() NSTimeZone.default = defaultTimeZone } func testCalculation() { // ... } } 9 if let timezone = TimeZone(abbreviation: "UTC+7") { NSTimeZone.default = timezone } NSTimeZone.default = defaultTimeZone
  7. Test Plan • Что запускать • В каком порядке запускать

    • Параметры: язык, регион, локация • Переменные окружения и аргументы запуска 11
  8. CI? • Jenkins • Каждый PR проходит все Unit-тесты •

    165 разработчиков • 50-100 PR одномоментно на ревью 13
  9. class CalculationTests: XCTestCase { func testCalculation() { let defaultTimeZone =

    TimeZone.current let timeZones = ["MSK", "UTC+7", "UTC+10"].compactMap { TimeZone(abbreviation: $0) } for timezone in timeZones { NSTimeZone.default = timezone myOldTestCalculation() } NSTimeZone.default = defaultTimeZone } func myOldTestCalculation() { // ... } } 14 for timezone in timeZones { NSTimeZone.default = timezone myOldTestCalculation() }
  10. class CalculationTests: XCTestCase { func testCalculation() { let defaultTimeZone =

    TimeZone.current let timeZones = ["MSK", "UTC+7", "UTC+10"].compactMap { TimeZone(abbreviation: $0) } for timezone in timeZones { NSTimeZone.default = timezone myOldTestCalculation1() // ... myOldTestCalculation8() } NSTimeZone.default = defaultTimeZone } func myOldTestCalculation1() { // ... } func myOldTestCalculation8() { // ... } } 15 myOldTestCalculation1() // ... myOldTestCalculation8()
  11. class CalculationTests: XCTestCase { override class var defaultTestSuite: XCTestSuite {

    let testSuite = XCTestSuite(forTestCaseClass: self) let testCases = testInvocations.map { CalculationTests(invocation: $0) } testCases.forEach { testSuite.addTest($0) } return testSuite } func testCalculation1() { // ... } } 19 let testSuite = XCTestSuite(forTestCaseClass: self) let testCases = testInvocations.map { CalculationTests(invocation: $0) } testCases.forEach { testSuite.addTest($0) } return testSuite
  12. class CalculationTests: XCTestCase { static let timeZones = ["MSK", "UTC+7",

    "UTC+10"].compactMap { TimeZone(abbreviation: $0) } override class var defaultTestSuite: XCTestSuite { let testSuite = XCTestSuite(forTestCaseClass: self) timeZones.forEach { timeZone in testInvocations.forEach { testInvocation in let testCase = CalculationTests(invocation: testInvocation) testCase.timeZone = timeZone testSuite.addTest(testCase) } } return testSuite } private let defaultTimeZone = TimeZone.current private var timeZone: TimeZone! override func setUp() { super.setUp() NSTimeZone.default = timeZone } override func tearDown() { super.tearDown() NSTimeZone.default = defaultTimeZone } func testCalculation1() { // ... } } 20 let testSuite = XCTestSuite(forTestCaseClass: self) timeZones.forEach { timeZone in testInvocations.forEach { testInvocation in let testCase = CalculationTests(invocation: testInvocation) testCase.timeZone = timeZone testSuite.addTest(testCase) } } return testSuite
  13. Актуально? • Можно задавать не только time zone • Структура

    с параметрами • Генерация случайных параметров • Чтение больших объемов параметров из файлов 23
  14. Выводы • Тесты — тоже production-код • Документацию читать полезно

    • Не всегда нужны фреймворки 24 Виктор Суриков @Virasio