Тест отус – Пентест: сетевая безопасность, повышение привилегий, web-пентест Team Lead: эффективное управление командами разработки

Содержание

Автоматизированное тестирование с Pytest / OTUS. Онлайн-образование corporate blog / Habr

Перевод статьи подготовлен специально для студентов курса «Python QA Engineer».




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

У автоматизированного тестирования есть множество плюсов, вот три основных:
Переиспользование: Нет необходимости писать каждый раз новые скрипты, даже при выпуске новой версии операционной системы, если только в этом не появится острая необходимость.
Надежность: Люди склонны совершать ошибки, а машины совершают их с меньшей вероятностью. А еще они работают быстрее при выполнении повторяющихся шагов/тестов, которые необходимо выполнять постоянно.
Работа 24/7: Вы можете запустить тестирование в любое время суток даже удаленно. Если запустить тестирование ночью, то оно будет выполняться даже пока вы спите.
Развитый полнофункциональный инструмент тестирования pytest на Python

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

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

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

Несколько ключевых особенностей pytest:

  • Автоматическое обнаружение тестовых модулей и функций;
  • Эффективный CLI для улучшения контроля над тем, что вы хотите запустить или пропустить;
  • Большая сторонняя экосистема плагинов;
  • Фикстуры – разные типы, разные области применения;
  • Работа с традиционной структурой модульного тестирования.

Автоматическое и конфигурируемое обнаружение тестов

По умолчанию pytest ожидает найти тесты в тех модулях Python, имена которых начинаются на test_ или кончаются на _test.py. Также по умолчанию он ожидает, что имена тестовых функций будут начинаться с префикса test_. Однако этот протокол обнаружения тестов можно изменить, добавив собственную конфигурацию в один из файлов конфигурации pytest.
# content of pytest.ini
# Example 1: have pytest look for "check" instead of "test"
# can also be defined in tox.ini or setup.cfg file, although the section
# name in setup.cfg files should be "tool:pytest"
[pytest]
python_files = check_*.py
python_classes = Check
python_functions = *_check

Давайте посмотрим на очень простую тестовую функцию:
class CheckClass(object):
    def one_check(self):
        x = "this"
        assert 'h' in x

    def two_check(self):
        x = "hello"
        assert hasattr(x, 'check')

Вы что-нибудь заметили? Нет никаких assertEqual или assertDictEqual, просто доступный и понятный assert. Нет необходимости импортировать эти функции, чтобы просто сравнить два объекта. Assert – это то, что уже есть в Python и нет необходимости изобретать колесо.
Шаблонный код? Не переживайте, фикстуры спешат на помощь!

Посмотрите на тестовые функции, которые тестируют базовые операции в программе Wallet:
// test_wallet.py from wallet import Wallet def test_default_initial_amount(): wallet = Wallet() assert wallet.balance == 0 wallet.close() def test_setting_initial_amount(): wallet = Wallet(initial_amount=100) assert wallet.balance == 100 wallet.close() def test_wallet_add_cash(): wallet = Wallet(initial_amount=10) wallet.add_cash(amount=90) assert wallet.balance == 100 wallet.close() def test_wallet_spend_cash(): wallet = Wallet(initial_amount=20) wallet.spend_cash(amount=10) assert wallet.balance == 10 wallet.close()

Кхм, интересно! Заметили? Здесь очень много шаблонного кода. Еще одна вещь, которую стоит заметить, заключается в том, что этот тест делает кое-что еще помимо тестирования функциональной части, например, создает Wallet и закрывает его с помощью wallet.close()
.

Теперь давайте посмотрим на то, как можно избавиться от шаблонного кода с помощью фикстур pytest.

import pytest
from _pytest.fixtures import SubRequest
from wallet import Wallet
#==================== fixtures
@pytest.fixture
def wallet(request: SubRequest):
   param = getattr(request, ‘param’, None)
   if param:
     prepared_wallet = Wallet(initial_amount=param[0])
   else:
     prepared_wallet = Wallet()
   yield prepared_wallet
   prepared_wallet.close()
#==================== tests
def test_default_initial_amount(wallet):
   assert wallet.balance == 0
@pytest.mark.parametrize(‘wallet’, [(100,)], indirect=True)
def test_setting_initial_amount(wallet):
   assert wallet.balance == 100
@pytest.mark.parametrize(‘wallet’, [(10,)], indirect=True)
def test_wallet_add_cash(wallet):
   wallet.add_cash(amount=90)
   assert wallet.balance == 100
