vak: (Default)
[personal profile] vak
Любишь кодить - люби и тестировать. Фундаментальность программистского образования в СССР нивелировалась полным отсутствием представления об организации процесса тестирования, и вообще обеспечения качества программного продукта. Ни в курчатнике, где мы делали операционную систему Демос, ни в ИТМиВТ, с которым мы активно сотрудничали и где разрабатывали штатные ОС и компиляторы для БЭСМ и Эльбрус, не было соответствующей практики наработки тестов и организации регулярного тестирования. А жаль.

С опытом я прихожу к мысли, что современные методики типа TDD представляют основу практики программирования. Впрочем, про TDD я напишу позже, а сейчас я веду к тому, что pytest представляет собой первейший инструмент всякого Питон-программиста. Мне лично доводится использовать pytest по работе и я нахожу его весьма полезным.

Pytest представляет собой утилиту, которая вызывается из командной строки и запускает набор тестов Вашей программы. Для этого pytest сканирует присутствующие папки и файлы в них, находит файлы с именами test_*.py, а в них определения процедур с именами вида test_xxx(), и вызывает эти процедуры. На экран выдаётся информация о пройденных тестах. По умолчанию печатается имя файла и дальше точка для каждого успешного теста или F для неуспешного. Скажем, у меня есть файл test_demo.py и в нём десять тестов. Будет выдано следующее:
$ pytest
======================== test session starts =========================
platform darwin -- Python 3.8.4, pytest-5.4.3, py-1.9.0, pluggy-0.13.1
rootdir: /Users/vak/Project/Github/Pytest-Actions-Demo
collected 10 items

test_demo.py .......... [100%]

========================= 10 passed in 0.03s ========================
Если добавить флаг -v, будут выдаваться имена тестов, по одному в строке:
$ pytest -v
======================== test session starts =========================
platform darwin -- Python 3.8.4, pytest-5.4.3, py-1.9.0, pluggy-0.13.1 -- /usr/local/opt/python@3.8/bin/python3.8
cachedir: .pytest_cache
rootdir: /Users/vak/Project/Github/Pytest-Actions-Demo
collected 10 items

test_demo.py::test_fact_0 PASSED [ 10%]
test_demo.py::test_fact_1 PASSED [ 20%]
test_demo.py::test_fact_2 PASSED [ 30%]
test_demo.py::test_fact_3 PASSED [ 40%]
test_demo.py::test_fact_10 PASSED [ 50%]
test_demo.py::test_fact_20 PASSED [ 60%]
test_demo.py::test_fact_30 PASSED [ 70%]
test_demo.py::test_fact_40 PASSED [ 80%]
test_demo.py::test_fact_50 PASSED [ 90%]
test_demo.py::test_fact_minus1 PASSED [100%]

========================= 10 passed in 0.03s ========================
Процедуры тестов содержат операторы assert, проверяющие результат выполнения Вашей программы. Если результат совпадает - тест считается успешным:
def test_fact_3():
assert demo.factorial(3) == 6
Если в одном из тестов обнаружена ошибка, она выдаётся в виде:
============================== FAILURES ==============================
____________________________ test_fact_3 _____________________________

def test_fact_3():
> assert demo.factorial(3) == 7
E assert 6 == 7
E +6
E -7

test_demo.py:24: AssertionError
====================== short test summary info =======================
FAILED test_demo.py::test_fact_3 - assert 6 == 7
==================== 1 failed, 9 passed in 0.06s =====================
Да, я не упомянул: устанавливается pytest командой "pip install pytest". А если добавить к нему ещё и "pip3 install pytest-xdist", то у pytest появится флаг "-nauto", запускающий тесты впараллель на всех доступных процессорах компьютера. Это заметно ускоряет процесс. К примеру у меня на работе в одном из проектов имеется больше 600 тестов, и полный прогон (на одном процессоре) занимает около 15 минут. С флагом же "-nauto" задействуется 16 процессоров моего MacBook Pro, и тестирование ускоряется до 5 минут.

Это базовый минимум. Но в pytest есть куча полезных фич, помогающих в разработке тестов. Рекомендую книжку, где все возможности подробно описаны: "Python Testing with pytest".



Пример проекта с pytest смотрите на Гитхабе: https://github.com/sergev/Pytest-Actions-Demo

Date: 2020-07-27 10:49 (UTC)
vit_r: default (Default)
From: [personal profile] vit_r
В индустриальном коде assert стоит не в тесте, а в функции, потому что нет смысла что-то там дальше гонять по проводам, когда данные получились недопустимыми. Но это не новомодный стиль, когда даже exception используется для передачи параметров.

А Питон - студенческий язык со всеми вытекающими.

Date: 2020-07-27 11:36 (UTC)
elglin: (Default)
From: [personal profile] elglin
Поздравляю вас, гражданин, соврамши. В индустриальном коде assert выоптимизирован при компиляции.
Валидация входных данных - это вообще защитное программирование, применяющееся более или менее активно, сообразуясь с задачей. Языконезависимая и стиленезависимая вещь.
Реализация логики исключениями (вы, наверное, это имели в виду) есть очень плохой стиль... только он не новомодный. Он просто плохой. Более того, в языках с исключениями можно... их не использовать. Noexcept не просто так в плюсы запилили.

Короче, отучайтесь говорить за всю сеть. Особенно если, как здесь, вы несете какую-то фигню.

