Comments 11
Любовь, любовь, лучи любви!
f-строки, частичный захват структур, '|' в enum'ах в struct.
Rust становится не просто офигенным, но и изящным.
Жду эквивалента pytest'а по эргономичности....
А не раскроете мысль? Хочется узнать, что именно в pytest есть такого, что (ещё?) не реализовано в ржавых тестах? Мне просто любопытно, для меня все тестовые фреймворки +/- одинаковые (естественно, я не говорю про QuickCheck и фаззеры, это достаточно узкоспециализированные инструменты)
Вангую, что недостает setUp/tearDown методов и mock объектов
Ох, там много всего. Я не буду трогать интроспекцию, поскольку это другой мир, но вот что мне очень хочется:
параметризации
@pytest.mark.parametrize('foo', ['foo1', 'foo2']) @pytest.mark.parametrize('bar', ['bar1', 'bar2']) def test_foo(foo, bar): pass
Ключевое свойство параметризации — оно делает декартово произведение параметров, причём с правильным оформлением.
красивых assert'ов.
В pytest я могу написать так:
assert x!=y
И если этот assert не выполнится, pytest правильно покажет что не так.
В rust мне нужно делать уродливые макросы под каждый тип операции (assert_eq!, assert_ne, etc).
Ну и то, что ниже пишут про setup/teardown, mock'ов (кстати, почему нет magic mock'ов в Rust? Это же так просто — надо всего лишь реализовывать все трейты, которые попросят).
В целом, тесты на pytest красивые и выразительные. Тесты на rust — некрасивые и с куче мелких нюансов, которых бы хотелось избежать. Они не так фатальны как в питоне (т.к. проверка типов работает лучше), но всё равно некрасиво.
Спасибо за ответ, макросы действительно не очень красивые по сравнению с assert x != y
, а вот такая параметризация легко реализуется вложенным форычем, нет?
Каждый тест независим. Часть может fail, часть sucess. Когда мы делаем не сложение интов, а что-то странное/сложное (например, содержимое файлов) позволяет видеть все ошибки сразу, а не по одной за запуск.
import pytest
@pytest.mark.parametrize("arg1", [1, 2, 3])
@pytest.mark.parametrize("arg2", [2, 1, 3])
@pytest.mark.parametrize("res", [3, 4])
def test_order(arg1, arg2, res):
assert arg1 + arg2 == res
И в конце:
...
_________________________ test_order[4-3-3] ________________
arg1 = 3, arg2 = 3, res = 4
@pytest.mark.parametrize("arg1", [1, 2, 3])
@pytest.mark.parametrize("arg2", [2, 1, 3])
@pytest.mark.parametrize("res", [3, 4])
def test_order(arg1, arg2, res):
> assert arg1 + arg2 == res
E assert 6 == 4
E -6
E +4
=== 13 failed, 5 passed in 0.21 seconds ===
параметризации
proptest
не решает эту задачу?
В rust мне нужно делать уродливые макросы под каждый тип операции (assert_eq!, assert_ne, etc).
Наверное, у меня просто глаз замылен (и на питоне не пишу) поэтому не вижу проблемы написать assert_ne!(x, y)
вместо assert x!=y
. Но в целом согласен, что местами хотелось бы удобнее.
Спасибо, выглядит интересно. У них подход сильно отличается от pytest'а, но, возможно, Rust'у именно это и нужно.
насчёт assert'ов — главное WTF в запятой. Если у вас не x и y, а что-то сложное, то становится так: assert_ne!(foo.bar<Item=i32>.baz(42), Foo::from_42())
Сравните с возможным:
assert foo.bar<Item=i32>.baz(42) != Foo::from_42()
assert!(a != b)
реально звал assert_ne!(a, b)
и аналогично для ==
в assert_eq!
?Понимаю, что тут ещё скобки мешаются, но уже ж ближе :)
Планирование редакции Rust 2021