@pytest.mark.parametrize(‘wallet’, [(20,)], indirect=True)
def test_wallet_spend_cash(wallet):
   wallet.spend_cash(amount=10)
   assert wallet.balance == 10

Красиво, не правда ли? Тестовые функции теперь компактные и делают ровно то, что должны делать. Настройка, инстанциирование и закрытие Wallet осуществляется с помощью фикстуры wallet. Фикстуры не только помогают писать переиспользуемый код, но и добавляют концепцию разделения данных. Если вы посмотрите внимательнее, то amount в wallet – это часть тестовых данных, предоставленная извне тестовой логикой, а не жестко закрепленная внутри функции.
@pytest.mark.parametrize(‘wallet’, [(10,)], indirect=True)

В более контролируемой среде у вас может быть файл с тестовыми данными, например test-data.ini в вашем репозитории или оболочке, которая сможет его прочитать, при этом ваша тестовая функция может вызывать различные оболочки для чтения тестовых данных.

Рекомендуется, однако, поместить все ваши фикстуры в специальный файл conftest.py. Это специальный файл в pytest, который позволяет тесту обнаруживать глобальные фикстуры.

Но у меня есть тестовые случаи, которые я хочу выполнять на различных наборах данных!

Не беспокойтесь, у pytest есть классная функция для параметризации вашей фикстуры. Давайте посмотрим на примере.

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

Вы могли подумать о написании отдельного тест-кейса для каждого из этих параметров, но с pytest все намного проще!

@pytest.mark.parametrize(“setting_name, setting_value”, [(‘qdb_mem_usage’, ‘low’),
(‘report_crashes’, ‘yes’),
(‘stop_download_on_hang’, ‘no’),
(‘stop_download_on_disconnect’, ‘no’),
(‘reduce_connections_on_congestion’, ‘no’),
(‘global.max_web_users’, ‘1024’),
(‘global.max_downloads’, ‘5’),
(‘use_kernel_congestion_detection’, ‘no’),
(‘log_type’, ‘normal’),
(‘no_signature_check’, ‘no’),
(‘disable_xmlrpc’, ‘no’),
(‘disable_ntp’, ‘yes’),
(‘ssl_mode’, ‘tls_1_2’),])def test_settings_defaults(self, setting_name, setting_value):
   assert product_shell.run_command(setting_name) == \
     self.”The current value for \’{0}\’ is     \’{1}\’.”.format(setting_name, setting_value), \
 ‘The {} default should be {}’.format(preference_name, preference_value)

Круто, не правда ли? Вы только что написали 13 тест-кейсов (каждый устанавливает разное значение setting_value), а в будущем, если вы добавите новый параметр в свой продукт, то все, что вам нужно будет сделать – это добавить еще один кортеж.
Как pytest интегрируется с тестированием пользовательского интерфейса с Selenium и тестами для API?

Что ж, у вашего продукта может быть несколько интерфейсов. CLI – как мы говорили выше. Аналогично GUI и API. Перед развертыванием вашего программного продукта важно протестировать их все. В корпоративном программном обеспечении, где несколько компонентов взаимосвязаны и зависят друг от друга, изменение в одной части может повлиять на все остальные.

Помните о том, что pytest – это просто фреймворк для облегчения тестирования, а не конкретный тип тестирования. То есть вы можете создавать тесты для GUI с помощью Selenium или, например, тесты для API с библиотекой requests из Python и запускать их с pytest.

Например, на высоком уровне это может быть проверка структуры репозитория.

Как вы видите на изображении выше, он дает хорошую возможность разделять компоненты:

apiobjects: хорошее место для создания оболочек для вызова конечных точек API. У вас может быть BaseAPIObject и производный класс, отвечающий вашим требованиям.

helpers: Можете добавить сюда свои вспомогательные методы.

lib: файлы библиотек, которые могут использоваться различными компонентами, например, вашими фикстурами в conftest, pageobjects и т.д.

pageobjects: шаблон архитектуры PageObjects можно использовать для создания классов различных страниц GUI. Мы используем Webium, который является библиотекой реализаций шаблонов Page Object для Python.

suites: вы можете написать свои наборы pylint-проверок для кода, они помогут получить большую уверенность в качестве вашего кода.

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

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

У меня много тест-кейсов, и я хочу, чтобы они выполнялись параллельно

У вас может быть множество тест-кейсов в вашем наборе, и случается, что нужно запустить их параллельно и сократить общее время выполнения тестирования.

Pytest предлагает удивительный плагин для параллельного запуска тестов, который называется pytest-xdist, который добавляет к базовому pytest несколько уникальных режимов выполнения. Установите этот плагин с помощью pip.

