tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

getting-started.rst (9504B)


      1 .. _get-started:
      2 
      3 Get Started
      4 ===================================
      5 
      6 .. _`getstarted`:
      7 .. _`installation`:
      8 
      9 Install ``pytest``
     10 ----------------------------------------
     11 
     12 ``pytest`` requires: Python 3.8+ or PyPy3.
     13 
     14 1. Run the following command in your command line:
     15 
     16 .. code-block:: bash
     17 
     18    pip install -U pytest
     19 
     20 2. Check that you installed the correct version:
     21 
     22 .. code-block:: bash
     23 
     24    $ pytest --version
     25    pytest 8.2.1
     26 
     27 .. _`simpletest`:
     28 
     29 Create your first test
     30 ----------------------------------------------------------
     31 
     32 Create a new file called ``test_sample.py``, containing a function, and a test:
     33 
     34 .. code-block:: python
     35 
     36    # content of test_sample.py
     37    def func(x):
     38        return x + 1
     39 
     40 
     41    def test_answer():
     42        assert func(3) == 5
     43 
     44 The test
     45 
     46 .. code-block:: pytest
     47 
     48    $ pytest
     49    =========================== test session starts ============================
     50    platform linux -- Python 3.x.y, pytest-8.x.y, pluggy-1.x.y
     51    rootdir: /home/sweet/project
     52    collected 1 item
     53 
     54    test_sample.py F                                                     [100%]
     55 
     56    ================================= FAILURES =================================
     57    _______________________________ test_answer ________________________________
     58 
     59        def test_answer():
     60    >       assert func(3) == 5
     61    E       assert 4 == 5
     62    E        +  where 4 = func(3)
     63 
     64    test_sample.py:6: AssertionError
     65    ========================= short test summary info ==========================
     66    FAILED test_sample.py::test_answer - assert 4 == 5
     67    ============================ 1 failed in 0.12s =============================
     68 
     69 The ``[100%]`` refers to the overall progress of running all test cases. After it finishes, pytest then shows a failure report because ``func(3)`` does not return ``5``.
     70 
     71 .. note::
     72 
     73    You can use the ``assert`` statement to verify test expectations. pytest’s :ref:`Advanced assertion introspection <python:assert>` will intelligently report intermediate values of the assert expression so you can avoid the many names :ref:`of JUnit legacy methods <testcase-objects>`.
     74 
     75 Run multiple tests
     76 ----------------------------------------------------------
     77 
     78 ``pytest`` will run all files of the form test_*.py or \*_test.py in the current directory and its subdirectories. More generally, it follows :ref:`standard test discovery rules <test discovery>`.
     79 
     80 
     81 Assert that a certain exception is raised
     82 --------------------------------------------------------------
     83 
     84 Use the :ref:`raises <assertraises>` helper to assert that some code raises an exception:
     85 
     86 .. code-block:: python
     87 
     88    # content of test_sysexit.py
     89    import pytest
     90 
     91 
     92    def f():
     93        raise SystemExit(1)
     94 
     95 
     96    def test_mytest():
     97        with pytest.raises(SystemExit):
     98            f()
     99 
    100 You can also use the context provided by :ref:`raises <assertraises>` to
    101 assert that an expected exception is part of a raised :class:`ExceptionGroup`:
    102 
    103 .. code-block:: python
    104 
    105    # content of test_exceptiongroup.py
    106    import pytest
    107 
    108 
    109    def f():
    110        raise ExceptionGroup(
    111            "Group message",
    112            [
    113                RuntimeError(),
    114            ],
    115        )
    116 
    117 
    118    def test_exception_in_group():
    119        with pytest.raises(ExceptionGroup) as excinfo:
    120            f()
    121        assert excinfo.group_contains(RuntimeError)
    122        assert not excinfo.group_contains(TypeError)
    123 
    124 Execute the test function with “quiet” reporting mode:
    125 
    126 .. code-block:: pytest
    127 
    128    $ pytest -q test_sysexit.py
    129    .                                                                    [100%]
    130    1 passed in 0.12s
    131 
    132 .. note::
    133 
    134    The ``-q/--quiet`` flag keeps the output brief in this and following examples.
    135 
    136 Group multiple tests in a class
    137 --------------------------------------------------------------
    138 
    139 .. regendoc:wipe
    140 
    141 Once you develop multiple tests, you may want to group them into a class. pytest makes it easy to create a class containing more than one test:
    142 
    143 .. code-block:: python
    144 
    145    # content of test_class.py
    146    class TestClass:
    147        def test_one(self):
    148            x = "this"
    149            assert "h" in x
    150 
    151        def test_two(self):
    152            x = "hello"
    153            assert hasattr(x, "check")
    154 
    155 ``pytest`` discovers all tests following its :ref:`Conventions for Python test discovery <test discovery>`, so it finds both ``test_`` prefixed functions. There is no need to subclass anything, but make sure to prefix your class with ``Test`` otherwise the class will be skipped. We can simply run the module by passing its filename:
    156 
    157 .. code-block:: pytest
    158 
    159    $ pytest -q test_class.py
    160    .F                                                                   [100%]
    161    ================================= FAILURES =================================
    162    ____________________________ TestClass.test_two ____________________________
    163 
    164    self = <test_class.TestClass object at 0xdeadbeef0001>
    165 
    166        def test_two(self):
    167            x = "hello"
    168    >       assert hasattr(x, "check")
    169    E       AssertionError: assert False
    170    E        +  where False = hasattr('hello', 'check')
    171 
    172    test_class.py:8: AssertionError
    173    ========================= short test summary info ==========================
    174    FAILED test_class.py::TestClass::test_two - AssertionError: assert False
    175    1 failed, 1 passed in 0.12s
    176 
    177 The first test passed and the second failed. You can easily see the intermediate values in the assertion to help you understand the reason for the failure.
    178 
    179 Grouping tests in classes can be beneficial for the following reasons:
    180 
    181 * Test organization
    182 * Sharing fixtures for tests only in that particular class
    183 * Applying marks at the class level and having them implicitly apply to all tests
    184 
    185 Something to be aware of when grouping tests inside classes is that each test has a unique instance of the class.
    186 Having each test share the same class instance would be very detrimental to test isolation and would promote poor test practices.
    187 This is outlined below:
    188 
    189 .. regendoc:wipe
    190 
    191 .. code-block:: python
    192 
    193    # content of test_class_demo.py
    194    class TestClassDemoInstance:
    195        value = 0
    196 
    197        def test_one(self):
    198            self.value = 1
    199            assert self.value == 1
    200 
    201        def test_two(self):
    202            assert self.value == 1
    203 
    204 
    205 .. code-block:: pytest
    206 
    207    $ pytest -k TestClassDemoInstance -q
    208    .F                                                                   [100%]
    209    ================================= FAILURES =================================
    210    ______________________ TestClassDemoInstance.test_two ______________________
    211 
    212    self = <test_class_demo.TestClassDemoInstance object at 0xdeadbeef0002>
    213 
    214        def test_two(self):
    215    >       assert self.value == 1
    216    E       assert 0 == 1
    217    E        +  where 0 = <test_class_demo.TestClassDemoInstance object at 0xdeadbeef0002>.value
    218 
    219    test_class_demo.py:9: AssertionError
    220    ========================= short test summary info ==========================
    221    FAILED test_class_demo.py::TestClassDemoInstance::test_two - assert 0 == 1
    222    1 failed, 1 passed in 0.12s
    223 
    224 Note that attributes added at class level are *class attributes*, so they will be shared between tests.
    225 
    226 Request a unique temporary directory for functional tests
    227 --------------------------------------------------------------
    228 
    229 ``pytest`` provides :std:doc:`Builtin fixtures/function arguments <builtin>` to request arbitrary resources, like a unique temporary directory:
    230 
    231 .. code-block:: python
    232 
    233    # content of test_tmp_path.py
    234    def test_needsfiles(tmp_path):
    235        print(tmp_path)
    236        assert 0
    237 
    238 List the name ``tmp_path`` in the test function signature and ``pytest`` will lookup and call a fixture factory to create the resource before performing the test function call. Before the test runs, ``pytest`` creates a unique-per-test-invocation temporary directory:
    239 
    240 .. code-block:: pytest
    241 
    242    $ pytest -q test_tmp_path.py
    243    F                                                                    [100%]
    244    ================================= FAILURES =================================
    245    _____________________________ test_needsfiles ______________________________
    246 
    247    tmp_path = PosixPath('PYTEST_TMPDIR/test_needsfiles0')
    248 
    249        def test_needsfiles(tmp_path):
    250            print(tmp_path)
    251    >       assert 0
    252    E       assert 0
    253 
    254    test_tmp_path.py:3: AssertionError
    255    --------------------------- Captured stdout call ---------------------------
    256    PYTEST_TMPDIR/test_needsfiles0
    257    ========================= short test summary info ==========================
    258    FAILED test_tmp_path.py::test_needsfiles - assert 0
    259    1 failed in 0.12s
    260 
    261 More info on temporary directory handling is available at :ref:`Temporary directories and files <tmp_path handling>`.
    262 
    263 Find out what kind of builtin :ref:`pytest fixtures <fixtures>` exist with the command:
    264 
    265 .. code-block:: bash
    266 
    267    pytest --fixtures   # shows builtin and custom fixtures
    268 
    269 Note that this command omits fixtures with leading ``_`` unless the ``-v`` option is added.
    270 
    271 Continue reading
    272 -------------------------------------
    273 
    274 Check out additional pytest resources to help you customize tests for your unique workflow:
    275 
    276 * ":ref:`usage`" for command line invocation examples
    277 * ":ref:`existingtestsuite`" for working with preexisting tests
    278 * ":ref:`mark`" for information on the ``pytest.mark`` mechanism
    279 * ":ref:`fixtures`" for providing a functional baseline to your tests
    280 * ":ref:`plugins`" for managing and writing plugins
    281 * ":ref:`goodpractices`" for virtualenv and test layouts