Giter Club home page Giter Club logo

frobnicator's Introduction

  1. A po co komu framework do testów?

Bo pisanie testów jest nudne, uruchamiają się wolno, trzeba spędzać czas na przygotowaniu raportów, wykresów itp.

W pythonie jest wbudowany framework oparty o klasy, unittest, ale moim zdaniem pytest jest wygodniejszy i postaram się opowiedzieć dlaczego.

  1. Wyszukiwanie testów
  • pliki nazwane test_*.py (ale można podać plik wprost)
  • funkcje nazwane test_*
  • klasy nazwane Test* i ich metody test_*

Nie ma znaczenia gdzie to wszystko leży. Są dwie główne konwencje: albo osobny katalog tests/, albo pliki foo_test.py obok modułu foo.py.

W Silvair preferujemy dedykowany katalog.

  1. Asercje

Pytest nie uruchamia kodu wprost.

Zamiast tego, ładuje znalezione moduły jako AST, następnie wykonuje na nich magiczne transformacje i odpala dopiero zmodyfikowany kod.

Główna transformacja to tzw "assertion rewriting", dzięki której nie trzeba używać specjalnych funkcji typu unittest.TestCase.assertEqual a nieprzechodzące asercje raportują znacznie więcej informacji niż tylko AssertionError

Można też dodawać swoje własne szczegóły błędów

Lektura do poduszki:

  1. Setup/teardown
class TestClass:
    def setup_method(self):
        print("SETUP")

    def test_one(self):
        pass

    def test_two(self):
        pass

    def teardown_method(self):
        print("TEARDOWN")

Czemu klasycznie jest niedobrze?

  • żeby wykonać trzeba trzymać stan w instancji self
  • wszystkie test case'y w obrębie klasy współdzielą setup i teardown, mimo że może to być nadmiarowe
  • dziedziczenie klas testowych zaciemnia obraz
  1. Fixturki (aka "armatura")

Pytest nie uruchamia kodu wprost!

Druga magiczna transformacja AST to ewaluacja argumentów funkcji testowych.

Binding odbywa się po nazwie (można też fixture(name="foo"))

import pytest

@pytest.fixture
def setup():
    print("SETUP")
    yield
    print("TEARDOWN")

def test_one(setup):
    pass

def test_two(setup):
    pass

Czemu magicznie jest niedobrze?

  • IDE mają problem żeby to zrozumieć
  • nazwy fixturek są globalne
  1. Mockowanie

Python jest językiem z plasteliny i pozwala modyfikować kod w runtime.

Nie trzeba refaktoryzować kodu żeby umożliwić dependency injection - zamiast tego używamy monkey patching.

Pytest ma do tego wbudowany mechanizm, fixturkę monkeypatch:

@pytest.fixture
def no_requests(monkeypatch):
    def request(*args, **kwargs):
        raise NotImplementedError("Requests are disabled during the test run")

    monkeypatch.setattr("requests.api.request", request)
  1. Magic mock

W unittest jest przydatna klasa MagicMock która automatycznie mockuje prawie wszystko:

Also, pip install pytest-mock

@pytest.fixture
def mock_requests(monkeypatch):
    request = MagicMock()
    monkeypatch.setattr("requests.api.request", request)
    return request

def test_frobnicate(mock_requests):
    mock_requests.return_value = MagicMock(text="foo")
    assert frob.frobnicate() == "foo"
  1. Data-driven tests

Jeśli mamy test który sprawdza wiele przypadków w ten sam sposób, można je zwinąć - zwracam uwagę na binding argumentów funkcji testowej po nazwie:

@pytest.mark.parametrize("input, output",
    [
        pytest.param("one", "ONE"),
        pytest.param("tWo", "TwO"),
        pytest.param("THREE", "three"),
    ]
)
def test_swapcase(input, output):
    assert input.swapcase() == output

frobnicator's People

Contributors

michallowasrzechonek-silvair avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.