pip install pytest-xdist

Давайте посмотрим, как он работает на примере.

У меня есть репозиторий автоматизированного тестирования CloudApp для моих GUI тестов на Selenium. Помимо этого, он постоянно растет и пополняется новыми тестами и теперь в нем лежит сотня тестов. То, что я хочу сделать – это запустить их параллельно и сократить общее время выполнения тестирования.

В терминале просто введите pytest в корневой папке проекта/папке с тестами. Это позволит выполнить все тесты.

pytest -s -v -n=2

pytest-xdist запустит все тесты параллельно!

Таким способом вы также сможете параллельно запустить несколько браузеров.

Отчеты

Pytest поставляется со встроенной поддержкой создания файлов с результатами тестирования, которые можно открыть с помощью Jenkins, Bamboo или других серверов непрерывной интеграции. Используйте следующее:
pytest test/file/path — junitxml=path

Это поможет сгенерировать отличный XML-файл, который можно открыть множеством парсеров.

Заключение


Популярность Pytest растет с каждым годом. Кроме того, у него есть мощная поддержка сообщества, что позволяет получить доступ к множеству расширений, например
pytest-django
, который поможет писать тесты для веб-приложений на Django. Помните, что pytest поддерживает выполнение тест-кейсов unittest, поэтому если вы используете unittest, pytest стоит рассмотреть более детально.
Источники


На этом все. До встречи на курсе!

Шесть способов, которыми тестировщики могут принести пользу (помимо функционального тестирования)

Салют! Уже на следующей неделе стартуют занятия в новом потоке курса «QA-специалист», в связи с этим делимся с вами полезным материалом, переведенным специально для студентов курса. Поехали.

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

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

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

1. Изучите все сообщения


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

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

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

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

2. Делайте ревью UX


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

В процессе стабилизации продукта сосредоточьтесь на том, чтобы избавиться от любых несоответствий UX. Выполните UX-ревью всего приложения. Начните с иконок, текста, действий, функций и основных потоков. Используйте персонажей и мозговой штурм для полного ревью UX. Подумайте также о точках соприкосновения (touchpoints) для пользователей. Как вы справляетесь с ними? Есть ли в вашем приложении то, что вводит в заблуждение? По адресу https://cantunsee.space есть упражнения, которые помогут вам проверить ваши UI-навыки.

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

3. Проведите анализ конкурентов


Жаль, что многие тестировщики работают в изоляции и не имеют ни малейшего представления о продуктах других компаний. Изучите своих конкурентов с помощью рекламной информации, веб-семинаров, демонстраций, новостей в СМИ и блогах, а затем выпишите фичи и проанализируйте сильные и слабые стороны вашего продукта.

Узнайте у ваших продуктовых команд, можете ли вы получить доступ к предложениям других компаний, и спросите, как вы можете помочь в анализе конкурентов. Помимо анализа функциональности, обратите внимание также на такие критерии как удобство использования, производительность, безопасность и доступность. Полезно сделать сравнительную таблицу “функциональность — критерии оценки” с баллами, которые набрали продукты.

4. Изучите возможности инструментов


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

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

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

5. Подумайте о рисках, которые могут стать “ночным кошмаром”


Как описано в книге Элизабет Хендриксон ”Explore It! Reduce Risk and Increase Confidence with Exploratory Testing”, один из способов предотвратить катастрофу — подумать о возможных заголовках плохих новостей, связанных с вашим продуктом или проектом, и протестировать эти риски. Тестировщики хорошо умеют думать о возможных сценариях аварий, и этот навык может помочь команде разработчиков избежать ошибок при написании кода, заранее экономя время и усилия.

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

6. Проведите время со службой поддержки


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

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

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

На этом все. Ждем ваши комментарии и приглашаем на день открытых дверей, который пройдет уже 21 июня.

Пентест. Практика тестирования на проникновение или «этичный хакинг». Новый курс от OTUS

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




Тестирование на проникновение – это процесс легального взлома информационных систем с целью выявить уязвимости информационной системы. Пентест (то есть тестирование на проникновение) происходит по просьбе заказчика, а по окончании исполнитель дает ему рекомендации по устранению уязвимостей.

Если вы хотите уметь распознавать различные виды уязвимостей и защищать сетевые и веб-ресурсы от атак злоумышленников, то в Otus вас научат этому. Запущен набор на курс «Пентест. Практика тестирования на проникновение»

