Pytest Benchmark¶
Benchmark pozwala w bardzo prosty sposób testować wydajność naszego kodu poprzez wykorzystanie fixture w teście.
Fixture benchmark jest obiektem wywoływalnym który będzie robił testy wydajnościowe dla każdej przekazanej mu funkcji.
Co zapewnia pytest-benchmark?
- rozsądne wartości domyślne i automatyczna kalibracja dla mikro testów wydajnościowych
- dobra integracja z pytest
- porównywanie i śledzenie regresji
- wymuszone statystyki
- eksport danych do JSON
Instalacja¶
$ pip install pytest-benchmark
Wykorzystanie¶
def something(duration=0.000001):
"""
Function that needs some serious benchmarking.
"""
time.sleep(duration)
# You may return anything you want, like the result of a computation
return 123
def test_my_stuff(benchmark):
# benchmark something
result = benchmark(something)
# Extra code, to verify that the run completed correctly.
# Sometimes you may want to check the result, fast functions
# are no good if they return incorrect results :-)
assert result == 123
Można również dodawać argumenty
def test_my_stuff(benchmark):
benchmark(time.sleep, 0.02)
lub argumenty słów kluczowych
def test_my_stuff(benchmark):
benchmark(time.sleep, duration=0.02)
Jeśli potrzebujemy dokładnej kontrolia nad przebiegiem testu (np. funkcja konfiguracji czy dokładna kontrola iteracji i przebiegu) istnieje specjalny tryb pedantyczny pozwalający na dokładne określenie parametrów uruchamianego testu.
def test_with_setup(benchmark):
benchmark.pedantic(something, setup=my_special_setup, args=(1, 2, 3), kwargs={'foo': 'bar'}, iterations=10, rounds=100)
Dodatkowe opcje podczas uruchamiania¶
Benchmark zawiera szerek dodatkowych opcji ustawianych podczas uruchamiania testu. Więcej na ich temat możemy znaleźć w dokumentacji modułu http://pytest-benchmark.readthedocs.io/en/stable/usage.html#commandline-options.
Marker¶
Pozwala nam ustawić opcje testowania dla testu porównawczego.
@pytest.mark.benchmark(
group="group-name",
min_time=0.1,
max_time=0.5,
min_rounds=5,
timer=time.time,
disable_gc=True,
warmup=False
)
def test_my_stuff(benchmark):
@benchmark
def result():
# Code to be measured
return time.sleep(0.000001)
# Extra code, to verify that the run
# completed correctly.
# Note: this code is not measured.
assert result is None
Dodatkowe informacje¶
Tworząc zapis wyników do JSON możemy dodać dodatkowe informacje do słownika.
def test_my_stuff(benchmark):
benchmark.extra_info['foo'] = 'bar'
benchmark(time.sleep, 0.02)
Narzędzie Patch¶
Jeśli potrzebujesz przetestować wewnętrzną funkcję klasy należy wykorzystać benchmark_weave.
class Foo(object):
def __init__(self, arg=0.01):
self.arg = arg
def run(self):
self.internal(self.arg)
def internal(self, duration):
time.sleep(duration)
W przypadku testu porównawczego jest to dość trudne do sprawdzenia, jeśli nie ma pełnej
kontroli kodu klasy Foo lub ma on bardzo skomplikowaną konstrukcję. Aby przetestować taką
metodę można wykorzystać eksperymentalne fixture benchmark_weave. Należy jednak
się upewnić że mamy zainstalowany moduł aspectlib (pip install aspectlib
lub pip install pytest-benchmark[aspect])
def test_foo(benchmark):
benchmark.weave(Foo.internal, lazy=True):
f = Foo()
f.run()