Pull to refresh

Comments 16

A QA engineer walks into a bar. Orders a beer. Orders 0 beers. Orders 99999999999 beers. Orders a lizard. Orders -1 beers. Orders a ueicbksjdhd.

First real customer walks in and asks where the bathroom is. The bar bursts into flames, killing everyone.

— Brenan Keller (@brenankeller) November 30, 2018


1) Вывод unittest:
Заголовок спойлера
$ python test_sum_unittest.py
.F
======================================================================
FAIL: test_sum_tuple (__main__.TestSum)
— Traceback (most recent call last):
File «test_sum_unittest.py», line 9, in test_sum_tuple
self.assertEqual(sum((1, 2, 2)), 6, «Should be 6»)
AssertionError: Should be 6

— Ran 2 tests in 0.001s

FAILED (failures=1)



2) Вывод nose2:
Заголовок спойлера
$ python -m nose2
.F
======================================================================
FAIL: test_sum_tuple (__main__.TestSum)
— Traceback (most recent call last):
File «test_sum_unittest.py», line 9, in test_sum_tuple
self.assertEqual(sum((1, 2, 2)), 6, «Should be 6»)
AssertionError: Should be 6

— Ran 2 tests in 0.001s

FAILED (failures=1)



При этом говорится, что
становится все сложнее понимать и использовать данные вывода unittest

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

Спасибо за наводку! Очень интересная штука, о которой я не встречал упоминаний.

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

А ещё удивляет, почему так мало пишут про такую классную штуку, как property based testing. Причем в питоне есть просто офигенный фреймворк hypothesis как раз для этого.

У вас есть опыт использования?

Есть положительный опыт использования самого property based подхода в проекте на C++, есть опыт использования конкретно hypothesis в pet-проекте, и сейчас как раз в процессе переноса этого опыта на ещё один "боевой" проект.

При случае черканите статейку, а то я пока не определюсь насколько практичен этот поход, понятно, когда в какой-нибудь вводной статье тестируют функцию `sum`всё круто, но на практике бывают всякие сложные объекты и всё такое — непонятно будет ли выигрыш или проще в json какой написать тестовый набор данных.

Да, были мысли написать сборник идей для поиска свойств с примерами (обычно именно тут в начале самый большой затык с этим подходом происходит). Ну а если основные впечатления и кратко, то:


  • обычные example-based тесты никто не отменял
  • нужен некоторый опыт и определенная повернутость мозга, чтобы быстро придумывать хорошие property-тесты
  • подходит не для всего (хотя чем больше опыта, тем для бОльшего количества проблем получается находить хорошие свойства)
  • когда подходит (в моих случаях — подходит часто), то позволяет относительно небольшими усилиями вылавливать просто горы всяких edge-кейсов
Было бы интересно, если приведете в статье какие-нить нетривиальные примеры.
Потому что в статьях про property based testing обычно рассматривается банальщина с числами и строками.

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

Статья очень unittest'овая. Для меня моим Первым Тестовым Фреймворком был pytest, и каждый раз, натыкаясь на unittest, я испытываю эстетический дискомфорт. pytest — реально питоническая система тестирования, с минимумом boilerplate, но позволяющая разрастаться на сложные штуки. Оно не требует сложного для простого, но позволяет сложное для сложного.

А как unittest узнает какие классы в файле подлежат исполнению, неужели все классы проверет?… Немного посмотрел в исходный код, вот так действительно проверяет все объекты:
for name in dir(module):
            obj = getattr(module, name)
            if isinstance(obj, type) and issubclass(obj, case.TestCase):
                tests.append(self.loadTestsFromTestCase(obj))

Sign up to leave a comment.