Кому подойдет этот курс?

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

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

  • Знаете основы работы TCP/IP
  • Знаете основы использования командной строки операционных систем Windows и Linux
  • Понимаете работы клиент-серверных приложений
  • Являетесь обладателем следующего «железа»: оперативная память от 8 Гб, высокоскоростное интернет-соединение, 150 ГБ свободного места на жестком диске

19 декабря в 20:00 пройдет День открытых дверей, на котором преподаватель курса «Пентест. Практика на проникновение» — Александр Колесников (вирусный аналитик в международной компании) ответит на все вопросы по курсу, более подробно расскажет о программе, онлайн-формате и итогах обучения.

А по итогам обучения вы научитесь:

  • Основным этапам проведения тестирования на проникновение
  • Использованию современных инструментов для проведения анализа защищенности информационной системы или приложения
  • Классификации уязвимостей и методам их исправления
  • Навыкам программирования для автоматизации рутинных задач

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

Чтобы иметь еще более ясное представление об этом курсе, вы можете ознакомиться с прошедшими вебинарами:

«Как начать разбираться с багами в Web»


«Все о курсе» (предыдущий запуск)


А также посетить открытый урок «AD: основные понятия. Как работает BloodHoundAD?» который состоится 17 декабря в 20:00. На этом вебинаре будут рассмотрены основные понятия: Что такое AD, основные сервисы, разграничение доступа, а также механизмы, которые используются утилитой BloodHoundAD.

До встречи на курсе!

Открытый вебинар «Метод Pairwise Testing в Black Box тестировании»

Всем доброго времени суток!

Предлагаем вашему вниманию подробное описание открытого урока, посвящённого попарному тестированию. Мероприятие прошло всего пару дней назад и было приурочено к запуску курса «QA-специалист».

Преподаватель — Нина Деваева — Senior Tester, Team Leader и ISTQB-сертифицированный тестировщик, эксперт по направлению Quality Assurance.

На открытом уроке поговорили о необходимости такого вида техники тест-дизайна, как попарное тестирование (pairwise testing). Изучили кейсы применения на практике и подробно рассмотрели инструментарий, доступный для работы.


Перед началом вебинара поставили следующие цели:
  • узнать, что из себя представляет попарное тестирование;
  • узнать, в каких случаях допустимо применение попарного тестирования;
  • научиться работать с инструментами попарного тестирования.

Несколько слов о тест-дизайне

Тест дизайн – это этап процесса тестирования ПО, на котором проектируются и создаются тестовые случаи (тест-кейсы) в соответствии с определёнными ранее критериями качества и целями тестирования. Некоторые испытывают затруднение, когда их спрашивают, зачем нужен тест-дизайн. Между тем, ответ кроется в одном из принципов тестирования, а именно: исчерпывающее тестирование недостижимо. И это действительно так за исключением каких-либо тривиальных случаев, когда входных данных очень мало. Да и по большему счёту мало какой бюджет «потянет» все возможные проверки, которыми можно покрыть наш продукт.

Тестирование методом черного ящика

Хорошо известный метод, не требующий длительных разъяснений. Если вкратце, то black box testing — это функциональное или нефункциональное тестирование, которое выполняется без знания внутренней структуры компонента или системы. Метод основан на работе исключительно с внешними интерфейсами тестируемой системы.

Техники тест-дизайна при использовании метода черного ящика, включают:

  • классы эквивалентности;
  • анализ граничных значений;
  • таблицы решений;
  • диаграммы изменения состояния;
  • попарное тестирование.

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

Так что же такое попарное тестирование?

Попарное тестирование (pairwise testing) — это разработка тестов методом черного ящика, в которой тестовые сценарии разрабатываются таким образом, чтобы выполнить все возможные отдельные комбинации каждой пары входных параметров. Собственно говоря, попарное тестирование позволяет нам сэкономить много времени.

Для pairwise testing используются алгоритмы, основанные на построении ортогональных массивов или на All-Pairs алгоритме, которые опираются на теоретические исследования в области комбинаторных алгоритмов, алгоритмов дискретной математики и, в частности, латинских квадратов. Давайте остановимся на этих алгоритмах подробнее.

Тестирование с использованием ортогонального массива

Orthogonal array testing — систематический подход к тестированию всех парных комбинаций переменных с использованием ортогональных массивов. Такой подход значительно уменьшает количество комбинаций переменных при проверке всех парных комбинаций.

Ортогональный массив по сути — это таблица, где m — число строк, n — число столбцов, которое соответствует числу входных параметров, k — количество вариантов значений элементов таблицы. Таблица обладает следующими свойствами:

  1. любые два столбца таблицы содержат все комбинации значений этих столбцов;
  2. если какая-либо пара значений двух столбцов встречается несколько раз, то все возможные парные комбинации значений этих столбцов должны встретиться столько же раз.