Date: 2020-07-27 11:41 (UTC)
vit_r: default (Default)
From: [personal profile] vit_r
Поздравляю вас, гражданин, соврамши. В индустриальном...

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

Date: 2020-07-27 12:04 (UTC)
norian: (Default)
From: [personal profile] norian
тдд это правильно, но на практике очень скучно и не всегда удобно, поскольку разработка кода в значительной степени является высоким искусством, а искусство не любит жостких рамок

коты предпочитают тсд - tests supported development, когда тесты можно делать на любом этапе, до, во время и после написания функционального текста, но к релизу должен быть full code coverage, иначе незачот

Date: 2020-07-27 12:13 (UTC)
elglin: (Default)
From: [personal profile] elglin
И вторично отучайтесь говорить за всю сеть. Если вы считаете индустриальным код, прошедший компиляцию, то это очередной фантом в вашей голове. Если у вас на работе все так, то мне вас жаль (с); в нормально отстроенном конвейере сборки компиляция - это только входной билет.
И про истинное значение слова, O RLY? https://de.wiktionary.org/wiki/industriell вам в помощь. Что до "стоит денег", я не готов говорить за платежные компоненты, я никогда ими не занимался, но если говорить о коде, из-за ошибок в котором контора теряет деньги... то я видел такой код, обмазанный валидаторами, ассертами и юнит-тестами. Видел такой код, не обмазанный ничем из этого. И видел много вариантов когда из этой троицы имелось какое-то подмножество.

Date: 2020-07-27 12:22 (UTC)
vit_r: default (Default)
From: [personal profile] vit_r
Тяжёлый случай.

Скажем так, вы когда-нибудь видели внутри код, на котором висят человеческие жизни? (Я имею ввиду не российские поделки, а те страны, где разработчиков могут посадить.)

Date: 2020-07-27 12:24 (UTC)
norian: (Default)
From: [personal profile] norian
в "индустриальной" разработке часто бывает что дебаг-версия работает, а в релизе слишком агрессивная оптимизация и он падает

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

Date: 2020-07-27 12:44 (UTC)
elglin: (Default)
From: [personal profile] elglin
Вы не подскажете, сколько разработчиков посадили за Therac-25 или 737 MAX?

Что до меня, то я, в основном, имею дело с кодом "купи-продай". С кодом, от которого зависит что-то более важное, чем пачка чьих-то купюр я, наверное, к счастью (в отличие от вас, я спокойно отношусь к тому, что мои способности достаточно скромны), никогда дела не имел. И, опять же, в отличие от вас, не мню себя экспертом в области, в которой не работаю.
Но мне есть, у кого спросить. Скажите, если мы говорим за код, на котором висела жизнь немецких космонавтов (не ГДР-овца Йена, а настоящего Wessie Райтера), то приоритет у российской поделки или у немецкого космонавта?

Date: 2020-07-27 12:45 (UTC)
vit_r: default (Default)
From: [personal profile] vit_r
Естественно, код должен падать, если он неправильный.
Edited Date: 2020-07-27 12:45 (UTC)

Date: 2020-07-27 12:47 (UTC)
vit_r: default (Default)
From: [personal profile] vit_r
"Давайте спорить о вкусе устриц и кокосовых орехов с теми, кто их ел, до хрипоты, до драки, воспринимая вкус еды на слух, цвет на зуб, вонь на глаз, представляя себе фильм по названию, живопись по фамилии, " индустриальный код по Википедии.

Date: 2020-07-27 12:48 (UTC)
elglin: (Default)
From: [personal profile] elglin
Кстати, своими глазами видел код, падавший при максимально аггрессивной оптимизации и стабильно работавший без самого аггрессивного флага (Watcom C, давно дело было, точный флаг не помню уже).

Date: 2020-07-27 12:52 (UTC)
elglin: (Default)
From: [personal profile] elglin
А, ну то есть по сути сказать нечего. Легко на словах быть Львом Толстым... хотя не очень успешному гастеру-заробитчанину больше ничего и не остается.

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

Date: 2020-07-27 12:57 (UTC)
vit_r: default (Default)
From: [personal profile] vit_r
Ох. Я просто написал, что ваши романтические википедийные представления очень далеки от грубой реальности. Можно верить, можно не верить. Мне пофиг.

Date: 2020-07-27 15:16 (UTC)
juan_gandhi: (Default)
From: [personal profile] juan_gandhi

В те поры юниттестов не было нигде. Я в Борланде провел семь лет - ничего такого не было. Тестирование было работой кюеев; но кюеи были никто и звать никак. Ну написал я тест, покрывающий "весь юникод" - и чо, кто-то будет фиксить эти баги? "Сойдет и так" был девиз.

Date: 2020-07-27 17:03 (UTC)
From: [personal profile] caztd
Включен или выключен assert в продакшен -- это исключительно вопрос требований на конкретный продукт, не надо обобщать за всю индустрию, да.

Например:
https://interrupt.memfault.com/blog/asserts-in-embedded-systems

Date: 2020-07-27 19:44 (UTC)
vit_r: default (Default)
From: [personal profile] vit_r
Вон, Боинг не боролся и поддался трендам. Сейчас на земле сидит.
Edited Date: 2020-07-27 19:44 (UTC)

Date: 2020-07-27 20:52 (UTC)
vit_r: default (Default)
From: [personal profile] vit_r
У них не было внешнего аудита. Да и цена ошибки не такая высокая. Изделия малосерийные.