Например: — это ортогональный массив с четырьмя строками и тремя столбцами (по количеству переменных). Цифра 2 означает, что все переменные принимают только два значения – 1 и 2.

Например, у нашего приложения есть 3 входных параметра, причем каждый бинарный (принимает значение «1» или «2»). Таким образом, все возможные комбинации входных данных можно представить так:

Для наглядности давайте предположим, что у нас есть приложение «Фонарик», которое:

  • работает с iOS и Android;
  • имеет ночной и дневной режим подсветки;
  • позволяет светить постоянно или мигать в режиме стробоскопа.

В общем, у нас есть три параметра, которые принимают бинарные значения.

Теперь давайте посмотрим, как будет выглядеть наша выборка после перевода в ортогональный массив:

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

All-Pairs Algorithm

All-Pairs Algorithm (алгоритм всех пар) — это комбинаторная методика, которая была специально создана для парного тестирования. В её основе лежит выбор возможных комбинаций значений всех переменных, в которых содержатся все возможные значения для каждой пары переменных. Исходя из определения, число комбинаций будет меньшее, чем при использовании ортогональных массивов.

При тестировании с использованием All-Pairs алгоритма выполняют следующие шаги:

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

Также нельзя не отметить тот факт, что ортогональные массивы и All-Pairs Algorithm используются с поправкой на предварительную выборку входных данных.

Тулзы для попарного тестирования

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

  1. pairwise.teremokgames.com — сайт с понятным интерфейсом, работа с которым не требует специфических знаний.
  2. PICT — свободный инструмент, разработанный Microsoft, для Pairwise Testing’а. Скачивается по следующей ссылке.

Разумеется, есть ещё Allpairs и VPTag, но разговор о них вышел за рамки прошедшего вебинара.

Практика и ещё раз практика

Теперь давайте попробуем, как эти инструменты работают на деле. Итак, постарайтесь выполнить два простых задания:

  1. С помощью pairwiseTool произведите выборку комбинаций исходных параметров и скиньте ссылку на скриншот результата в комментарии. Берётся условный сайт, который должен открываться на Win 7, Win 8 и Win 10. Поддерживаемые браузеры — Google Chrome, Opera, Microsoft Edge, Mozilla Firefox, Яндекс.Браузер. Пользователи могут использовать или не использовать AdBlock.
  2. С помощью программы PICT сделайте выборку комбинаций исходных параметров и скиньте ссылку на скриншот результата в комментариях. Необходимо провести конфигурационное тестирование со следующими комплектующими:

  • видеокарты: GeForce GT 730, GeForce GT 1030, GeForce GTX 1080, GeForce RTX 2070;
  • процессоры: Intel Core i5, Intel Core i7, AMD Ryzen 7, Intel Core i9;
  • память: 8GB, 16GB.

На этом, пожалуй, всё. Более подробно ознакомиться с нюансами попарного тестирования можно, посмотрев вебинар полностью. И, да, не пропустите День открытых дверей курса «QA специалист»!

Тест на QA: подходите ли вы профессии?

FQA_Deep_4.6_site-5020-ceeb8e.png

Выбор профессии — важнейшее решение в нашей жизни. И чего только уже не придумало человечество, чтобы нам в этом помочь: профориентационные тесты, открытые уроки, программы. Те, кто не хочет прогадать с выбором, денно и нощно штудирует «Атлас новых профессий».

Однако несмотря на достаточные объёмы информации, некоторые области всё же остаются «серыми лошадками». Пример тому — профессия тестировщика. Она не входит в перечни образовательных программ высших учебных заведений, следовательно, подготовку или, как сейчас любят говорить, «приращение компетенций» работодателям приходится осуществлять самостоятельно.

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

Внимание, только внимание

Народная мудрость гласит: «Лучше один раз увидеть, чем сто раз услышать». Поэтому мы предлагаем вам не только заявить о вашей внимательности, но и доказать её. Прежде всего, давайте посмотрим следующий ролик и ответим на вопрос, сколько раз прыгнули через скакалку девушки в зеленых футболках.

Если интересует правильный ответ, то это 38. Результаты сошлись? Отлично. Но заметили ли вы главное? К примеру то, что цвет заднего фона изменился с синего на красный, и пробегал человек в костюме курицы? Если да, то смело ставьте себе плюс.

Нет предела совершенству

Перед вами полотно известного итальянского художника Караваджо «Ужин в Эммаусе».

1-20219-f02b4b.jpg

При чем здесь тестирование? — спросите вы. Всё просто. Картина легко позволяет определить вашу способность находить пятна даже на солнце или попросту подмечать ляпы и ошибки. И в этой картине есть своя ахиллесова пята — корзина с фруктами.

2-20219-0528bb.jpg

Она как бы парит в воздухе, тогда как в реальной жизни давно бы рухнула со стола (эксперимент проводился и данная гипотеза подтверждена — корзина всё-таки падает).

Думай иначе

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

И сегодня существует сотня способов испытать креативность своего мышления. Для проверки одного из них обратимся к кейсу из книги Тины Силиг «Сделай себя сам».

Исходные данные: команда студентов, конверт с 10 скрепками и ограниченное время.

Цель: получить максимальный объём «ценности». Причём эта ценность может измеряться любым способом.

Итог: презентация результатов перед аудиторией.

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

3-20219-1e7029.jpg

Конечно, приведённые примеры довольно условны, да и перечень под кодовым названием «Портрет идеального тестировщика» можно продолжать до бесконечности. Но при этом, если во время прочтения статьи в вашей голове хоть раз мелькнула мысль: «Чёрт возьми! Во мне это есть!», советуем задуматься.

Ведь, как сказал один мудрец с Хабра: «Тестирование — это мега-супер-пупер-аж-захватывает-дух интересно, либо просто НЕ ВАШЕ!». И чтобы это понять, стоит как минимум попробовать!

Материал подготовлен компанией-партнёром Bytex, разработавшей курс «QA-специалист».

Быстрый старт / OTUS. Онлайн-образование corporate blog / Habr

Перевод статьи подготовлен специально для студентов курса «Python QA Engineer».


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

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

Сегодня мы сосредоточимся на тестировании бэкенда. То есть разработчик реализовал некоторый проект согласно спецификациям (например, Calculator.py), а ваша задача состоит в том, чтобы убедиться, что разработанный код действительно им соответствует (например, с помощью TestCalculator.py).

Предположим, что вы написали класс Calculator для выполнения основных вычислительных функций: сложения, вычитания, умножения и деления.

Код для этого здесь (Calculator.py):

#A simple calculator
class Calculator:
  #empty constructor
  def __init__(self):
    pass
  #add method - given two numbers, return the addition
  def add(self, x1, x2):
    return x1 + x2
  #multiply method - given two numbers, return the 
  #multiplication of the two
  def multiply(self, x1, x2):
    return x1 * x2
  #subtract method - given two numbers, return the value
  #of first value minus the second
  def subtract(self, x1, x2):
    return x1 - x2
  #divide method - given two numbers, return the value
  #of first value divided by the second
  def divide(self, x1, x2):
    if x2 != 0:
      return x1/x2

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

Обычно Python поставляется уже с пакетом unittest. Если в вашей системе его нет, используйте pip для его установки.

Юнит-тест имеет следующую структуру:

setUp() и tearDown() – это стандартные методы, которые поставляются с фреймворком unittest (они определены в классе unittest.TestCase). В зависимости от вашего тестового случая вы можете переопределять или не переопределять два этих метода по умолчанию.

Пришло время посмотреть на код тест-кейса. Вот файл TestCalculator.py.

import unittest
from Calculator import Calculator
#Test cases to test Calulator methods
#You always create  a child class derived from unittest.TestCase
class TestCalculator(unittest.TestCase):
  #setUp method is overridden from the parent class TestCase
  def setUp(self):
    self.calculator = Calculator()
  #Each test method starts with the keyword test_
  def test_add(self):
    self.assertEqual(self.calculator.add(4,7), 11)
  def test_subtract(self):
    self.assertEqual(self.calculator.subtract(10,5), 5)
  def test_multiply(self):
    self.assertEqual(self.calculator.multiply(3,7), 21)
  def test_divide(self):
    self.assertEqual(self.calculator.divide(10,2), 5)
# Executing the tests in the above test case class
if __name__ == "__main__":
  unittest.main()

Хотя это и не обязательно, но как правило я называю тестовый класс с префиксом Test (в нашем случае TestCalculator). Ключевым требованием в этом классе является наличие надкласса unittest.TestCase.

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

На данный момент все, что вы будете делать, это писать методы test_xxx для тестирования каждого метода в классе Calculator. Обратите внимание, что все тестовые методы начинаются с префикса test_. Это говорит Python с помощью фреймворка unittest, что это методы тестирования.

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

Есть множество встроенных методов assert, о которых мы будем говорить позже.

Последняя строка в приведенном выше коде просто запускает тестовый случай TestCalculator. Он выполняет каждый тестовый метод, определенный внутри класса, и выдает результат.

python TestCalculator.py -v

Вы увидите вывод, сходный со следующим:

test_add (__main__.TestCalculator) ... ok
test_divide (__main__.TestCalculator) ... ok
test_multiply (__main__.TestCalculator) ... ok
test_subtract (__main__.TestCalculator) ... ok

--------------------------------------------------------------------
Ran 4 tests in 0.000s

OK

Что делать, если что-то не работает, как ожидалось? Давайте изменим ожидаемое значение test_divide с 5 на 6 (5 – правильное значение, сейчас мы посмотрим, что случится при сбое. Это не ошибка в исходном коде, а ошибка в тестовом наборе, у вас тоже могут быть ошибки в тестовых наборах, поэтому всегда проверяйте тестовые сценарии на наличие ошибок!)
import unittest
from Calculator import Calculator
#Test cases to test Calulator methods
#You always create  a child class derived from unittest.TestCase class
class TestCalculator(unittest.TestCase):
#setUp method overridden from the parent class TestCase
 def setUp(self):
  self.calculator = Calculator()
...
 def test_divide(self):
  self.assertEqual(self.calculator.divide(10,2), 6)
# Executing the tests in the above test case class
if __name__ == "__main__":
 unittest.main()

При запуске этого тест-кейса, вы получите следующий результат:
test_add (__main__.TestCalculator) ... ok
test_divide (__main__.TestCalculator) ... FAIL
test_multiply (__main__.TestCalculator) ... ok
test_subtract (__main__.TestCalculator) ... ok

====================================================================
FAIL: test_divide (__main__.TestCalculator)
--------------------------------------------------------------------
Traceback (most recent call last):
  File "TestCalculator.py", line 23, in test_divide
    self.assertEqual(self.calculator.divide(10,2), 6)
AssertionError: 5.0 != 6

--------------------------------------------------------------------
Ran 4 tests in 0.001s

FAILED (failures=1)

Здесь написано, что 3 из 4 тестов прошли успешно, а один не удался. В реальном сценарии, предполагается, что ваш тестовый случай является верным, то есть таким образом он помогает определять неправильно реализованную функцию.

Шесть вещей, которые не стоит делать, говоря о тестировании

FQA_Deep_24.6_site-5020-b209ce.png

Обсуждать тестирование ПО непросто. Это мета-деятельность – непривычный для нашего сознания процесс. Вы выполняете не обычную работу – ваше текущее задание постоянно генерирует целые комплексы новых (например, при нахождении багов, которые нужно поправить, или рисков, которые стоит исследовать). Это работа, которую невозможно завершить, но которая всё же должна быть выполнена.

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

1. Людей заботит то, сколько они написали тест-кейсов, а не то, насколько было плодотворно их тестирование

Число написанных тест-кейсов (500, 257, да хоть 39345) ничуть не поможет оценить пользу от вашего тестирования. Причина, по которой разработчики не хвастаются тем, как много файлов они создали за день заключается в том, что нелепо считать эти самые файлы или нажатия на клавиши и тому подобное. По той же причине считать тест-кейсы не менее глупо. Тестирование одного элемента можно описать как через один тест-кейс, так и через миллион. Можно написать программу, которая сгенерирует сто тест-кейсов из одного. Что из этого получится? Сотня средних тест-кейсов? Один качественный тест-кейс? Или просто сто пунктов однообразного текста, набранного разными словами? В следующий раз, когда вам подадут вот такой набор бесполезной писанины, скажите: «этот талмуд мне не говорит абсолютно ничего». И спросите: «Что именно нас интересуют в первую очередь? Какие баги мы ищем? Какие риски наиболее важны?»

2. О тестировании говорят, как об объекте, а не о процессе

Тестирование – не физический объект, хоть оно и включает в себя такие материальные вещи, как документация, данные и код. Тестирование – это процесс, это действие, это что-то, что вы делаете. Говоря о тестировании, как о предмете, а не процессе, вы упускаете из внимания наиболее важные детали тестирования: внимание, мотивацию, погружение и навыки тестировщика. Нет двух тестировщиков, которые выполнят одно и то же тестирование одним и тем же способом. Технически, вы не можете взять тест-кейс и дать его кому-то, ожидая, что не будет каких-то мелких изменений в конечном результате (так, например, хоккеист не сможет сыграть одинаково дважды), хоть эти мелкие изменения особо ничего и не значат.

3. Люди не могут описать свою тестовую стратегию по мере её развития

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

4. Говорят, что именно автоматизация производит тестирование, а не тестировщики

Если бы разработчики говорили о написании ПО так, как многие люди говорят о тестировании, они бы сказали, что это их компилятор создал продукт, а не они, и всё, что они сделали – нажали на кнопку. Они сказали бы, что продукт был создан «автоматически», а не конкретными людьми, умеющими писать код и затратившими уйму усилий. В этом случае руководство стало бы одержимым «автоматизацией разработки», купив лучшие инструменты вместо найма и обучения настоящих разработчиков.

Говорить о тестировании следует так, как мы говорим о разработке: это то, что делают люди, а не инструменты. Инструменты помогают, но не проводят тестирование сами.

Автоматизированного тестирования, как такового, не существует.

Лучшее, что может сделать программа – управлять продуктом согласно сценарию и проверять соответствие ожидаемого результата и фактического. Никакого полёта фантазии от нескольких строк кода ожидать не стоит — лишь работа с готовым чек-листом (хотя, стоит признать, с этим инструменты могут справиться неплохо). Но тестирование – это гораздо большее, чем простая проверка списка фактов, потому что тестировщики должны формировать собственные технические выводы, использовать изобретательность для создания чек-листов для программ, а также для их оценки, поддержки и улучшения. Такое «автоматизированное тестирование» правильнее называть «тестированием с поддержкой инструментов». Когда вы фокусируетесь на «автоматических тестах», вы забываете о навыках, суждениях, решении проблем и мотивации, которая фактически контролирует качество тестирования.

5. Говорят, что есть только один вид тестового покрытия

Существует множество способов покрытия продукта при его тестировании. Каждый метод покрытия отличается и имеет свою собственную динамику. Нет конкретного способа (например, покрытие кода), способного обеспечить всеобъемлющий результат. В качестве примера: если вы протестируете страницу, которая предоставляет результаты поиска по запросу, то вы рассмотрите функциональность, представленную только тем видом запроса, который вы только что сделали (покрытие функции), а охватите вы только конкретный набор элементов данных, который существовал в это время (охват данных). Если вы измените запрос, чтобы вызвать другой тип поиска, вы получите новый функциональный охват. Если вы измените набор данных, вы получите новое покрытие данных. Таким образом, вы можете найти новую ошибку с этим новым покрытием. Функции взаимодействуют с данными; поэтому хорошее тестирование включает не только тот или иной вид покрытия, но и оба вместе в разных комбинациях.

6. Говорят, что тестирование – статическая задача, которая легко формализуется

Тестирование заключается в постоянном обучении. Если вы скажете мне, что вы тестируете, но ничему при этом не обучаетесь, я вам отвечу, что вы не тестируете вообще. Природа настоящего обучения заключается в том, что вы не можете знать, что вам откроется дальше. То же самое происходит со многими вещами в нашей жизни: от вождения автомобиля до управления компанией. Действительно, есть вещи, которые мы можем предсказать, и образцы, которые мы могли бы использовать для организации наших действий, но это не значит, что можно просто пройти всю жизнь, сонно опустив голову и бездумно следуя сценарию. Тестировать — значит постоянно задавать себе вопросы вроде «Что именно я сейчас вижу?», «Что именно я сейчас делаю?»

Процесс профессионального тестирования – это не разработка тест-кейсов и слепое следованием им. Ни один ответственный тестер не работает таким образом. Ответственное тестирование – это постоянный процесс исследования и экспериментирования. Он может включать в себя разработку автоматизированных процедур, систематически собирающих информацию о продукте, но делая что-то подобное, вы должны осознавать ответственность за свои действия прежде всего перед самим собой. Мы часто отклоняемся от автоматизированных процедур, потому что ПО часто бывает очень сложным и способным удивить совершенно неожиданным образом; и потому что потребности заказчика постоянно меняются; а ещё потому что мы постоянно узнаём лучшие способы тестирования по мере работы.

Люди постоянно упорствуют в убеждении, что быть хорошим тестировщиком – это написать побольше тест-кейсов (независимо от того, нужны ли они), автоматизировать их (независимо от того, на что автоматизация не способна), передавать их от одного специалиста другому и предаваться прочему фетишу на число файлов и сценариев вместо того, чтобы следить за тем, как выполняются поставленные задачи.

Материал подготовлен компанией-партнёром Bytex на основе одной из статей Джеймса Баха.

Отправить ответ

avatar
  Подписаться  
Уведомление о